@phantom/browser-sdk 1.0.0-beta.22 → 1.0.0-beta.24

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/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,12 +17,20 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var src_exports = {};
22
32
  __export(src_exports, {
23
- AddressType: () => import_client5.AddressType,
33
+ AddressType: () => import_client4.AddressType,
24
34
  BrowserSDK: () => BrowserSDK,
25
35
  DebugCategory: () => DebugCategory,
26
36
  DebugLevel: () => DebugLevel,
@@ -41,11 +51,7 @@ module.exports = __toCommonJS(src_exports);
41
51
  var import_client = require("@phantom/client");
42
52
 
43
53
  // src/providers/injected/index.ts
44
- var import_client4 = require("@phantom/client");
45
- var import_browser_injected_sdk = require("@phantom/browser-injected-sdk");
46
- var import_solana = require("@phantom/browser-injected-sdk/solana");
47
- var import_ethereum = require("@phantom/browser-injected-sdk/ethereum");
48
- var import_auto_confirm = require("@phantom/browser-injected-sdk/auto-confirm");
54
+ var import_client3 = require("@phantom/client");
49
55
 
50
56
  // src/debug.ts
51
57
  var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
@@ -66,109 +72,1433 @@ var Debug = class {
66
72
  }
67
73
  return Debug.instance;
68
74
  }
69
- setCallback(callback) {
70
- this.callback = callback;
75
+ setCallback(callback) {
76
+ this.callback = callback;
77
+ }
78
+ setLevel(level) {
79
+ this.level = level;
80
+ }
81
+ enable() {
82
+ this.enabled = true;
83
+ }
84
+ disable() {
85
+ this.enabled = false;
86
+ }
87
+ writeLog(level, category, message, data) {
88
+ if (!this.enabled || level > this.level) {
89
+ return;
90
+ }
91
+ const debugMessage = {
92
+ timestamp: Date.now(),
93
+ level,
94
+ category,
95
+ message,
96
+ data
97
+ };
98
+ if (this.callback) {
99
+ this.callback(debugMessage);
100
+ }
101
+ }
102
+ error(category, message, data) {
103
+ this.writeLog(0 /* ERROR */, category, message, data);
104
+ }
105
+ warn(category, message, data) {
106
+ this.writeLog(1 /* WARN */, category, message, data);
107
+ }
108
+ info(category, message, data) {
109
+ this.writeLog(2 /* INFO */, category, message, data);
110
+ }
111
+ debug(category, message, data) {
112
+ this.writeLog(3 /* DEBUG */, category, message, data);
113
+ }
114
+ log(category, message, data) {
115
+ this.writeLog(3 /* DEBUG */, category, message, data);
116
+ }
117
+ };
118
+ var debug = Debug.getInstance();
119
+ var DebugCategory = {
120
+ BROWSER_SDK: "BrowserSDK",
121
+ PROVIDER_MANAGER: "ProviderManager",
122
+ EMBEDDED_PROVIDER: "EmbeddedProvider",
123
+ INJECTED_PROVIDER: "InjectedProvider",
124
+ PHANTOM_CONNECT_AUTH: "PhantomConnectAuth",
125
+ JWT_AUTH: "JWTAuth",
126
+ STORAGE: "Storage",
127
+ SESSION: "Session"
128
+ };
129
+
130
+ // src/wallets/discovery.ts
131
+ var import_client2 = require("@phantom/client");
132
+ var import_browser_injected_sdk = require("@phantom/browser-injected-sdk");
133
+ var import_browser_injected_sdk2 = require("@phantom/browser-injected-sdk");
134
+ var import_solana = require("@phantom/browser-injected-sdk/solana");
135
+ var import_ethereum = require("@phantom/browser-injected-sdk/ethereum");
136
+ var import_auto_confirm = require("@phantom/browser-injected-sdk/auto-confirm");
137
+ function generateWalletIdFromEIP6963(info) {
138
+ if (info.rdns) {
139
+ return info.rdns.split(".").reverse().join("-");
140
+ }
141
+ return info.name.toLowerCase().replace(/\s+/g, "-");
142
+ }
143
+ function generateWalletIdFromName(name) {
144
+ return name.toLowerCase().replace(/\s+/g, "-");
145
+ }
146
+ function processEIP6963Providers(providers) {
147
+ const wallets = [];
148
+ debug.log(DebugCategory.BROWSER_SDK, "Processing EIP-6963 providers", {
149
+ providerCount: providers.size,
150
+ providerNames: Array.from(providers.values()).map((d) => d.info.name)
151
+ });
152
+ for (const [, detail] of providers) {
153
+ const { info, provider } = detail;
154
+ const isPhantom = info.name.toLowerCase().includes("phantom") || info.rdns && (info.rdns.toLowerCase().includes("phantom") || info.rdns.toLowerCase() === "app.phantom");
155
+ if (isPhantom) {
156
+ debug.log(DebugCategory.BROWSER_SDK, "Skipping Phantom from EIP-6963", { name: info.name, rdns: info.rdns });
157
+ continue;
158
+ }
159
+ const walletId = generateWalletIdFromEIP6963(info);
160
+ debug.log(DebugCategory.BROWSER_SDK, "Discovered EIP-6963 wallet", {
161
+ walletId,
162
+ walletName: info.name,
163
+ rdns: info.rdns
164
+ });
165
+ wallets.push({
166
+ id: walletId,
167
+ name: info.name,
168
+ icon: info.icon,
169
+ addressTypes: [import_client2.AddressType.ethereum],
170
+ providers: {
171
+ // EIP-6963 provider implements EIP-1193 interface (IEthereumChain)
172
+ ethereum: provider
173
+ },
174
+ rdns: info.rdns
175
+ // Store rdns for potential future matching
176
+ });
177
+ }
178
+ debug.log(DebugCategory.BROWSER_SDK, "EIP-6963 discovery completed", {
179
+ discoveredCount: wallets.length,
180
+ walletIds: wallets.map((w) => w.id)
181
+ });
182
+ return wallets;
183
+ }
184
+ function discoverEthereumWallets() {
185
+ return new Promise((resolve) => {
186
+ const discoveredProviders = /* @__PURE__ */ new Map();
187
+ if (typeof window === "undefined") {
188
+ resolve([]);
189
+ return;
190
+ }
191
+ const handleAnnounce = (event) => {
192
+ const detail = event.detail;
193
+ if (detail?.info && detail?.provider) {
194
+ discoveredProviders.set(detail.info.uuid, detail);
195
+ }
196
+ };
197
+ window.addEventListener("eip6963:announceProvider", handleAnnounce);
198
+ window.dispatchEvent(new Event("eip6963:requestProvider"));
199
+ const processProviders = () => {
200
+ const wallets = processEIP6963Providers(discoveredProviders);
201
+ window.removeEventListener("eip6963:announceProvider", handleAnnounce);
202
+ resolve(wallets);
203
+ };
204
+ setTimeout(processProviders, 400);
205
+ });
206
+ }
207
+ async function discoverSolanaWallets() {
208
+ const wallets = [];
209
+ if (typeof window === "undefined" || typeof navigator === "undefined") {
210
+ debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard discovery skipped (not in browser environment)");
211
+ return wallets;
212
+ }
213
+ const registeredWalletsSet = /* @__PURE__ */ new Set();
214
+ let cachedWalletsArray;
215
+ function addRegisteredWallet(wallet) {
216
+ cachedWalletsArray = void 0;
217
+ registeredWalletsSet.add(wallet);
218
+ const featureKeys = wallet.features ? Object.keys(wallet.features) : [];
219
+ debug.log(DebugCategory.BROWSER_SDK, "Wallet registered", {
220
+ name: wallet.name,
221
+ chains: wallet.chains,
222
+ featureKeys,
223
+ totalWallets: registeredWalletsSet.size
224
+ });
225
+ }
226
+ function removeRegisteredWallet(wallet) {
227
+ cachedWalletsArray = void 0;
228
+ registeredWalletsSet.delete(wallet);
229
+ }
230
+ function getRegisteredWallets() {
231
+ if (!cachedWalletsArray) {
232
+ cachedWalletsArray = [...registeredWalletsSet];
233
+ }
234
+ return cachedWalletsArray;
235
+ }
236
+ function register(...wallets2) {
237
+ wallets2 = wallets2.filter((wallet) => !registeredWalletsSet.has(wallet));
238
+ if (!wallets2.length) {
239
+ return () => {
240
+ };
241
+ }
242
+ wallets2.forEach((wallet) => addRegisteredWallet(wallet));
243
+ return function unregister() {
244
+ wallets2.forEach((wallet) => removeRegisteredWallet(wallet));
245
+ };
246
+ }
247
+ const registerAPI = Object.freeze({ register });
248
+ const handleRegisterWalletEvent = (event) => {
249
+ const callback = event.detail;
250
+ if (typeof callback === "function") {
251
+ try {
252
+ callback(registerAPI);
253
+ } catch (error) {
254
+ debug.warn(DebugCategory.BROWSER_SDK, "Error calling wallet registration callback", { error });
255
+ }
256
+ }
257
+ };
258
+ try {
259
+ window.addEventListener("wallet-standard:register-wallet", handleRegisterWalletEvent);
260
+ } catch (error) {
261
+ debug.warn(DebugCategory.BROWSER_SDK, "Could not add register-wallet event listener", { error });
262
+ }
263
+ class AppReadyEvent extends Event {
264
+ constructor(api) {
265
+ super("wallet-standard:app-ready", {
266
+ bubbles: false,
267
+ cancelable: false,
268
+ composed: false
269
+ });
270
+ this.detail = api;
271
+ }
272
+ }
273
+ try {
274
+ window.dispatchEvent(new AppReadyEvent(registerAPI));
275
+ debug.log(DebugCategory.BROWSER_SDK, "Dispatched wallet-standard:app-ready event");
276
+ } catch (error) {
277
+ debug.warn(DebugCategory.BROWSER_SDK, "Could not dispatch app-ready event", { error });
278
+ }
279
+ const walletsAPI = {
280
+ getWallets: () => {
281
+ return {
282
+ get: getRegisteredWallets,
283
+ on: (_event, _listener) => {
284
+ return () => {
285
+ };
286
+ },
287
+ register
288
+ };
289
+ }
290
+ };
291
+ if (!navigator.wallets) {
292
+ navigator.wallets = walletsAPI;
293
+ }
294
+ debug.log(DebugCategory.BROWSER_SDK, "Initialized Wallet Standard registry");
295
+ await new Promise((resolve) => setTimeout(resolve, 100));
296
+ const existingWalletsAPI = navigator.wallets || window.wallets;
297
+ if (!existingWalletsAPI || typeof existingWalletsAPI.getWallets !== "function") {
298
+ const logData = {
299
+ hasNavigator: !!navigator,
300
+ hasWindow: typeof window !== "undefined",
301
+ note: "Wallet Standard API not properly initialized"
302
+ };
303
+ debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard API not available", logData);
304
+ return wallets;
305
+ }
306
+ const walletsGetter = existingWalletsAPI.getWallets();
307
+ const getWalletsFn = () => Promise.resolve([...walletsGetter.get()]);
308
+ debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard API detected, starting discovery");
309
+ try {
310
+ let registeredWallets = [];
311
+ let attempts = 0;
312
+ const maxAttempts = 5;
313
+ const initialDelay = 100;
314
+ const eip6963Timeout = 400;
315
+ await new Promise((resolve) => setTimeout(resolve, initialDelay));
316
+ while (attempts < maxAttempts) {
317
+ registeredWallets = await getWalletsFn();
318
+ const logData = {
319
+ attempt: attempts + 1,
320
+ walletCount: registeredWallets.length,
321
+ walletNames: registeredWallets.map((w) => w.name),
322
+ chains: registeredWallets.flatMap((w) => w.chains)
323
+ };
324
+ debug.log(DebugCategory.BROWSER_SDK, `Wallet Standard getWallets attempt ${attempts + 1}`, logData);
325
+ if (registeredWallets.length > 0 || attempts === maxAttempts - 1) {
326
+ break;
327
+ }
328
+ await new Promise((resolve) => setTimeout(resolve, initialDelay));
329
+ attempts++;
330
+ }
331
+ const totalWaitTime = initialDelay + attempts * initialDelay;
332
+ if (totalWaitTime < eip6963Timeout) {
333
+ const remainingWait = eip6963Timeout - totalWaitTime;
334
+ await new Promise((resolve) => setTimeout(resolve, remainingWait));
335
+ registeredWallets = await getWalletsFn();
336
+ }
337
+ debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard getWallets final result", {
338
+ walletCount: registeredWallets.length,
339
+ walletNames: registeredWallets.map((w) => w.name),
340
+ attempts: attempts + 1
341
+ });
342
+ for (const wallet of registeredWallets) {
343
+ const supportsSolana = wallet.chains.some((chain) => {
344
+ const chainLower = chain.toLowerCase();
345
+ return chainLower.startsWith("solana:") || chainLower === "solana";
346
+ }) || wallet.features && typeof wallet.features === "object" && Object.keys(wallet.features).some((featureKey) => {
347
+ const featureLower = featureKey.toLowerCase();
348
+ return featureLower.includes("solana") || featureLower.includes("standard:connect") || featureLower.includes("standard:signTransaction");
349
+ });
350
+ if (!supportsSolana) {
351
+ const featureKeys = wallet.features ? Object.keys(wallet.features) : [];
352
+ debug.log(DebugCategory.BROWSER_SDK, "Wallet does not support Solana", {
353
+ walletName: wallet.name,
354
+ chains: wallet.chains,
355
+ featureKeys
356
+ });
357
+ continue;
358
+ }
359
+ if (wallet.name.toLowerCase().includes("phantom")) {
360
+ debug.log(DebugCategory.BROWSER_SDK, "Skipping Phantom from Wallet Standard (handled separately)");
361
+ continue;
362
+ }
363
+ const walletId = generateWalletIdFromName(wallet.name);
364
+ const safeFeatures = wallet.features ? Object.keys(wallet.features) : [];
365
+ debug.log(DebugCategory.BROWSER_SDK, "Discovered Wallet Standard Solana wallet", {
366
+ walletId,
367
+ walletName: wallet.name,
368
+ chains: wallet.chains,
369
+ featureKeys: safeFeatures,
370
+ icon: wallet.icon,
371
+ version: wallet.version,
372
+ accountCount: wallet.accounts?.length || 0
373
+ });
374
+ wallets.push({
375
+ id: walletId,
376
+ name: wallet.name,
377
+ icon: wallet.icon,
378
+ addressTypes: [import_client2.AddressType.solana],
379
+ providers: {
380
+ // Cast to ISolanaChain - Wallet Standard wallets have compatible methods
381
+ // The InjectedWalletSolanaChain wrapper will handle the actual method calls
382
+ solana: wallet
383
+ }
384
+ });
385
+ }
386
+ } catch (error) {
387
+ debug.warn(DebugCategory.BROWSER_SDK, "Wallet Standard API error", {
388
+ error: error instanceof Error ? error.message : String(error),
389
+ stack: error instanceof Error ? error.stack : void 0
390
+ });
391
+ }
392
+ const finalLogData = {
393
+ discoveredCount: wallets.length,
394
+ walletIds: wallets.map((w) => w.id),
395
+ walletNames: wallets.map((w) => w.name)
396
+ };
397
+ debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard Solana discovery completed", finalLogData);
398
+ return wallets;
399
+ }
400
+ function getPhantomIconFromWalletStandard() {
401
+ if (typeof window === "undefined" || typeof navigator === "undefined") {
402
+ return null;
403
+ }
404
+ const walletsAPI = navigator.wallets;
405
+ if (!walletsAPI || typeof walletsAPI.getWallets !== "function") {
406
+ return null;
407
+ }
408
+ try {
409
+ const walletsGetter = walletsAPI.getWallets();
410
+ if (walletsGetter && typeof walletsGetter.get === "function") {
411
+ const registeredWallets = walletsGetter.get();
412
+ const phantomWallet = registeredWallets.find((w) => w.name.toLowerCase().includes("phantom"));
413
+ if (phantomWallet?.icon) {
414
+ return phantomWallet.icon;
415
+ }
416
+ }
417
+ } catch (error) {
418
+ }
419
+ return null;
420
+ }
421
+ async function discoverPhantomWallet(addressTypes) {
422
+ if (typeof window === "undefined") {
423
+ return null;
424
+ }
425
+ if (!(0, import_browser_injected_sdk.isPhantomExtensionInstalled)()) {
426
+ return null;
427
+ }
428
+ let icon = await getPhantomIconFromWalletStandard();
429
+ if (!icon) {
430
+ await new Promise((resolve) => setTimeout(resolve, 200));
431
+ icon = await getPhantomIconFromWalletStandard();
432
+ }
433
+ if (!icon) {
434
+ icon = "https://phantom.app/img/phantom-icon-purple.png";
435
+ }
436
+ const plugins = [(0, import_browser_injected_sdk2.createExtensionPlugin)()];
437
+ if (addressTypes.includes(import_client2.AddressType.solana)) {
438
+ plugins.push((0, import_solana.createSolanaPlugin)());
439
+ }
440
+ if (addressTypes.includes(import_client2.AddressType.ethereum)) {
441
+ plugins.push((0, import_ethereum.createEthereumPlugin)());
442
+ }
443
+ plugins.push((0, import_auto_confirm.createAutoConfirmPlugin)());
444
+ const phantomInstance = (0, import_browser_injected_sdk2.createPhantom)({ plugins });
445
+ return {
446
+ id: "phantom",
447
+ name: "Phantom",
448
+ icon,
449
+ addressTypes,
450
+ providers: {
451
+ solana: addressTypes.includes(import_client2.AddressType.solana) ? phantomInstance.solana : void 0,
452
+ ethereum: addressTypes.includes(import_client2.AddressType.ethereum) ? phantomInstance.ethereum : void 0
453
+ },
454
+ isPhantom: true,
455
+ phantomInstance
456
+ };
457
+ }
458
+ async function discoverWallets(addressTypes) {
459
+ const requestedAddressTypes = addressTypes || [];
460
+ debug.log(DebugCategory.BROWSER_SDK, "Starting all wallet discovery methods", {
461
+ addressTypes: requestedAddressTypes
462
+ });
463
+ const [phantomWallet, solanaWallets, ethereumWallets] = await Promise.all([
464
+ discoverPhantomWallet(requestedAddressTypes),
465
+ discoverSolanaWallets(),
466
+ discoverEthereumWallets()
467
+ ]);
468
+ debug.log(DebugCategory.BROWSER_SDK, "All wallet discovery methods completed", {
469
+ phantomFound: !!phantomWallet,
470
+ solanaWalletsCount: solanaWallets.length,
471
+ ethereumWalletsCount: ethereumWallets.length,
472
+ solanaWalletIds: solanaWallets.map((w) => w.id),
473
+ ethereumWalletIds: ethereumWallets.map((w) => w.id)
474
+ });
475
+ const walletMap = /* @__PURE__ */ new Map();
476
+ if (phantomWallet) {
477
+ walletMap.set("phantom", phantomWallet);
478
+ }
479
+ for (const wallet of [...solanaWallets, ...ethereumWallets]) {
480
+ const existing = walletMap.get(wallet.id);
481
+ if (existing) {
482
+ const mergedAddressTypes = Array.from(/* @__PURE__ */ new Set([...existing.addressTypes, ...wallet.addressTypes]));
483
+ const mergedProviders = {
484
+ ...existing.providers,
485
+ ...wallet.providers
486
+ };
487
+ const mergedWallet = {
488
+ ...existing,
489
+ addressTypes: mergedAddressTypes,
490
+ // Prefer icon from the most recent discovery
491
+ icon: wallet.icon || existing.icon,
492
+ providers: mergedProviders
493
+ };
494
+ walletMap.set(wallet.id, mergedWallet);
495
+ debug.log(DebugCategory.BROWSER_SDK, "Merged wallet by ID", {
496
+ walletName: wallet.name,
497
+ walletId: wallet.id,
498
+ existingAddressTypes: existing.addressTypes,
499
+ newAddressTypes: wallet.addressTypes,
500
+ mergedAddressTypes,
501
+ existingProviders: Object.keys(existing.providers || {}),
502
+ newProviders: Object.keys(wallet.providers || {}),
503
+ mergedProviders: Object.keys(mergedProviders)
504
+ });
505
+ debug.log(DebugCategory.BROWSER_SDK, "Merged wallet from multiple discovery methods", {
506
+ walletId: wallet.id,
507
+ walletName: wallet.name,
508
+ existingAddressTypes: existing.addressTypes,
509
+ newAddressTypes: wallet.addressTypes,
510
+ mergedAddressTypes
511
+ });
512
+ } else {
513
+ walletMap.set(wallet.id, wallet);
514
+ }
515
+ }
516
+ return Array.from(walletMap.values());
517
+ }
518
+
519
+ // src/providers/injected/chains/InjectedWalletSolanaChain.ts
520
+ var import_eventemitter3 = require("eventemitter3");
521
+ var import_buffer = require("buffer");
522
+ var InjectedWalletSolanaChain = class {
523
+ constructor(provider, walletId, walletName) {
524
+ this.eventEmitter = new import_eventemitter3.EventEmitter();
525
+ this._connected = false;
526
+ this._publicKey = null;
527
+ this.provider = provider;
528
+ this.walletId = walletId;
529
+ this.walletName = walletName;
530
+ this.setupEventListeners();
531
+ }
532
+ get connected() {
533
+ return this._connected;
534
+ }
535
+ get publicKey() {
536
+ return this._publicKey;
537
+ }
538
+ async connect(options) {
539
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect", {
540
+ walletId: this.walletId,
541
+ walletName: this.walletName,
542
+ onlyIfTrusted: options?.onlyIfTrusted
543
+ });
544
+ try {
545
+ const result = await this.provider.connect(options);
546
+ if (typeof result === "string") {
547
+ this._connected = true;
548
+ this._publicKey = result;
549
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
550
+ walletId: this.walletId,
551
+ walletName: this.walletName,
552
+ publicKey: result
553
+ });
554
+ return { publicKey: result };
555
+ }
556
+ if (typeof result === "object" && result !== null && "publicKey" in result) {
557
+ this._connected = true;
558
+ this._publicKey = result.publicKey;
559
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
560
+ walletId: this.walletId,
561
+ walletName: this.walletName,
562
+ publicKey: result.publicKey
563
+ });
564
+ return result;
565
+ }
566
+ if (Array.isArray(result) && result.length > 0) {
567
+ const firstAccount = result[0];
568
+ if (typeof firstAccount === "object" && firstAccount !== null && "address" in firstAccount) {
569
+ this._connected = true;
570
+ this._publicKey = firstAccount.address;
571
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
572
+ walletId: this.walletId,
573
+ walletName: this.walletName,
574
+ publicKey: firstAccount.address
575
+ });
576
+ return { publicKey: firstAccount.address };
577
+ }
578
+ }
579
+ throw new Error("Unexpected connect result format");
580
+ } catch (error) {
581
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect failed", {
582
+ walletId: this.walletId,
583
+ walletName: this.walletName,
584
+ error: error instanceof Error ? error.message : String(error)
585
+ });
586
+ throw error;
587
+ }
588
+ }
589
+ async disconnect() {
590
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana disconnect", {
591
+ walletId: this.walletId,
592
+ walletName: this.walletName
593
+ });
594
+ try {
595
+ await this.provider.disconnect();
596
+ this._connected = false;
597
+ this._publicKey = null;
598
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana disconnected", {
599
+ walletId: this.walletId,
600
+ walletName: this.walletName
601
+ });
602
+ } catch (error) {
603
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana disconnect failed", {
604
+ walletId: this.walletId,
605
+ walletName: this.walletName,
606
+ error: error instanceof Error ? error.message : String(error)
607
+ });
608
+ throw error;
609
+ }
610
+ }
611
+ async signMessage(message) {
612
+ const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
613
+ const messagePreview = typeof message === "string" ? message.substring(0, 50) : `${messageBytes.length} bytes`;
614
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signMessage", {
615
+ walletId: this.walletId,
616
+ walletName: this.walletName,
617
+ messagePreview,
618
+ messageLength: messageBytes.length
619
+ });
620
+ try {
621
+ const result = await this.provider.signMessage(message);
622
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signMessage success", {
623
+ walletId: this.walletId,
624
+ walletName: this.walletName,
625
+ signatureLength: result.signature.length
626
+ });
627
+ return {
628
+ signature: result.signature instanceof Uint8Array ? result.signature : new Uint8Array(import_buffer.Buffer.from(result.signature, "base64")),
629
+ publicKey: result.publicKey || this._publicKey || ""
630
+ };
631
+ } catch (error) {
632
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signMessage failed", {
633
+ walletId: this.walletId,
634
+ walletName: this.walletName,
635
+ error: error instanceof Error ? error.message : String(error)
636
+ });
637
+ throw error;
638
+ }
639
+ }
640
+ async signTransaction(transaction) {
641
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signTransaction", {
642
+ walletId: this.walletId,
643
+ walletName: this.walletName
644
+ });
645
+ try {
646
+ const result = await this.provider.signTransaction(transaction);
647
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signTransaction success", {
648
+ walletId: this.walletId,
649
+ walletName: this.walletName
650
+ });
651
+ return result;
652
+ } catch (error) {
653
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signTransaction failed", {
654
+ walletId: this.walletId,
655
+ walletName: this.walletName,
656
+ error: error instanceof Error ? error.message : String(error)
657
+ });
658
+ throw error;
659
+ }
660
+ }
661
+ async signAndSendTransaction(transaction) {
662
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAndSendTransaction", {
663
+ walletId: this.walletId,
664
+ walletName: this.walletName
665
+ });
666
+ try {
667
+ const result = await this.provider.signAndSendTransaction(transaction);
668
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAndSendTransaction success", {
669
+ walletId: this.walletId,
670
+ walletName: this.walletName,
671
+ signature: result.signature
672
+ });
673
+ return result;
674
+ } catch (error) {
675
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAndSendTransaction failed", {
676
+ walletId: this.walletId,
677
+ walletName: this.walletName,
678
+ error: error instanceof Error ? error.message : String(error)
679
+ });
680
+ throw error;
681
+ }
682
+ }
683
+ async signAllTransactions(transactions) {
684
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAllTransactions", {
685
+ walletId: this.walletId,
686
+ walletName: this.walletName,
687
+ transactionCount: transactions.length
688
+ });
689
+ try {
690
+ const result = await this.provider.signAllTransactions(transactions);
691
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAllTransactions success", {
692
+ walletId: this.walletId,
693
+ walletName: this.walletName,
694
+ signedCount: result.length
695
+ });
696
+ return result;
697
+ } catch (error) {
698
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAllTransactions failed", {
699
+ walletId: this.walletId,
700
+ walletName: this.walletName,
701
+ error: error instanceof Error ? error.message : String(error)
702
+ });
703
+ throw error;
704
+ }
705
+ }
706
+ async signAndSendAllTransactions(transactions) {
707
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAndSendAllTransactions", {
708
+ walletId: this.walletId,
709
+ walletName: this.walletName,
710
+ transactionCount: transactions.length
711
+ });
712
+ try {
713
+ const result = await this.provider.signAndSendAllTransactions(transactions);
714
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAndSendAllTransactions success", {
715
+ walletId: this.walletId,
716
+ walletName: this.walletName,
717
+ signatureCount: result.signatures.length
718
+ });
719
+ return result;
720
+ } catch (error) {
721
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana signAndSendAllTransactions failed", {
722
+ walletId: this.walletId,
723
+ walletName: this.walletName,
724
+ error: error instanceof Error ? error.message : String(error)
725
+ });
726
+ throw error;
727
+ }
728
+ }
729
+ switchNetwork(_network) {
730
+ return Promise.resolve();
731
+ }
732
+ getPublicKey() {
733
+ return Promise.resolve(this._publicKey);
734
+ }
735
+ isConnected() {
736
+ return this._connected;
737
+ }
738
+ setupEventListeners() {
739
+ if (typeof this.provider.on === "function") {
740
+ this.provider.on("connect", (publicKey) => {
741
+ this._connected = true;
742
+ this._publicKey = publicKey;
743
+ this.eventEmitter.emit("connect", publicKey);
744
+ });
745
+ this.provider.on("disconnect", () => {
746
+ this._connected = false;
747
+ this._publicKey = null;
748
+ this.eventEmitter.emit("disconnect");
749
+ });
750
+ this.provider.on("accountChanged", (publicKey) => {
751
+ this._publicKey = publicKey;
752
+ this.eventEmitter.emit("accountChanged", publicKey);
753
+ });
754
+ }
755
+ }
756
+ on(event, listener) {
757
+ this.eventEmitter.on(event, listener);
758
+ }
759
+ off(event, listener) {
760
+ this.eventEmitter.off(event, listener);
761
+ }
762
+ };
763
+
764
+ // src/providers/injected/chains/WalletStandardSolanaAdapter.ts
765
+ var import_parsers = require("@phantom/parsers");
766
+ var import_bs58 = __toESM(require("bs58"));
767
+ var WalletStandardSolanaAdapter = class {
768
+ constructor(wallet, walletId, walletName) {
769
+ this._connected = false;
770
+ this._publicKey = null;
771
+ this.wallet = wallet;
772
+ this.walletId = walletId;
773
+ this.walletName = walletName;
774
+ }
775
+ get connected() {
776
+ return this._connected;
777
+ }
778
+ get publicKey() {
779
+ return this._publicKey;
780
+ }
781
+ async connect(_options) {
782
+ try {
783
+ const connectFeature = this.wallet.features?.["standard:connect"];
784
+ if (!connectFeature || typeof connectFeature.connect !== "function") {
785
+ throw new Error("Wallet Standard connect feature not available");
786
+ }
787
+ const connectResult = await connectFeature.connect();
788
+ let accounts;
789
+ if (Array.isArray(connectResult) && connectResult.length > 0) {
790
+ accounts = connectResult;
791
+ } else if (this.wallet.accounts && this.wallet.accounts.length > 0) {
792
+ accounts = Array.from(this.wallet.accounts);
793
+ }
794
+ if (!accounts || accounts.length === 0) {
795
+ throw new Error("No accounts available after connecting to wallet");
796
+ }
797
+ const firstAccount = accounts[0];
798
+ if (!firstAccount) {
799
+ throw new Error("First account is null or undefined");
800
+ }
801
+ let address;
802
+ if (typeof firstAccount === "string") {
803
+ address = firstAccount;
804
+ } else if (typeof firstAccount === "object" && firstAccount !== null) {
805
+ address = firstAccount.address || firstAccount.publicKey?.toString() || (firstAccount.publicKey instanceof Uint8Array ? Buffer.from(firstAccount.publicKey).toString("hex") : void 0);
806
+ }
807
+ if (!address) {
808
+ throw new Error(
809
+ `Could not extract address from account. Account structure: ${JSON.stringify(firstAccount, null, 2)}`
810
+ );
811
+ }
812
+ this._connected = true;
813
+ this._publicKey = address;
814
+ return { publicKey: address };
815
+ } catch (error) {
816
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana connect failed", {
817
+ walletId: this.walletId,
818
+ walletName: this.walletName,
819
+ error: error instanceof Error ? error.message : String(error)
820
+ });
821
+ throw error;
822
+ }
823
+ }
824
+ async disconnect() {
825
+ try {
826
+ const disconnectFeature = this.wallet.features?.["standard:disconnect"];
827
+ if (disconnectFeature && typeof disconnectFeature.disconnect === "function") {
828
+ await disconnectFeature.disconnect();
829
+ }
830
+ this._connected = false;
831
+ this._publicKey = null;
832
+ } catch (error) {
833
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana disconnect failed", {
834
+ walletId: this.walletId,
835
+ walletName: this.walletName,
836
+ error: error instanceof Error ? error.message : String(error)
837
+ });
838
+ throw error;
839
+ }
840
+ }
841
+ async signMessage(message) {
842
+ try {
843
+ const signMessageFeature = this.wallet.features?.["solana:signMessage"];
844
+ if (!signMessageFeature || typeof signMessageFeature.signMessage !== "function") {
845
+ throw new Error("Wallet Standard signMessage feature not available");
846
+ }
847
+ const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
848
+ const result = await signMessageFeature.signMessage({
849
+ message: messageBytes,
850
+ account: this.wallet.accounts?.[0]
851
+ });
852
+ if (!Array.isArray(result) || result.length === 0) {
853
+ throw new Error(`Expected array result from signMessage, got: ${typeof result}`);
854
+ }
855
+ const signedMessageResult = result[0];
856
+ if (!signedMessageResult || !signedMessageResult.signature) {
857
+ throw new Error(`Invalid signMessage result structure: ${JSON.stringify(result)}`);
858
+ }
859
+ const signature = this.parseUint8Array(signedMessageResult.signature);
860
+ if (signature.length === 0) {
861
+ throw new Error(`Signature is empty`);
862
+ }
863
+ const publicKey = signedMessageResult.account?.address || this.wallet.accounts?.[0]?.address || this._publicKey || "";
864
+ return { signature, publicKey };
865
+ } catch (error) {
866
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signMessage failed", {
867
+ walletId: this.walletId,
868
+ walletName: this.walletName,
869
+ error: error instanceof Error ? error.message : String(error)
870
+ });
871
+ throw error;
872
+ }
873
+ }
874
+ async signTransaction(transaction) {
875
+ try {
876
+ const signTransactionFeature = this.wallet.features?.["solana:signTransaction"];
877
+ if (!signTransactionFeature || typeof signTransactionFeature.signTransaction !== "function") {
878
+ throw new Error("Wallet Standard signTransaction feature not available");
879
+ }
880
+ if (!this.wallet.accounts || this.wallet.accounts.length === 0) {
881
+ throw new Error("No accounts available. Please connect first.");
882
+ }
883
+ const account = this.wallet.accounts[0];
884
+ const serializedTransaction = this.serializeTransaction(transaction);
885
+ const results = await signTransactionFeature.signTransaction({
886
+ transaction: serializedTransaction,
887
+ account
888
+ });
889
+ let transactionData;
890
+ if (Array.isArray(results) && results.length > 0) {
891
+ const firstItem = results[0];
892
+ if (firstItem && typeof firstItem === "object") {
893
+ transactionData = firstItem.signedTransaction || firstItem.transaction;
894
+ }
895
+ } else if (results && typeof results === "object" && !Array.isArray(results)) {
896
+ transactionData = results.transaction || results.signedTransaction;
897
+ }
898
+ if (!transactionData) {
899
+ throw new Error("No transaction data found in Wallet Standard result");
900
+ }
901
+ const signedBytes = this.parseUint8Array(transactionData);
902
+ if (signedBytes.length === 0) {
903
+ throw new Error("Empty signed transaction returned from Wallet Standard");
904
+ }
905
+ const signedTx = (0, import_parsers.deserializeSolanaTransaction)(signedBytes);
906
+ return signedTx;
907
+ } catch (error) {
908
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signTransaction failed", {
909
+ walletId: this.walletId,
910
+ walletName: this.walletName,
911
+ error: error instanceof Error ? error.message : String(error)
912
+ });
913
+ throw error;
914
+ }
915
+ }
916
+ async signAndSendTransaction(transaction) {
917
+ try {
918
+ const signAndSendTransactionFeature = this.wallet.features?.["solana:signAndSendTransaction"];
919
+ if (!signAndSendTransactionFeature || typeof signAndSendTransactionFeature.signAndSendTransaction !== "function") {
920
+ throw new Error("Wallet Standard signAndSendTransaction feature not available");
921
+ }
922
+ if (!this.wallet.accounts || this.wallet.accounts.length === 0) {
923
+ throw new Error("No accounts available. Please connect first.");
924
+ }
925
+ const account = this.wallet.accounts[0];
926
+ const chain = account.chains?.[0] || "solana:mainnet";
927
+ const serializedTransaction = this.serializeTransaction(transaction);
928
+ const results = await signAndSendTransactionFeature.signAndSendTransaction({
929
+ transaction: serializedTransaction,
930
+ account,
931
+ chain
932
+ });
933
+ let signatureOutput;
934
+ if (Array.isArray(results) && results.length > 0) {
935
+ signatureOutput = results[0];
936
+ } else if (results && typeof results === "object" && !Array.isArray(results)) {
937
+ signatureOutput = results;
938
+ } else {
939
+ throw new Error("Invalid signAndSendTransaction result format");
940
+ }
941
+ if (!signatureOutput.signature) {
942
+ throw new Error("No signature found in signAndSendTransaction result");
943
+ }
944
+ const signatureBytes = this.parseUint8Array(signatureOutput.signature);
945
+ const signature = import_bs58.default.encode(signatureBytes);
946
+ return { signature };
947
+ } catch (error) {
948
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signAndSendTransaction failed", {
949
+ walletId: this.walletId,
950
+ walletName: this.walletName,
951
+ error: error instanceof Error ? error.message : String(error)
952
+ });
953
+ throw error;
954
+ }
955
+ }
956
+ async signAllTransactions(transactions) {
957
+ try {
958
+ const signedTransactions = [];
959
+ for (const transaction of transactions) {
960
+ const signedTx = await this.signTransaction(transaction);
961
+ signedTransactions.push(signedTx);
962
+ }
963
+ return signedTransactions;
964
+ } catch (error) {
965
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signAllTransactions failed", {
966
+ walletId: this.walletId,
967
+ walletName: this.walletName,
968
+ error: error instanceof Error ? error.message : String(error)
969
+ });
970
+ throw error;
971
+ }
972
+ }
973
+ async signAndSendAllTransactions(transactions) {
974
+ try {
975
+ const signatures = [];
976
+ for (const transaction of transactions) {
977
+ const result = await this.signAndSendTransaction(transaction);
978
+ signatures.push(result.signature);
979
+ }
980
+ return { signatures };
981
+ } catch (error) {
982
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signAndSendAllTransactions failed", {
983
+ walletId: this.walletId,
984
+ walletName: this.walletName,
985
+ error: error instanceof Error ? error.message : String(error)
986
+ });
987
+ throw error;
988
+ }
989
+ }
990
+ async switchNetwork(network) {
991
+ try {
992
+ const switchNetworkFeature = this.wallet.features?.["standard:switchNetwork"];
993
+ if (switchNetworkFeature && typeof switchNetworkFeature.switchNetwork === "function") {
994
+ const chainId = network === "mainnet" ? "solana:mainnet" : "solana:devnet";
995
+ await switchNetworkFeature.switchNetwork({ chain: chainId });
996
+ }
997
+ } catch (error) {
998
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana switchNetwork failed", {
999
+ walletId: this.walletId,
1000
+ walletName: this.walletName,
1001
+ network,
1002
+ error: error instanceof Error ? error.message : String(error)
1003
+ });
1004
+ throw error;
1005
+ }
1006
+ }
1007
+ getPublicKey() {
1008
+ return Promise.resolve(this._publicKey);
1009
+ }
1010
+ isConnected() {
1011
+ return this._connected;
1012
+ }
1013
+ on(_event, _listener) {
1014
+ const eventsFeature = this.wallet.features?.["standard:events"];
1015
+ if (eventsFeature && typeof eventsFeature.on === "function") {
1016
+ eventsFeature.on(_event, _listener);
1017
+ }
1018
+ }
1019
+ off(_event, _listener) {
1020
+ const eventsFeature = this.wallet.features?.["standard:events"];
1021
+ if (eventsFeature && typeof eventsFeature.off === "function") {
1022
+ eventsFeature.off(_event, _listener);
1023
+ }
1024
+ }
1025
+ /**
1026
+ * Serialize a transaction to Uint8Array for Wallet Standard API
1027
+ */
1028
+ serializeTransaction(transaction) {
1029
+ if (typeof transaction.serialize === "function") {
1030
+ return transaction.serialize({
1031
+ requireAllSignatures: false,
1032
+ verifySignatures: false
1033
+ });
1034
+ }
1035
+ if (transaction instanceof Uint8Array) {
1036
+ return transaction;
1037
+ }
1038
+ return new Uint8Array(0);
1039
+ }
1040
+ /**
1041
+ * Parse a Uint8Array from various formats
1042
+ * Handles: Uint8Array, Array, object with numeric keys (JSON-serialized Uint8Array)
1043
+ */
1044
+ parseUint8Array(value) {
1045
+ if (value instanceof Uint8Array) {
1046
+ return value;
1047
+ }
1048
+ if (Array.isArray(value)) {
1049
+ return new Uint8Array(value);
1050
+ }
1051
+ if (typeof value === "object" && value !== null) {
1052
+ const keys = Object.keys(value).map(Number).filter((k) => !isNaN(k) && k >= 0).sort((a, b) => a - b);
1053
+ if (keys.length > 0) {
1054
+ const maxKey = Math.max(...keys);
1055
+ const array = new Uint8Array(maxKey + 1);
1056
+ for (const key of keys) {
1057
+ array[key] = Number(value[key]) || 0;
1058
+ }
1059
+ return array;
1060
+ }
1061
+ }
1062
+ return new Uint8Array(0);
1063
+ }
1064
+ };
1065
+
1066
+ // src/providers/injected/chains/InjectedWalletEthereumChain.ts
1067
+ var import_eventemitter32 = require("eventemitter3");
1068
+ var InjectedWalletEthereumChain = class {
1069
+ constructor(provider, walletId, walletName) {
1070
+ this.eventEmitter = new import_eventemitter32.EventEmitter();
1071
+ this._connected = false;
1072
+ this._chainId = "0x1";
1073
+ this._accounts = [];
1074
+ this.provider = provider;
1075
+ this.walletId = walletId;
1076
+ this.walletName = walletName;
1077
+ this.setupEventListeners();
1078
+ }
1079
+ get connected() {
1080
+ return this._connected;
1081
+ }
1082
+ get chainId() {
1083
+ return this._chainId;
1084
+ }
1085
+ get accounts() {
1086
+ return this._accounts;
1087
+ }
1088
+ async request(args) {
1089
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum request", {
1090
+ walletId: this.walletId,
1091
+ walletName: this.walletName,
1092
+ method: args.method
1093
+ });
1094
+ try {
1095
+ const requiresAuth = [
1096
+ "personal_sign",
1097
+ "eth_sign",
1098
+ "eth_signTypedData",
1099
+ "eth_signTypedData_v4",
1100
+ "eth_sendTransaction",
1101
+ "eth_signTransaction"
1102
+ ].includes(args.method);
1103
+ if (requiresAuth && (!this._connected || this._accounts.length === 0)) {
1104
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Method requires authorization, ensuring connection", {
1105
+ walletId: this.walletId,
1106
+ walletName: this.walletName,
1107
+ method: args.method
1108
+ });
1109
+ await this.connect();
1110
+ }
1111
+ const result = await this.provider.request(args);
1112
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum request success", {
1113
+ walletId: this.walletId,
1114
+ walletName: this.walletName,
1115
+ method: args.method
1116
+ });
1117
+ return result;
1118
+ } catch (error) {
1119
+ if (error?.code === 4100) {
1120
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Got 4100 Unauthorized, attempting to re-authorize", {
1121
+ walletId: this.walletId,
1122
+ walletName: this.walletName,
1123
+ method: args.method
1124
+ });
1125
+ try {
1126
+ await this.provider.request({ method: "eth_requestAccounts" });
1127
+ const result = await this.provider.request(args);
1128
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum request success (after re-auth)", {
1129
+ walletId: this.walletId,
1130
+ walletName: this.walletName,
1131
+ method: args.method
1132
+ });
1133
+ return result;
1134
+ } catch (retryError) {
1135
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Failed after re-authorization", {
1136
+ walletId: this.walletId,
1137
+ walletName: this.walletName,
1138
+ method: args.method,
1139
+ error: retryError instanceof Error ? retryError.message : String(retryError)
1140
+ });
1141
+ throw retryError;
1142
+ }
1143
+ }
1144
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum request failed", {
1145
+ walletId: this.walletId,
1146
+ walletName: this.walletName,
1147
+ method: args.method,
1148
+ error: error instanceof Error ? error.message : String(error),
1149
+ errorCode: error?.code
1150
+ });
1151
+ throw error;
1152
+ }
1153
+ }
1154
+ async connect() {
1155
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum connect", {
1156
+ walletId: this.walletId,
1157
+ walletName: this.walletName
1158
+ });
1159
+ try {
1160
+ const accounts = await this.provider.request({ method: "eth_requestAccounts" });
1161
+ this._connected = accounts.length > 0;
1162
+ this._accounts = accounts;
1163
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum connected (via eth_requestAccounts)", {
1164
+ walletId: this.walletId,
1165
+ walletName: this.walletName,
1166
+ accountCount: accounts.length,
1167
+ accounts
1168
+ });
1169
+ return accounts;
1170
+ } catch (error) {
1171
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum connect failed", {
1172
+ walletId: this.walletId,
1173
+ walletName: this.walletName,
1174
+ error: error instanceof Error ? error.message : String(error)
1175
+ });
1176
+ throw error;
1177
+ }
1178
+ }
1179
+ async disconnect() {
1180
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum disconnect", {
1181
+ walletId: this.walletId,
1182
+ walletName: this.walletName
1183
+ });
1184
+ try {
1185
+ await this.provider.disconnect();
1186
+ this._connected = false;
1187
+ this._accounts = [];
1188
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum disconnected", {
1189
+ walletId: this.walletId,
1190
+ walletName: this.walletName
1191
+ });
1192
+ } catch (error) {
1193
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum disconnect failed", {
1194
+ walletId: this.walletId,
1195
+ walletName: this.walletName,
1196
+ error: error instanceof Error ? error.message : String(error)
1197
+ });
1198
+ throw error;
1199
+ }
1200
+ }
1201
+ async signPersonalMessage(message, address) {
1202
+ const messagePreview = message.length > 50 ? message.substring(0, 50) + "..." : message;
1203
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signPersonalMessage", {
1204
+ walletId: this.walletId,
1205
+ walletName: this.walletName,
1206
+ messagePreview,
1207
+ messageLength: message.length,
1208
+ address
1209
+ });
1210
+ try {
1211
+ const providerConnected = this.provider.isConnected?.() || this.provider.connected || false;
1212
+ if (!this._connected || this._accounts.length === 0 || !providerConnected) {
1213
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Not connected, attempting to connect before signing", {
1214
+ walletId: this.walletId,
1215
+ walletName: this.walletName,
1216
+ internalConnected: this._connected,
1217
+ accountsLength: this._accounts.length,
1218
+ providerConnected
1219
+ });
1220
+ await this.connect();
1221
+ }
1222
+ const normalizedAddress = address.toLowerCase();
1223
+ const normalizedAccounts = this._accounts.map((acc) => acc.toLowerCase());
1224
+ if (!normalizedAccounts.includes(normalizedAddress)) {
1225
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Address not in connected accounts, refreshing connection", {
1226
+ walletId: this.walletId,
1227
+ walletName: this.walletName,
1228
+ requestedAddress: address,
1229
+ connectedAccounts: this._accounts
1230
+ });
1231
+ const currentAccounts = await this.getAccounts();
1232
+ const normalizedCurrentAccounts = currentAccounts.map((acc) => acc.toLowerCase());
1233
+ if (!normalizedCurrentAccounts.includes(normalizedAddress)) {
1234
+ throw new Error(`Address ${address} is not connected. Connected accounts: ${currentAccounts.join(", ")}`);
1235
+ }
1236
+ this._accounts = currentAccounts;
1237
+ }
1238
+ if (typeof this.provider.signPersonalMessage === "function") {
1239
+ const result2 = await this.provider.signPersonalMessage(message, address);
1240
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signPersonalMessage success", {
1241
+ walletId: this.walletId,
1242
+ walletName: this.walletName,
1243
+ signatureLength: result2.length
1244
+ });
1245
+ return result2;
1246
+ }
1247
+ const result = await this.request({
1248
+ method: "personal_sign",
1249
+ params: [message, address]
1250
+ });
1251
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signPersonalMessage success", {
1252
+ walletId: this.walletId,
1253
+ walletName: this.walletName,
1254
+ signatureLength: result.length
1255
+ });
1256
+ return result;
1257
+ } catch (error) {
1258
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signPersonalMessage failed", {
1259
+ walletId: this.walletId,
1260
+ walletName: this.walletName,
1261
+ error: error instanceof Error ? error.message : String(error),
1262
+ errorCode: error?.code
1263
+ });
1264
+ throw error;
1265
+ }
71
1266
  }
72
- setLevel(level) {
73
- this.level = level;
1267
+ async signTypedData(typedData, address) {
1268
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTypedData", {
1269
+ walletId: this.walletId,
1270
+ walletName: this.walletName,
1271
+ primaryType: typedData?.primaryType,
1272
+ address
1273
+ });
1274
+ try {
1275
+ if (typeof this.provider.signTypedData === "function") {
1276
+ const result2 = await this.provider.signTypedData(typedData, address);
1277
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTypedData success", {
1278
+ walletId: this.walletId,
1279
+ walletName: this.walletName,
1280
+ signatureLength: result2.length
1281
+ });
1282
+ return result2;
1283
+ }
1284
+ const result = await this.request({
1285
+ method: "eth_signTypedData_v4",
1286
+ params: [address, typedData]
1287
+ });
1288
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTypedData success", {
1289
+ walletId: this.walletId,
1290
+ walletName: this.walletName,
1291
+ signatureLength: result.length
1292
+ });
1293
+ return result;
1294
+ } catch (error) {
1295
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTypedData failed", {
1296
+ walletId: this.walletId,
1297
+ walletName: this.walletName,
1298
+ error: error instanceof Error ? error.message : String(error)
1299
+ });
1300
+ throw error;
1301
+ }
74
1302
  }
75
- enable() {
76
- this.enabled = true;
1303
+ async signTransaction(transaction) {
1304
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTransaction", {
1305
+ walletId: this.walletId,
1306
+ walletName: this.walletName,
1307
+ from: transaction.from,
1308
+ to: transaction.to
1309
+ });
1310
+ try {
1311
+ if (typeof this.provider.signTransaction === "function") {
1312
+ const result2 = await this.provider.signTransaction(transaction);
1313
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTransaction success", {
1314
+ walletId: this.walletId,
1315
+ walletName: this.walletName,
1316
+ signatureLength: result2.length
1317
+ });
1318
+ return result2;
1319
+ }
1320
+ const result = await this.request({
1321
+ method: "eth_signTransaction",
1322
+ params: [transaction]
1323
+ });
1324
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTransaction success", {
1325
+ walletId: this.walletId,
1326
+ walletName: this.walletName,
1327
+ signatureLength: result.length
1328
+ });
1329
+ return result;
1330
+ } catch (error) {
1331
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum signTransaction failed", {
1332
+ walletId: this.walletId,
1333
+ walletName: this.walletName,
1334
+ error: error instanceof Error ? error.message : String(error)
1335
+ });
1336
+ throw error;
1337
+ }
77
1338
  }
78
- disable() {
79
- this.enabled = false;
1339
+ async sendTransaction(transaction) {
1340
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum sendTransaction", {
1341
+ walletId: this.walletId,
1342
+ walletName: this.walletName,
1343
+ from: transaction.from,
1344
+ to: transaction.to,
1345
+ value: transaction.value
1346
+ });
1347
+ try {
1348
+ if (typeof this.provider.sendTransaction === "function") {
1349
+ const result2 = await this.provider.sendTransaction(transaction);
1350
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum sendTransaction success", {
1351
+ walletId: this.walletId,
1352
+ walletName: this.walletName,
1353
+ txHash: result2
1354
+ });
1355
+ return result2;
1356
+ }
1357
+ const result = await this.request({
1358
+ method: "eth_sendTransaction",
1359
+ params: [transaction]
1360
+ });
1361
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum sendTransaction success", {
1362
+ walletId: this.walletId,
1363
+ walletName: this.walletName,
1364
+ txHash: result
1365
+ });
1366
+ return result;
1367
+ } catch (error) {
1368
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum sendTransaction failed", {
1369
+ walletId: this.walletId,
1370
+ walletName: this.walletName,
1371
+ error: error instanceof Error ? error.message : String(error)
1372
+ });
1373
+ throw error;
1374
+ }
80
1375
  }
81
- writeLog(level, category, message, data) {
82
- if (!this.enabled || level > this.level) {
83
- return;
1376
+ async switchChain(chainId) {
1377
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum switchChain", {
1378
+ walletId: this.walletId,
1379
+ walletName: this.walletName,
1380
+ chainId
1381
+ });
1382
+ try {
1383
+ const hexChainId = typeof chainId === "string" ? chainId.toLowerCase().startsWith("0x") ? chainId : `0x${parseInt(chainId, 10).toString(16)}` : `0x${chainId.toString(16)}`;
1384
+ if (typeof this.provider.switchChain === "function") {
1385
+ await this.provider.switchChain(hexChainId);
1386
+ } else {
1387
+ await this.request({ method: "wallet_switchEthereumChain", params: [{ chainId: hexChainId }] });
1388
+ }
1389
+ this._chainId = hexChainId;
1390
+ this.eventEmitter.emit("chainChanged", this._chainId);
1391
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum switchChain success", {
1392
+ walletId: this.walletId,
1393
+ walletName: this.walletName,
1394
+ chainId: hexChainId
1395
+ });
1396
+ } catch (error) {
1397
+ debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum switchChain failed", {
1398
+ walletId: this.walletId,
1399
+ walletName: this.walletName,
1400
+ error: error instanceof Error ? error.message : String(error)
1401
+ });
1402
+ throw error;
84
1403
  }
85
- const debugMessage = {
86
- timestamp: Date.now(),
87
- level,
88
- category,
89
- message,
90
- data
91
- };
92
- if (this.callback) {
93
- this.callback(debugMessage);
1404
+ }
1405
+ async getChainId() {
1406
+ if (typeof this.provider.getChainId === "function") {
1407
+ const chainId2 = await this.provider.getChainId();
1408
+ this._chainId = `0x${chainId2.toString(16)}`;
1409
+ return chainId2;
94
1410
  }
1411
+ const chainId = await this.request({ method: "eth_chainId" });
1412
+ const parsed = parseInt(chainId, 16);
1413
+ this._chainId = chainId;
1414
+ return parsed;
95
1415
  }
96
- error(category, message, data) {
97
- this.writeLog(0 /* ERROR */, category, message, data);
1416
+ async getAccounts() {
1417
+ if (typeof this.provider.getAccounts === "function") {
1418
+ const accounts2 = await this.provider.getAccounts();
1419
+ this._accounts = accounts2;
1420
+ return accounts2;
1421
+ }
1422
+ const accounts = await this.request({ method: "eth_accounts" });
1423
+ this._accounts = accounts;
1424
+ return accounts;
98
1425
  }
99
- warn(category, message, data) {
100
- this.writeLog(1 /* WARN */, category, message, data);
1426
+ isConnected() {
1427
+ return this._connected;
101
1428
  }
102
- info(category, message, data) {
103
- this.writeLog(2 /* INFO */, category, message, data);
1429
+ setupEventListeners() {
1430
+ if (typeof this.provider.on === "function") {
1431
+ this.provider.on("connect", (info) => {
1432
+ this._connected = true;
1433
+ this._chainId = info.chainId;
1434
+ this.eventEmitter.emit("connect", info);
1435
+ });
1436
+ this.provider.on("disconnect", (error) => {
1437
+ this._connected = false;
1438
+ this._accounts = [];
1439
+ this.eventEmitter.emit("disconnect", error);
1440
+ this.eventEmitter.emit("accountsChanged", []);
1441
+ });
1442
+ this.provider.on("accountsChanged", (accounts) => {
1443
+ this._accounts = accounts;
1444
+ this.eventEmitter.emit("accountsChanged", accounts);
1445
+ });
1446
+ this.provider.on("chainChanged", (chainId) => {
1447
+ this._chainId = chainId;
1448
+ this.eventEmitter.emit("chainChanged", chainId);
1449
+ });
1450
+ }
104
1451
  }
105
- debug(category, message, data) {
106
- this.writeLog(3 /* DEBUG */, category, message, data);
1452
+ on(event, listener) {
1453
+ this.eventEmitter.on(event, listener);
107
1454
  }
108
- log(category, message, data) {
109
- this.writeLog(3 /* DEBUG */, category, message, data);
1455
+ off(event, listener) {
1456
+ this.eventEmitter.off(event, listener);
110
1457
  }
111
1458
  };
112
- var debug = Debug.getInstance();
113
- var DebugCategory = {
114
- BROWSER_SDK: "BrowserSDK",
115
- PROVIDER_MANAGER: "ProviderManager",
116
- EMBEDDED_PROVIDER: "EmbeddedProvider",
117
- INJECTED_PROVIDER: "InjectedProvider",
118
- PHANTOM_CONNECT_AUTH: "PhantomConnectAuth",
119
- JWT_AUTH: "JWTAuth",
120
- STORAGE: "Storage",
121
- SESSION: "Session"
122
- };
123
1459
 
124
1460
  // src/providers/injected/chains/SolanaChain.ts
125
- var import_eventemitter3 = require("eventemitter3");
126
- var import_client2 = require("@phantom/client");
127
- var import_buffer = require("buffer");
128
- var InjectedSolanaChain = class {
129
- constructor(phantom, callbacks) {
130
- this._connected = false;
1461
+ var import_eventemitter33 = require("eventemitter3");
1462
+ var import_buffer2 = require("buffer");
1463
+ var PhantomSolanaChain = class {
1464
+ constructor(phantom) {
131
1465
  this._publicKey = null;
132
- this.eventEmitter = new import_eventemitter3.EventEmitter();
1466
+ this.eventEmitter = new import_eventemitter33.EventEmitter();
133
1467
  this.phantom = phantom;
134
- this.callbacks = callbacks;
135
1468
  this.setupEventListeners();
136
- this.syncInitialState();
137
1469
  }
138
1470
  // Wallet adapter compliant properties
139
1471
  get connected() {
140
- return this._connected;
1472
+ return this._publicKey !== null;
141
1473
  }
142
1474
  get publicKey() {
143
1475
  return this._publicKey;
144
1476
  }
145
- // Connection methods - delegate to provider
146
- connect(_options) {
147
- if (!this.callbacks.isConnected()) {
148
- return Promise.reject(new Error("Provider not connected. Call provider connect first."));
149
- }
150
- const addresses = this.callbacks.getAddresses();
151
- const solanaAddress = addresses.find((addr) => addr.addressType === import_client2.AddressType.solana);
152
- if (!solanaAddress) {
153
- return Promise.reject(new Error("Solana not enabled for this provider"));
1477
+ // Connection methods
1478
+ async connect(options) {
1479
+ const result = await this.phantom.solana.connect(options);
1480
+ if (!result) {
1481
+ throw new Error("Failed to connect to Solana wallet");
154
1482
  }
155
- this.updateConnectionState(true, solanaAddress.address);
156
- return Promise.resolve({ publicKey: solanaAddress.address });
1483
+ const publicKey = typeof result === "string" ? result : "";
1484
+ this._publicKey = publicKey;
1485
+ return { publicKey };
157
1486
  }
158
1487
  async disconnect() {
159
- await this.callbacks.disconnect();
1488
+ await this.phantom.solana.disconnect();
1489
+ this._publicKey = null;
160
1490
  }
161
1491
  // Standard wallet adapter methods
162
1492
  async signMessage(message) {
163
1493
  const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
164
1494
  const result = await this.phantom.solana.signMessage(messageBytes);
165
1495
  return {
166
- signature: result.signature instanceof Uint8Array ? result.signature : new Uint8Array(import_buffer.Buffer.from(result.signature, "base64")),
1496
+ signature: result.signature instanceof Uint8Array ? result.signature : new Uint8Array(import_buffer2.Buffer.from(result.signature, "base64")),
167
1497
  publicKey: this._publicKey || ""
168
1498
  };
169
1499
  }
170
1500
  async signTransaction(transaction) {
171
- if (!this.callbacks.isConnected()) {
1501
+ if (!this.connected) {
172
1502
  return Promise.reject(new Error("Provider not connected. Call provider connect first."));
173
1503
  }
174
1504
  try {
@@ -183,7 +1513,7 @@ var InjectedSolanaChain = class {
183
1513
  return { signature: result.signature };
184
1514
  }
185
1515
  async signAllTransactions(transactions) {
186
- if (!this.callbacks.isConnected()) {
1516
+ if (!this.connected) {
187
1517
  return Promise.reject(new Error("Provider not connected. Call provider connect first."));
188
1518
  }
189
1519
  try {
@@ -194,7 +1524,7 @@ var InjectedSolanaChain = class {
194
1524
  }
195
1525
  }
196
1526
  async signAndSendAllTransactions(transactions) {
197
- if (!this.callbacks.isConnected()) {
1527
+ if (!this.connected) {
198
1528
  return Promise.reject(new Error("Provider not connected. Call provider connect first."));
199
1529
  }
200
1530
  try {
@@ -212,42 +1542,21 @@ var InjectedSolanaChain = class {
212
1542
  return Promise.resolve(this._publicKey);
213
1543
  }
214
1544
  isConnected() {
215
- return this._connected && this.callbacks.isConnected();
1545
+ return this.connected;
216
1546
  }
217
1547
  setupEventListeners() {
218
1548
  this.phantom.solana.addEventListener("connect", (publicKey) => {
219
- this.updateConnectionState(true, publicKey);
1549
+ this._publicKey = publicKey;
220
1550
  this.eventEmitter.emit("connect", publicKey);
221
1551
  });
222
1552
  this.phantom.solana.addEventListener("disconnect", () => {
223
- this.updateConnectionState(false, null);
1553
+ this._publicKey = null;
224
1554
  this.eventEmitter.emit("disconnect");
225
1555
  });
226
1556
  this.phantom.solana.addEventListener("accountChanged", (publicKey) => {
227
1557
  this._publicKey = publicKey;
228
1558
  this.eventEmitter.emit("accountChanged", publicKey);
229
1559
  });
230
- this.callbacks.on("connect", (data) => {
231
- const solanaAddress = data.addresses?.find((addr) => addr.addressType === import_client2.AddressType.solana);
232
- if (solanaAddress) {
233
- this.updateConnectionState(true, solanaAddress.address);
234
- }
235
- });
236
- this.callbacks.on("disconnect", () => {
237
- this.updateConnectionState(false, null);
238
- });
239
- }
240
- syncInitialState() {
241
- if (this.callbacks.isConnected()) {
242
- const solanaAddress = this.callbacks.getAddresses().find((addr) => addr.addressType === import_client2.AddressType.solana);
243
- if (solanaAddress) {
244
- this.updateConnectionState(true, solanaAddress.address);
245
- }
246
- }
247
- }
248
- updateConnectionState(connected, publicKey) {
249
- this._connected = connected;
250
- this._publicKey = publicKey;
251
1560
  }
252
1561
  // Event methods for interface compliance
253
1562
  on(event, listener) {
@@ -259,22 +1568,18 @@ var InjectedSolanaChain = class {
259
1568
  };
260
1569
 
261
1570
  // src/providers/injected/chains/EthereumChain.ts
262
- var import_eventemitter32 = require("eventemitter3");
263
- var import_client3 = require("@phantom/client");
264
- var InjectedEthereumChain = class {
265
- constructor(phantom, callbacks) {
266
- this._connected = false;
1571
+ var import_eventemitter34 = require("eventemitter3");
1572
+ var PhantomEthereumChain = class {
1573
+ constructor(phantom) {
267
1574
  this._chainId = "0x1";
268
1575
  this._accounts = [];
269
- this.eventEmitter = new import_eventemitter32.EventEmitter();
1576
+ this.eventEmitter = new import_eventemitter34.EventEmitter();
270
1577
  this.phantom = phantom;
271
- this.callbacks = callbacks;
272
1578
  this.setupEventListeners();
273
- this.syncInitialState();
274
1579
  }
275
1580
  // EIP-1193 compliant properties
276
1581
  get connected() {
277
- return this._connected;
1582
+ return this._accounts.length > 0;
278
1583
  }
279
1584
  get chainId() {
280
1585
  return this._chainId;
@@ -289,21 +1594,18 @@ var InjectedEthereumChain = class {
289
1594
  const result = await this.signTransaction(transaction);
290
1595
  return result;
291
1596
  }
292
- const provider = await this.phantom.ethereum.getProvider();
293
- return await provider.request(args);
1597
+ const phantomProvider = await this.phantom.ethereum.getProvider();
1598
+ return await phantomProvider.request(args);
294
1599
  }
295
- // Connection methods - delegate to provider
296
- connect() {
297
- if (!this.callbacks.isConnected()) {
298
- return Promise.reject(new Error("Provider not connected. Call provider connect first."));
299
- }
300
- const addresses = this.callbacks.getAddresses();
301
- const ethAddresses = addresses.filter((addr) => addr.addressType === import_client3.AddressType.ethereum).map((addr) => addr.address);
302
- this.updateConnectionState(true, ethAddresses);
303
- return Promise.resolve(ethAddresses);
1600
+ // Connection methods
1601
+ async connect() {
1602
+ const accounts = await this.phantom.ethereum.getAccounts();
1603
+ this._accounts = accounts;
1604
+ return accounts;
304
1605
  }
305
1606
  async disconnect() {
306
- await this.callbacks.disconnect();
1607
+ await this.phantom.ethereum.disconnect();
1608
+ this._accounts = [];
307
1609
  }
308
1610
  // Standard compliant methods (return raw values, not wrapped objects)
309
1611
  async signPersonalMessage(message, address) {
@@ -332,16 +1634,16 @@ var InjectedEthereumChain = class {
332
1634
  return await this.phantom.ethereum.getAccounts();
333
1635
  }
334
1636
  isConnected() {
335
- return this._connected && this.callbacks.isConnected();
1637
+ return this.connected;
336
1638
  }
337
1639
  setupEventListeners() {
338
1640
  this.phantom.ethereum.addEventListener("connect", (accounts) => {
339
- this.updateConnectionState(true, accounts);
1641
+ this._accounts = accounts;
340
1642
  this.eventEmitter.emit("connect", { chainId: this._chainId });
341
1643
  this.eventEmitter.emit("accountsChanged", accounts);
342
1644
  });
343
1645
  this.phantom.ethereum.addEventListener("disconnect", () => {
344
- this.updateConnectionState(false, []);
1646
+ this._accounts = [];
345
1647
  this.eventEmitter.emit("disconnect", { code: 4900, message: "Provider disconnected" });
346
1648
  this.eventEmitter.emit("accountsChanged", []);
347
1649
  });
@@ -353,27 +1655,6 @@ var InjectedEthereumChain = class {
353
1655
  this._chainId = chainId;
354
1656
  this.eventEmitter.emit("chainChanged", chainId);
355
1657
  });
356
- this.callbacks.on("connect", (data) => {
357
- const ethAddresses = data.addresses?.filter((addr) => addr.addressType === import_client3.AddressType.ethereum)?.map((addr) => addr.address) || [];
358
- if (ethAddresses.length > 0) {
359
- this.updateConnectionState(true, ethAddresses);
360
- }
361
- });
362
- this.callbacks.on("disconnect", () => {
363
- this.updateConnectionState(false, []);
364
- });
365
- }
366
- syncInitialState() {
367
- if (this.callbacks.isConnected()) {
368
- const ethAddresses = this.callbacks.getAddresses().filter((addr) => addr.addressType === import_client3.AddressType.ethereum).map((addr) => addr.address);
369
- if (ethAddresses.length > 0) {
370
- this.updateConnectionState(true, ethAddresses);
371
- }
372
- }
373
- }
374
- updateConnectionState(connected, accounts) {
375
- this._connected = connected;
376
- this._accounts = accounts;
377
1658
  }
378
1659
  // Event methods for interface compliance
379
1660
  on(event, listener) {
@@ -384,64 +1665,400 @@ var InjectedEthereumChain = class {
384
1665
  }
385
1666
  };
386
1667
 
1668
+ // src/wallets/registry.ts
1669
+ function isPhantomWallet(wallet) {
1670
+ return wallet !== void 0 && wallet.id === "phantom" && "isPhantom" in wallet && wallet.isPhantom === true;
1671
+ }
1672
+ var InjectedWalletRegistry = class {
1673
+ constructor() {
1674
+ this.wallets = /* @__PURE__ */ new Map();
1675
+ this.discoveryPromise = null;
1676
+ }
1677
+ register(info) {
1678
+ const wrappedProviders = {};
1679
+ if (info.providers?.solana) {
1680
+ const isWalletStandard = info.providers.solana && typeof info.providers.solana === "object" && "features" in info.providers.solana && typeof info.providers.solana.features === "object";
1681
+ if (isWalletStandard) {
1682
+ wrappedProviders.solana = new WalletStandardSolanaAdapter(info.providers.solana, info.id, info.name);
1683
+ debug.log(DebugCategory.BROWSER_SDK, "Wrapped Wallet Standard Solana wallet with adapter", {
1684
+ walletId: info.id,
1685
+ walletName: info.name
1686
+ });
1687
+ } else {
1688
+ wrappedProviders.solana = new InjectedWalletSolanaChain(info.providers.solana, info.id, info.name);
1689
+ debug.log(DebugCategory.BROWSER_SDK, "Wrapped Solana provider with InjectedWalletSolanaChain", {
1690
+ walletId: info.id,
1691
+ walletName: info.name
1692
+ });
1693
+ }
1694
+ }
1695
+ if (info.providers?.ethereum) {
1696
+ wrappedProviders.ethereum = new InjectedWalletEthereumChain(info.providers.ethereum, info.id, info.name);
1697
+ debug.log(DebugCategory.BROWSER_SDK, "Wrapped Ethereum provider with InjectedWalletEthereumChain", {
1698
+ walletId: info.id,
1699
+ walletName: info.name
1700
+ });
1701
+ }
1702
+ const wrappedInfo = {
1703
+ ...info,
1704
+ providers: Object.keys(wrappedProviders).length > 0 ? wrappedProviders : info.providers
1705
+ };
1706
+ this.wallets.set(info.id, wrappedInfo);
1707
+ }
1708
+ /**
1709
+ * Register Phantom wallet with its instance
1710
+ * This creates wrapped providers and stores the Phantom instance for auto-confirm access
1711
+ */
1712
+ registerPhantom(phantomInstance, addressTypes, icon) {
1713
+ const wrappedProviders = {};
1714
+ if (addressTypes.includes(import_client.AddressType.solana) && phantomInstance.solana) {
1715
+ wrappedProviders.solana = new PhantomSolanaChain(phantomInstance);
1716
+ debug.log(DebugCategory.BROWSER_SDK, "Created PhantomSolanaChain wrapper", {
1717
+ walletId: "phantom"
1718
+ });
1719
+ }
1720
+ if (addressTypes.includes(import_client.AddressType.ethereum) && phantomInstance.ethereum) {
1721
+ wrappedProviders.ethereum = new PhantomEthereumChain(phantomInstance);
1722
+ debug.log(DebugCategory.BROWSER_SDK, "Created PhantomEthereumChain wrapper", {
1723
+ walletId: "phantom"
1724
+ });
1725
+ }
1726
+ const phantomWallet = {
1727
+ id: "phantom",
1728
+ name: "Phantom",
1729
+ icon: icon || "https://phantom.app/img/phantom-icon-purple.png",
1730
+ addressTypes,
1731
+ providers: wrappedProviders,
1732
+ isPhantom: true,
1733
+ phantomInstance
1734
+ };
1735
+ this.wallets.set("phantom", phantomWallet);
1736
+ debug.log(DebugCategory.BROWSER_SDK, "Registered Phantom wallet with chain wrappers", {
1737
+ addressTypes,
1738
+ hasSolana: !!wrappedProviders.solana,
1739
+ hasEthereum: !!wrappedProviders.ethereum
1740
+ });
1741
+ }
1742
+ unregister(id) {
1743
+ this.wallets.delete(id);
1744
+ }
1745
+ has(id) {
1746
+ return this.wallets.has(id);
1747
+ }
1748
+ getById(id) {
1749
+ return this.wallets.get(id);
1750
+ }
1751
+ getAll() {
1752
+ return Array.from(this.wallets.values());
1753
+ }
1754
+ getByAddressTypes(addressTypes) {
1755
+ if (addressTypes.length === 0) {
1756
+ return this.getAll();
1757
+ }
1758
+ const allowed = new Set(addressTypes);
1759
+ return this.getAll().filter((wallet) => wallet.addressTypes.some((t) => allowed.has(t)));
1760
+ }
1761
+ discover(addressTypes) {
1762
+ if (this.discoveryPromise) {
1763
+ return this.discoveryPromise;
1764
+ }
1765
+ debug.log(DebugCategory.BROWSER_SDK, "Starting wallet discovery", { addressTypes });
1766
+ this.discoveryPromise = discoverWallets(addressTypes).then((discoveredWallets) => {
1767
+ const relevantWallets = addressTypes ? discoveredWallets.filter((wallet) => wallet.addressTypes.some((type) => addressTypes.includes(type))) : discoveredWallets;
1768
+ for (const wallet of relevantWallets) {
1769
+ if (wallet.id === "phantom" && isPhantomWallet(wallet)) {
1770
+ this.registerPhantom(wallet.phantomInstance, wallet.addressTypes, wallet.icon);
1771
+ } else {
1772
+ this.register(wallet);
1773
+ }
1774
+ debug.log(DebugCategory.BROWSER_SDK, "Registered discovered wallet", {
1775
+ id: wallet.id,
1776
+ name: wallet.name,
1777
+ addressTypes: wallet.addressTypes
1778
+ });
1779
+ }
1780
+ debug.info(DebugCategory.BROWSER_SDK, "Wallet discovery completed", {
1781
+ totalDiscovered: discoveredWallets.length,
1782
+ relevantWallets: relevantWallets.length
1783
+ });
1784
+ }).catch((error) => {
1785
+ debug.warn(DebugCategory.BROWSER_SDK, "Wallet discovery failed", { error });
1786
+ this.discoveryPromise = null;
1787
+ throw error;
1788
+ });
1789
+ return this.discoveryPromise;
1790
+ }
1791
+ };
1792
+ var walletRegistry = null;
1793
+ function getWalletRegistry() {
1794
+ if (!walletRegistry) {
1795
+ walletRegistry = new InjectedWalletRegistry();
1796
+ }
1797
+ return walletRegistry;
1798
+ }
1799
+
387
1800
  // src/providers/injected/index.ts
388
1801
  var WAS_CONNECTED_KEY = "phantom-injected-was-connected";
389
1802
  var WAS_CONNECTED_VALUE = "true";
1803
+ var LAST_WALLET_ID_KEY = "phantom-injected-last-wallet-id";
390
1804
  var InjectedProvider = class {
1805
+ // Track which wallets have event listeners set up
391
1806
  constructor(config) {
392
- this.connected = false;
393
- this.addresses = [];
1807
+ this.selectedWalletId = null;
1808
+ this.walletStates = /* @__PURE__ */ new Map();
394
1809
  // Event management
395
1810
  this.eventListeners = /* @__PURE__ */ new Map();
396
1811
  this.browserInjectedCleanupFunctions = [];
397
1812
  this.eventsInitialized = false;
1813
+ this.externalWalletEventListenersSetup = /* @__PURE__ */ new Set();
398
1814
  debug.log(DebugCategory.INJECTED_PROVIDER, "Initializing InjectedProvider", { config });
399
1815
  this.addressTypes = config.addressTypes;
1816
+ this.walletRegistry = getWalletRegistry();
400
1817
  debug.log(DebugCategory.INJECTED_PROVIDER, "Address types configured", { addressTypes: this.addressTypes });
401
- const plugins = [(0, import_browser_injected_sdk.createExtensionPlugin)()];
402
- if (this.addressTypes.includes(import_client4.AddressType.solana)) {
403
- plugins.push((0, import_solana.createSolanaPlugin)());
404
- debug.log(DebugCategory.INJECTED_PROVIDER, "Solana plugin added");
405
- }
406
- if (this.addressTypes.includes(import_client4.AddressType.ethereum)) {
407
- plugins.push((0, import_ethereum.createEthereumPlugin)());
408
- debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
409
- }
410
- plugins.push((0, import_auto_confirm.createAutoConfirmPlugin)());
411
- debug.log(DebugCategory.INJECTED_PROVIDER, "AutoConfirm plugin added");
412
- debug.log(DebugCategory.INJECTED_PROVIDER, "Creating Phantom instance with plugins", {
413
- pluginCount: plugins.length
1818
+ this.walletRegistry.discover(this.addressTypes).catch((error) => {
1819
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Wallet discovery failed during initialization", { error });
414
1820
  });
415
- this.phantom = (0, import_browser_injected_sdk.createPhantom)({ plugins });
416
- const callbacks = this.createCallbacks();
417
- if (this.addressTypes.includes(import_client4.AddressType.solana)) {
418
- this._solanaChain = new InjectedSolanaChain(this.phantom, callbacks);
1821
+ debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
1822
+ }
1823
+ /**
1824
+ * Wait for wallet discovery to complete if the wallet is not yet in the registry
1825
+ * This is needed for auto-connect when the last wallet was an external wallet
1826
+ */
1827
+ async waitForWalletDiscovery(walletId) {
1828
+ if (this.walletRegistry.has(walletId)) {
1829
+ return;
419
1830
  }
420
- if (this.addressTypes.includes(import_client4.AddressType.ethereum)) {
421
- this._ethereumChain = new InjectedEthereumChain(this.phantom, callbacks);
1831
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Wallet not found in registry, waiting for discovery", {
1832
+ walletId
1833
+ });
1834
+ try {
1835
+ await this.walletRegistry.discover(this.addressTypes);
1836
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Wallet discovery completed", { walletId });
1837
+ } catch (error) {
1838
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Wallet discovery failed", {
1839
+ walletId,
1840
+ error: error instanceof Error ? error.message : String(error)
1841
+ });
422
1842
  }
423
- debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
424
1843
  }
425
1844
  get solana() {
426
- if (!this.addressTypes.includes(import_client4.AddressType.solana)) {
1845
+ if (!this.addressTypes.includes(import_client3.AddressType.solana)) {
427
1846
  throw new Error("Solana not enabled for this provider");
428
1847
  }
429
- if (!this._solanaChain) {
430
- throw new Error("Solana chain not initialized");
1848
+ const walletId = this.selectedWalletId || "phantom";
1849
+ const walletInfo = this.walletRegistry.getById(walletId);
1850
+ if (!walletInfo) {
1851
+ const registry = this.walletRegistry;
1852
+ if (registry.discoveryPromise) {
1853
+ throw new Error(
1854
+ `Wallet "${walletId}" not found. Wallet discovery is still in progress. Please wait for sdk.discoverWallets() to complete before accessing chain properties.`
1855
+ );
1856
+ }
1857
+ throw new Error(
1858
+ `Wallet "${walletId}" not found. Please ensure wallet discovery has completed. Make sure you call sdk.discoverWallets() and await it before accessing chain properties.`
1859
+ );
1860
+ }
1861
+ if (!walletInfo.providers?.solana) {
1862
+ throw new Error(
1863
+ `Selected wallet "${walletInfo.name}" does not support Solana. This wallet only supports: ${walletInfo.addressTypes.join(", ")}. Make sure your SDK config includes Solana in addressTypes.`
1864
+ );
1865
+ }
1866
+ return walletInfo.providers.solana;
1867
+ }
1868
+ /**
1869
+ * Access to Ethereum chain operations
1870
+ */
1871
+ get ethereum() {
1872
+ if (!this.addressTypes.includes(import_client3.AddressType.ethereum)) {
1873
+ throw new Error("Ethereum not enabled for this provider");
1874
+ }
1875
+ const walletId = this.selectedWalletId || "phantom";
1876
+ const walletInfo = this.walletRegistry.getById(walletId);
1877
+ if (!walletInfo) {
1878
+ const registry = this.walletRegistry;
1879
+ if (registry.discoveryPromise) {
1880
+ throw new Error(
1881
+ `Wallet "${walletId}" not found. Wallet discovery is still in progress. Please wait for sdk.discoverWallets() to complete before accessing chain properties.`
1882
+ );
1883
+ }
1884
+ throw new Error(
1885
+ `Wallet "${walletId}" not found. Please ensure wallet discovery has completed. Make sure you call sdk.discoverWallets() and await it before accessing chain properties.`
1886
+ );
1887
+ }
1888
+ if (!walletInfo.providers?.ethereum) {
1889
+ throw new Error(
1890
+ `Selected wallet "${walletInfo.name}" does not support Ethereum. This wallet only supports: ${walletInfo.addressTypes.join(", ")}. Make sure your SDK config includes Ethereum in addressTypes.`
1891
+ );
1892
+ }
1893
+ return walletInfo.providers.ethereum;
1894
+ }
1895
+ validateAndSelectWallet(requestedWalletId) {
1896
+ if (!this.walletRegistry.has(requestedWalletId)) {
1897
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Unknown injected wallet id requested", {
1898
+ walletId: requestedWalletId
1899
+ });
1900
+ throw new Error(`Unknown injected wallet id: ${requestedWalletId}`);
1901
+ }
1902
+ const walletInfo = this.walletRegistry.getById(requestedWalletId);
1903
+ if (!walletInfo || !walletInfo.providers) {
1904
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Wallet not available for connection", {
1905
+ walletId: requestedWalletId
1906
+ });
1907
+ throw new Error(`Wallet not available for connection: ${requestedWalletId}`);
1908
+ }
1909
+ this.selectedWalletId = requestedWalletId;
1910
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Selected injected wallet for connection", {
1911
+ walletId: requestedWalletId
1912
+ });
1913
+ return walletInfo;
1914
+ }
1915
+ async connectToWallet(walletInfo, options) {
1916
+ if (!walletInfo.providers) {
1917
+ const error = new Error(`Wallet adapter not available for wallet: ${this.selectedWalletId}`);
1918
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet adapter not available", { walletId: this.selectedWalletId });
1919
+ this.emit("connect_error", {
1920
+ error: error.message,
1921
+ source: options?.skipEventListeners ? "auto-connect" : "manual-connect"
1922
+ });
1923
+ throw error;
1924
+ }
1925
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Connecting via wallet", {
1926
+ walletId: this.selectedWalletId,
1927
+ walletName: walletInfo.name,
1928
+ options
1929
+ });
1930
+ if (!options?.skipEventListeners) {
1931
+ this.setupExternalWalletEvents(walletInfo);
1932
+ if (this.selectedWalletId === "phantom" && isPhantomWallet(walletInfo)) {
1933
+ this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
1934
+ this.browserInjectedCleanupFunctions = [];
1935
+ this.setupBrowserInjectedEvents();
1936
+ this.eventsInitialized = true;
1937
+ }
1938
+ }
1939
+ const connectedAddresses = [];
1940
+ if (this.addressTypes.includes(import_client3.AddressType.solana) && walletInfo.providers?.solana) {
1941
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection", {
1942
+ walletId: this.selectedWalletId,
1943
+ walletName: walletInfo.name,
1944
+ onlyIfTrusted: options?.onlyIfTrusted
1945
+ });
1946
+ try {
1947
+ const result = await walletInfo.providers.solana.connect(
1948
+ options?.onlyIfTrusted ? { onlyIfTrusted: true } : void 0
1949
+ );
1950
+ const address = result.publicKey;
1951
+ connectedAddresses.push({
1952
+ addressType: import_client3.AddressType.solana,
1953
+ address
1954
+ });
1955
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", {
1956
+ address,
1957
+ walletId: this.selectedWalletId,
1958
+ walletName: walletInfo.name
1959
+ });
1960
+ } catch (err) {
1961
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana, stopping", {
1962
+ error: err,
1963
+ walletId: this.selectedWalletId,
1964
+ walletName: walletInfo.name
1965
+ });
1966
+ this.emit("connect_error", {
1967
+ error: err instanceof Error ? err.message : "Failed to connect",
1968
+ source: options?.skipEventListeners ? "auto-connect" : "manual-connect"
1969
+ });
1970
+ throw err;
1971
+ }
1972
+ }
1973
+ if (this.addressTypes.includes(import_client3.AddressType.ethereum) && walletInfo.providers?.ethereum) {
1974
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Ethereum connection", {
1975
+ walletId: this.selectedWalletId,
1976
+ walletName: walletInfo.name,
1977
+ silent: options?.silent
1978
+ });
1979
+ try {
1980
+ let accounts;
1981
+ if (options?.silent) {
1982
+ accounts = await walletInfo.providers.ethereum.request({ method: "eth_accounts" });
1983
+ } else {
1984
+ accounts = await walletInfo.providers.ethereum.connect();
1985
+ }
1986
+ if (accounts.length > 0) {
1987
+ connectedAddresses.push(
1988
+ ...accounts.map((address) => ({
1989
+ addressType: import_client3.AddressType.ethereum,
1990
+ address
1991
+ }))
1992
+ );
1993
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum connected successfully", {
1994
+ addresses: accounts,
1995
+ walletId: this.selectedWalletId,
1996
+ walletName: walletInfo.name
1997
+ });
1998
+ }
1999
+ } catch (err) {
2000
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum, stopping", {
2001
+ error: err,
2002
+ walletId: this.selectedWalletId,
2003
+ walletName: walletInfo.name
2004
+ });
2005
+ this.emit("connect_error", {
2006
+ error: err instanceof Error ? err.message : "Failed to connect",
2007
+ source: options?.skipEventListeners ? "auto-connect" : "manual-connect"
2008
+ });
2009
+ throw err;
2010
+ }
431
2011
  }
432
- return this._solanaChain;
2012
+ return connectedAddresses;
433
2013
  }
434
- /**
435
- * Access to Ethereum chain operations
436
- */
437
- get ethereum() {
438
- if (!this.addressTypes.includes(import_client4.AddressType.ethereum)) {
439
- throw new Error("Ethereum not enabled for this provider");
2014
+ async finalizeConnection(connectedAddresses, authProvider, walletId) {
2015
+ if (connectedAddresses.length === 0) {
2016
+ const error = new Error("Failed to connect to any supported wallet provider");
2017
+ this.emit("connect_error", {
2018
+ error: error.message,
2019
+ source: "manual-connect"
2020
+ });
2021
+ throw error;
440
2022
  }
441
- if (!this._ethereumChain) {
442
- throw new Error("Ethereum chain not initialized");
2023
+ if (this.selectedWalletId) {
2024
+ this.setWalletState(this.selectedWalletId, {
2025
+ connected: true,
2026
+ addresses: connectedAddresses
2027
+ });
443
2028
  }
444
- return this._ethereumChain;
2029
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Finalized connection with addresses", {
2030
+ addressCount: connectedAddresses.length,
2031
+ addresses: connectedAddresses.map((addr) => ({
2032
+ type: addr.addressType,
2033
+ address: addr.address.substring(0, 10) + "..."
2034
+ }))
2035
+ });
2036
+ const authUserId = await this.getAuthUserId("manual-connect");
2037
+ try {
2038
+ localStorage.setItem(WAS_CONNECTED_KEY, WAS_CONNECTED_VALUE);
2039
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Set was-connected flag - auto-reconnect enabled");
2040
+ if (this.selectedWalletId) {
2041
+ localStorage.setItem(LAST_WALLET_ID_KEY, this.selectedWalletId);
2042
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Stored last injected wallet id", {
2043
+ walletId: this.selectedWalletId
2044
+ });
2045
+ }
2046
+ } catch (error) {
2047
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to persist injected provider state", { error });
2048
+ }
2049
+ const result = {
2050
+ addresses: connectedAddresses,
2051
+ status: "completed",
2052
+ authUserId,
2053
+ authProvider,
2054
+ walletId
2055
+ };
2056
+ this.emit("connect", {
2057
+ addresses: connectedAddresses,
2058
+ source: "manual-connect",
2059
+ authUserId
2060
+ });
2061
+ return result;
445
2062
  }
446
2063
  async connect(authOptions) {
447
2064
  debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider connect", {
@@ -456,110 +2073,48 @@ var InjectedProvider = class {
456
2073
  providerType: "injected"
457
2074
  });
458
2075
  try {
459
- if (!this.phantom.extension?.isInstalled?.()) {
460
- debug.error(DebugCategory.INJECTED_PROVIDER, "Phantom wallet extension not found");
461
- const error = new Error("Phantom wallet not found");
462
- this.emit("connect_error", {
463
- error: error.message,
464
- source: "manual-connect"
465
- });
466
- throw error;
467
- }
468
- debug.log(DebugCategory.INJECTED_PROVIDER, "Phantom extension detected");
469
- const connectedAddresses = [];
470
- if (this.addressTypes.includes(import_client4.AddressType.solana)) {
471
- debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
2076
+ const requestedWalletId = authOptions.walletId || "phantom";
2077
+ const walletInfo = this.validateAndSelectWallet(requestedWalletId);
2078
+ const connectedAddresses = await this.connectToWallet(walletInfo);
2079
+ return await this.finalizeConnection(connectedAddresses, "injected", this.selectedWalletId || void 0);
2080
+ } catch (error) {
2081
+ this.emit("connect_error", {
2082
+ error: error instanceof Error ? error.message : "Failed to connect",
2083
+ source: "manual-connect"
2084
+ });
2085
+ throw error;
2086
+ }
2087
+ }
2088
+ async disconnect() {
2089
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
2090
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
2091
+ if (walletInfo?.providers) {
2092
+ if (this.addressTypes.includes(import_client3.AddressType.solana) && walletInfo.providers.solana) {
472
2093
  try {
473
- const publicKey = await this.phantom.solana.connect();
474
- if (publicKey) {
475
- connectedAddresses.push({
476
- addressType: import_client4.AddressType.solana,
477
- address: publicKey
478
- });
479
- debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
480
- }
2094
+ await walletInfo.providers.solana.disconnect();
2095
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
481
2096
  } catch (err) {
482
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana, stopping", { error: err });
483
- this.emit("connect_error", {
484
- error: err instanceof Error ? err.message : "Failed to connect",
485
- source: "manual-connect"
486
- });
487
- throw err;
2097
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
488
2098
  }
489
2099
  }
490
- if (this.addressTypes.includes(import_client4.AddressType.ethereum)) {
2100
+ if (this.addressTypes.includes(import_client3.AddressType.ethereum) && walletInfo.providers.ethereum) {
491
2101
  try {
492
- const accounts = await this.phantom.ethereum.connect();
493
- if (accounts && accounts.length > 0) {
494
- connectedAddresses.push(
495
- ...accounts.map((address) => ({
496
- addressType: import_client4.AddressType.ethereum,
497
- address
498
- }))
499
- );
500
- debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum connected successfully", { addresses: accounts });
501
- }
2102
+ await walletInfo.providers.ethereum.disconnect();
2103
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected successfully");
502
2104
  } catch (err) {
503
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum, stopping", { error: err });
504
- this.emit("connect_error", {
505
- error: err instanceof Error ? err.message : "Failed to connect",
506
- source: "manual-connect"
507
- });
508
- throw err;
2105
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Ethereum", { error: err });
509
2106
  }
510
2107
  }
511
- if (connectedAddresses.length === 0) {
512
- const error = new Error("Failed to connect to any supported wallet provider");
513
- this.emit("connect_error", {
514
- error: error.message,
515
- source: "manual-connect"
516
- });
517
- throw error;
518
- }
519
- this.addresses = connectedAddresses;
520
- this.connected = true;
521
- const authUserId = await this.getAuthUserId("manual-connect");
522
- try {
523
- localStorage.setItem(WAS_CONNECTED_KEY, WAS_CONNECTED_VALUE);
524
- debug.log(DebugCategory.INJECTED_PROVIDER, "Set was-connected flag - auto-reconnect enabled");
525
- } catch (error) {
526
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to set was-connected flag", { error });
527
- }
528
- const result = {
529
- addresses: this.addresses,
530
- status: "completed",
531
- authUserId
532
- };
533
- this.emit("connect", {
534
- addresses: this.addresses,
535
- source: "manual-connect",
536
- authUserId
537
- });
538
- return result;
539
- } catch (error) {
540
- if (error instanceof Error && !error.message.includes("Phantom wallet not found") && !error.message.includes("Failed to connect to any supported wallet provider")) {
541
- this.emit("connect_error", {
542
- error: error.message,
543
- source: "manual-connect"
544
- });
545
- }
546
- throw error;
547
- }
548
- }
549
- async disconnect() {
550
- debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
551
- if (this.addressTypes.includes(import_client4.AddressType.solana)) {
552
- try {
553
- await this.phantom.solana.disconnect();
554
- debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
555
- } catch (err) {
556
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
557
- }
558
2108
  }
559
2109
  this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
560
2110
  this.browserInjectedCleanupFunctions = [];
561
- this.connected = false;
562
- this.addresses = [];
2111
+ if (this.selectedWalletId) {
2112
+ this.externalWalletEventListenersSetup.delete(this.selectedWalletId);
2113
+ this.setWalletState(this.selectedWalletId, {
2114
+ connected: false,
2115
+ addresses: []
2116
+ });
2117
+ }
563
2118
  try {
564
2119
  localStorage.removeItem(WAS_CONNECTED_KEY);
565
2120
  debug.log(DebugCategory.INJECTED_PROVIDER, "Cleared was connected flag to prevent auto-reconnect");
@@ -578,13 +2133,17 @@ var InjectedProvider = class {
578
2133
  */
579
2134
  async autoConnect() {
580
2135
  debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting auto-connect");
2136
+ let lastWalletId = null;
581
2137
  try {
582
2138
  const wasConnected = localStorage.getItem(WAS_CONNECTED_KEY);
583
2139
  if (wasConnected !== WAS_CONNECTED_VALUE) {
584
2140
  debug.log(DebugCategory.INJECTED_PROVIDER, "Skipping auto-connect: user was not previously connected");
585
2141
  return;
586
2142
  }
587
- debug.log(DebugCategory.INJECTED_PROVIDER, "User was previously connected, attempting auto-connect");
2143
+ lastWalletId = localStorage.getItem(LAST_WALLET_ID_KEY);
2144
+ debug.log(DebugCategory.INJECTED_PROVIDER, "User was previously connected, attempting auto-connect", {
2145
+ lastWalletId: lastWalletId || "phantom"
2146
+ });
588
2147
  } catch (error) {
589
2148
  debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to check was-connected flag", { error });
590
2149
  return;
@@ -594,53 +2153,22 @@ var InjectedProvider = class {
594
2153
  providerType: "injected"
595
2154
  });
596
2155
  try {
597
- if (!this.phantom.extension?.isInstalled?.()) {
598
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Phantom wallet extension not found for auto-connect");
599
- this.emit("connect_error", {
600
- error: "Phantom wallet not found",
601
- source: "auto-connect"
2156
+ const walletId = lastWalletId || "phantom";
2157
+ await this.waitForWalletDiscovery(walletId);
2158
+ const walletInfo = this.validateAndSelectWallet(walletId);
2159
+ let connectedAddresses = [];
2160
+ try {
2161
+ connectedAddresses = await this.connectToWallet(walletInfo, {
2162
+ onlyIfTrusted: true,
2163
+ silent: true,
2164
+ skipEventListeners: true
2165
+ // Set up listeners only if connection succeeds
2166
+ });
2167
+ } catch (err) {
2168
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Auto-connect failed (expected if not trusted)", {
2169
+ error: err,
2170
+ walletId: this.selectedWalletId
602
2171
  });
603
- return;
604
- }
605
- const connectedAddresses = [];
606
- if (this.addressTypes.includes(import_client4.AddressType.solana)) {
607
- debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana auto-connect");
608
- try {
609
- const publicKey = await this.phantom.solana.connect({ onlyIfTrusted: true });
610
- if (publicKey) {
611
- connectedAddresses.push({
612
- addressType: import_client4.AddressType.solana,
613
- address: publicKey
614
- });
615
- debug.info(DebugCategory.INJECTED_PROVIDER, "Solana auto-connected successfully", { address: publicKey });
616
- }
617
- } catch (err) {
618
- debug.log(DebugCategory.INJECTED_PROVIDER, "Solana auto-connect failed (expected if not trusted)", {
619
- error: err
620
- });
621
- throw err;
622
- }
623
- }
624
- if (this.addressTypes.includes(import_client4.AddressType.ethereum)) {
625
- debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Ethereum auto-connect");
626
- try {
627
- const accounts = await this.phantom.ethereum.connect({ onlyIfTrusted: true });
628
- if (accounts && accounts.length > 0) {
629
- connectedAddresses.push(
630
- ...accounts.map((address) => ({
631
- addressType: import_client4.AddressType.ethereum,
632
- address
633
- }))
634
- );
635
- debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connected successfully", {
636
- addresses: accounts
637
- });
638
- }
639
- } catch (err) {
640
- debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connect failed (expected if not trusted)", {
641
- error: err
642
- });
643
- }
644
2172
  }
645
2173
  if (connectedAddresses.length === 0) {
646
2174
  debug.log(DebugCategory.INJECTED_PROVIDER, "Auto-connect failed: no trusted connections available");
@@ -650,11 +2178,22 @@ var InjectedProvider = class {
650
2178
  });
651
2179
  return;
652
2180
  }
653
- this.addresses = connectedAddresses;
654
- this.connected = true;
2181
+ this.setupExternalWalletEvents(walletInfo);
2182
+ if (this.selectedWalletId === "phantom" && isPhantomWallet(walletInfo)) {
2183
+ this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
2184
+ this.browserInjectedCleanupFunctions = [];
2185
+ this.setupBrowserInjectedEvents();
2186
+ this.eventsInitialized = true;
2187
+ }
2188
+ if (this.selectedWalletId) {
2189
+ this.setWalletState(this.selectedWalletId, {
2190
+ connected: true,
2191
+ addresses: connectedAddresses
2192
+ });
2193
+ }
655
2194
  const authUserId = await this.getAuthUserId("auto-connect");
656
2195
  this.emit("connect", {
657
- addresses: this.addresses,
2196
+ addresses: connectedAddresses,
658
2197
  source: "auto-connect",
659
2198
  authUserId
660
2199
  });
@@ -664,6 +2203,7 @@ var InjectedProvider = class {
664
2203
  type: addr.addressType,
665
2204
  address: addr.address.substring(0, 8) + "..."
666
2205
  })),
2206
+ walletId: this.selectedWalletId,
667
2207
  authUserId
668
2208
  });
669
2209
  } catch (error) {
@@ -676,34 +2216,80 @@ var InjectedProvider = class {
676
2216
  });
677
2217
  }
678
2218
  }
2219
+ getWalletState(walletId) {
2220
+ if (!this.walletStates.has(walletId)) {
2221
+ this.walletStates.set(walletId, { connected: false, addresses: [] });
2222
+ }
2223
+ return this.walletStates.get(walletId);
2224
+ }
2225
+ setWalletState(walletId, state) {
2226
+ this.walletStates.set(walletId, state);
2227
+ }
679
2228
  getAddresses() {
680
- return this.addresses;
2229
+ const walletId = this.selectedWalletId || "phantom";
2230
+ return this.getWalletState(walletId).addresses;
2231
+ }
2232
+ /**
2233
+ * Get enabled address types for the current selected wallet
2234
+ * - For Phantom: returns config.addressTypes
2235
+ * - For external wallets: returns the wallet's addressTypes from registry
2236
+ */
2237
+ getEnabledAddressTypes() {
2238
+ if (!this.selectedWalletId || this.selectedWalletId === "phantom") {
2239
+ return this.addressTypes;
2240
+ }
2241
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId);
2242
+ if (walletInfo) {
2243
+ return walletInfo.addressTypes;
2244
+ }
2245
+ return this.addressTypes;
681
2246
  }
682
2247
  isConnected() {
683
- return this.connected;
2248
+ const walletId = this.selectedWalletId || "phantom";
2249
+ return this.getWalletState(walletId).connected;
684
2250
  }
685
- // AutoConfirm methods - only available for injected providers
2251
+ // AutoConfirm methods - only available for Phantom wallet
686
2252
  async enableAutoConfirm(params) {
2253
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
2254
+ if (!isPhantomWallet(walletInfo)) {
2255
+ throw new Error("Auto-confirm is only available for Phantom wallet");
2256
+ }
687
2257
  debug.log(DebugCategory.INJECTED_PROVIDER, "Enabling autoConfirm", { params });
688
- return await this.phantom.autoConfirm.autoConfirmEnable(params);
2258
+ return await walletInfo.phantomInstance.autoConfirm.autoConfirmEnable(params);
689
2259
  }
690
2260
  async disableAutoConfirm() {
2261
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
2262
+ if (!isPhantomWallet(walletInfo)) {
2263
+ throw new Error("Auto-confirm is only available for Phantom wallet");
2264
+ }
691
2265
  debug.log(DebugCategory.INJECTED_PROVIDER, "Disabling autoConfirm");
692
- await this.phantom.autoConfirm.autoConfirmDisable();
2266
+ await walletInfo.phantomInstance.autoConfirm.autoConfirmDisable();
693
2267
  }
694
2268
  async getAutoConfirmStatus() {
2269
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
2270
+ if (!isPhantomWallet(walletInfo)) {
2271
+ throw new Error("Auto-confirm is only available for Phantom wallet");
2272
+ }
695
2273
  debug.log(DebugCategory.INJECTED_PROVIDER, "Getting autoConfirm status");
696
- return await this.phantom.autoConfirm.autoConfirmStatus();
2274
+ return await walletInfo.phantomInstance.autoConfirm.autoConfirmStatus();
697
2275
  }
698
2276
  async getSupportedAutoConfirmChains() {
2277
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
2278
+ if (!isPhantomWallet(walletInfo)) {
2279
+ throw new Error("Auto-confirm is only available for Phantom wallet");
2280
+ }
699
2281
  debug.log(DebugCategory.INJECTED_PROVIDER, "Getting supported autoConfirm chains");
700
- return await this.phantom.autoConfirm.autoConfirmSupportedChains();
2282
+ return await walletInfo.phantomInstance.autoConfirm.autoConfirmSupportedChains();
701
2283
  }
702
2284
  /**
703
2285
  * Helper method to get authUserId from window.phantom.app.getUser()
704
- * Returns undefined if the method is not available or fails
2286
+ * Returns undefined if the method is not available or fails, or if wallet is not Phantom
705
2287
  */
706
2288
  async getAuthUserId(context) {
2289
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
2290
+ if (!isPhantomWallet(walletInfo)) {
2291
+ return void 0;
2292
+ }
707
2293
  try {
708
2294
  if (window.phantom?.app?.getUser) {
709
2295
  const userInfo = await window.phantom.app.getUser();
@@ -767,140 +2353,245 @@ var InjectedProvider = class {
767
2353
  }
768
2354
  }
769
2355
  setupBrowserInjectedEvents() {
770
- debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up browser-injected-sdk event listeners");
771
- if (this.addressTypes.includes(import_client4.AddressType.solana)) {
772
- this.setupSolanaEvents();
2356
+ const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
2357
+ if (!isPhantomWallet(walletInfo)) {
2358
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Skipping browser-injected-sdk event setup - not Phantom wallet");
2359
+ return;
773
2360
  }
774
- if (this.addressTypes.includes(import_client4.AddressType.ethereum)) {
775
- this.setupEthereumEvents();
2361
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up browser-injected-sdk event listeners");
2362
+ if (this.selectedWalletId === "phantom" && isPhantomWallet(walletInfo)) {
2363
+ if (this.addressTypes.includes(import_client3.AddressType.solana)) {
2364
+ this.setupSolanaEvents(walletInfo.phantomInstance);
2365
+ }
2366
+ if (this.addressTypes.includes(import_client3.AddressType.ethereum)) {
2367
+ this.setupEthereumEvents(walletInfo.phantomInstance);
2368
+ }
776
2369
  }
777
2370
  }
778
- setupSolanaEvents() {
2371
+ setupSolanaEvents(phantom) {
779
2372
  debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners");
780
2373
  const handleSolanaConnect = async (publicKey) => {
781
2374
  debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey });
782
- const solanaAddress = { addressType: import_client4.AddressType.solana, address: publicKey };
783
- if (!this.addresses.find((addr) => addr.addressType === import_client4.AddressType.solana)) {
784
- this.addresses.push(solanaAddress);
785
- }
786
- this.connected = true;
2375
+ const walletId = this.selectedWalletId || "phantom";
2376
+ const state = this.getWalletState(walletId);
2377
+ const solanaAddress = { addressType: import_client3.AddressType.solana, address: publicKey };
2378
+ const hasSolana = state.addresses.some((addr) => addr.addressType === import_client3.AddressType.solana);
2379
+ const newAddresses = hasSolana ? state.addresses.map((addr) => addr.addressType === import_client3.AddressType.solana ? solanaAddress : addr) : [...state.addresses, solanaAddress];
2380
+ this.setWalletState(walletId, {
2381
+ connected: true,
2382
+ addresses: newAddresses
2383
+ });
787
2384
  const authUserId = await this.getAuthUserId("Solana connect event");
788
2385
  this.emit("connect", {
789
- addresses: this.addresses,
2386
+ addresses: newAddresses,
790
2387
  source: "injected-extension",
791
2388
  authUserId
792
2389
  });
793
2390
  };
794
2391
  const handleSolanaDisconnect = () => {
795
2392
  debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnect event received");
796
- this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.solana);
797
- this.connected = false;
2393
+ const walletId = this.selectedWalletId || "phantom";
2394
+ const state = this.getWalletState(walletId);
2395
+ const filteredAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.solana);
2396
+ this.setWalletState(walletId, {
2397
+ connected: filteredAddresses.length > 0,
2398
+ addresses: filteredAddresses
2399
+ });
798
2400
  this.emit("disconnect", {
799
2401
  source: "injected-extension"
800
2402
  });
801
2403
  };
802
2404
  const handleSolanaAccountChanged = async (publicKey) => {
803
2405
  debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey });
804
- const solanaIndex = this.addresses.findIndex((addr) => addr.addressType === import_client4.AddressType.solana);
805
- if (solanaIndex >= 0) {
806
- this.addresses[solanaIndex] = { addressType: import_client4.AddressType.solana, address: publicKey };
807
- } else {
808
- this.addresses.push({ addressType: import_client4.AddressType.solana, address: publicKey });
809
- }
2406
+ const walletId = this.selectedWalletId || "phantom";
2407
+ const state = this.getWalletState(walletId);
2408
+ const solanaIndex = state.addresses.findIndex((addr) => addr.addressType === import_client3.AddressType.solana);
2409
+ const newAddresses = solanaIndex >= 0 ? state.addresses.map(
2410
+ (addr, idx) => idx === solanaIndex ? { addressType: import_client3.AddressType.solana, address: publicKey } : addr
2411
+ ) : [...state.addresses, { addressType: import_client3.AddressType.solana, address: publicKey }];
2412
+ this.setWalletState(walletId, {
2413
+ connected: true,
2414
+ addresses: newAddresses
2415
+ });
810
2416
  const authUserId = await this.getAuthUserId("Solana account changed event");
811
2417
  this.emit("connect", {
812
- addresses: this.addresses,
2418
+ addresses: newAddresses,
813
2419
  source: "injected-extension-account-change",
814
2420
  authUserId
815
2421
  });
816
2422
  };
817
- const cleanupConnect = this.phantom.solana.addEventListener("connect", handleSolanaConnect);
818
- const cleanupDisconnect = this.phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
819
- const cleanupAccountChanged = this.phantom.solana.addEventListener("accountChanged", handleSolanaAccountChanged);
2423
+ const cleanupConnect = phantom.solana.addEventListener("connect", handleSolanaConnect);
2424
+ const cleanupDisconnect = phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
2425
+ const cleanupAccountChanged = phantom.solana.addEventListener("accountChanged", handleSolanaAccountChanged);
820
2426
  this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountChanged);
821
2427
  }
822
- setupEthereumEvents() {
2428
+ setupEthereumEvents(phantom) {
823
2429
  debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners");
824
2430
  const handleEthereumConnect = async (accounts) => {
825
2431
  debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts });
826
- this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.ethereum);
827
- if (accounts && accounts.length > 0) {
828
- this.addresses.push(
829
- ...accounts.map((address) => ({
830
- addressType: import_client4.AddressType.ethereum,
831
- address
832
- }))
833
- );
834
- }
835
- this.connected = this.addresses.length > 0;
2432
+ const walletId = this.selectedWalletId || "phantom";
2433
+ const state = this.getWalletState(walletId);
2434
+ const ethAddresses = accounts.map((address) => ({ addressType: import_client3.AddressType.ethereum, address }));
2435
+ const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
2436
+ const newAddresses = [...otherAddresses, ...ethAddresses];
2437
+ this.setWalletState(walletId, {
2438
+ connected: true,
2439
+ addresses: newAddresses
2440
+ });
836
2441
  const authUserId = await this.getAuthUserId("Ethereum connect event");
837
2442
  this.emit("connect", {
838
- addresses: this.addresses,
2443
+ addresses: newAddresses,
839
2444
  source: "injected-extension",
840
2445
  authUserId
841
2446
  });
842
2447
  };
843
2448
  const handleEthereumDisconnect = () => {
844
2449
  debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received");
845
- this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.ethereum);
846
- this.connected = false;
2450
+ const walletId = this.selectedWalletId || "phantom";
2451
+ const state = this.getWalletState(walletId);
2452
+ const filteredAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
2453
+ this.setWalletState(walletId, {
2454
+ connected: filteredAddresses.length > 0,
2455
+ addresses: filteredAddresses
2456
+ });
847
2457
  this.emit("disconnect", {
848
2458
  source: "injected-extension"
849
2459
  });
850
2460
  };
851
2461
  const handleEthereumAccountsChanged = async (accounts) => {
852
2462
  debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts });
853
- this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.ethereum);
2463
+ const walletId = this.selectedWalletId || "phantom";
2464
+ const state = this.getWalletState(walletId);
2465
+ const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
854
2466
  if (accounts && accounts.length > 0) {
855
- this.addresses.push(
856
- ...accounts.map((address) => ({
857
- addressType: import_client4.AddressType.ethereum,
858
- address
859
- }))
860
- );
2467
+ const ethAddresses = accounts.map((address) => ({ addressType: import_client3.AddressType.ethereum, address }));
2468
+ const newAddresses = [...otherAddresses, ...ethAddresses];
2469
+ this.setWalletState(walletId, {
2470
+ connected: true,
2471
+ addresses: newAddresses
2472
+ });
861
2473
  const authUserId = await this.getAuthUserId("Ethereum accounts changed event");
862
2474
  this.emit("connect", {
863
- addresses: this.addresses,
2475
+ addresses: newAddresses,
864
2476
  source: "injected-extension-account-change",
865
2477
  authUserId
866
2478
  });
867
2479
  } else {
868
- this.connected = false;
2480
+ this.setWalletState(walletId, {
2481
+ connected: otherAddresses.length > 0,
2482
+ addresses: otherAddresses
2483
+ });
869
2484
  this.emit("disconnect", {
870
2485
  source: "injected-extension-account-change"
871
2486
  });
872
2487
  }
873
2488
  };
874
- const cleanupConnect = this.phantom.ethereum.addEventListener("connect", handleEthereumConnect);
875
- const cleanupDisconnect = this.phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
876
- const cleanupAccountsChanged = this.phantom.ethereum.addEventListener(
877
- "accountsChanged",
878
- handleEthereumAccountsChanged
879
- );
2489
+ const cleanupConnect = phantom.ethereum.addEventListener("connect", handleEthereumConnect);
2490
+ const cleanupDisconnect = phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
2491
+ const cleanupAccountsChanged = phantom.ethereum.addEventListener("accountsChanged", handleEthereumAccountsChanged);
880
2492
  this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountsChanged);
881
2493
  }
882
- createCallbacks() {
883
- return {
884
- connect: async () => {
885
- const result = await this.connect({ provider: "injected" });
886
- return result.addresses;
887
- },
888
- disconnect: async () => {
889
- await this.disconnect();
890
- },
891
- isConnected: () => {
892
- return this.isConnected();
893
- },
894
- getAddresses: () => {
895
- return this.getAddresses();
896
- },
897
- on: (event, callback) => {
898
- this.on(event, callback);
899
- },
900
- off: (event, callback) => {
901
- this.off(event, callback);
2494
+ setupExternalWalletEvents(walletInfo) {
2495
+ if (isPhantomWallet(walletInfo)) {
2496
+ return;
2497
+ }
2498
+ if (!this.selectedWalletId || this.externalWalletEventListenersSetup.has(this.selectedWalletId)) {
2499
+ return;
2500
+ }
2501
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up external wallet event listeners", {
2502
+ walletId: this.selectedWalletId
2503
+ });
2504
+ if (walletInfo.providers?.ethereum) {
2505
+ const handleExternalEthereumAccountsChanged = async (accounts) => {
2506
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum accounts changed event received", {
2507
+ walletId: this.selectedWalletId,
2508
+ accounts
2509
+ });
2510
+ const walletId = this.selectedWalletId;
2511
+ const state = this.getWalletState(walletId);
2512
+ const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
2513
+ if (accounts && accounts.length > 0) {
2514
+ const ethAddresses = accounts.map((address) => ({ addressType: import_client3.AddressType.ethereum, address }));
2515
+ const newAddresses = [...otherAddresses, ...ethAddresses];
2516
+ this.setWalletState(walletId, {
2517
+ connected: true,
2518
+ addresses: newAddresses
2519
+ });
2520
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Updated Ethereum addresses after account change", {
2521
+ walletId,
2522
+ oldCount: 0,
2523
+ // We filtered them out
2524
+ newCount: accounts.length,
2525
+ addresses: newAddresses.filter((addr) => addr.addressType === import_client3.AddressType.ethereum)
2526
+ });
2527
+ const authUserId = await this.getAuthUserId("External wallet Ethereum accounts changed event");
2528
+ this.emit("connect", {
2529
+ addresses: newAddresses,
2530
+ source: "external-wallet-account-change",
2531
+ authUserId
2532
+ });
2533
+ } else {
2534
+ this.setWalletState(walletId, {
2535
+ connected: otherAddresses.length > 0,
2536
+ addresses: otherAddresses
2537
+ });
2538
+ this.emit("disconnect", {
2539
+ source: "external-wallet-account-change"
2540
+ });
2541
+ }
2542
+ };
2543
+ if (typeof walletInfo.providers.ethereum.on === "function") {
2544
+ walletInfo.providers.ethereum.on("accountsChanged", handleExternalEthereumAccountsChanged);
2545
+ this.browserInjectedCleanupFunctions.push(() => {
2546
+ if (typeof walletInfo.providers?.ethereum?.off === "function") {
2547
+ walletInfo.providers.ethereum.off("accountsChanged", handleExternalEthereumAccountsChanged);
2548
+ }
2549
+ });
902
2550
  }
903
- };
2551
+ }
2552
+ if (walletInfo.providers?.solana) {
2553
+ const handleExternalSolanaAccountChanged = async (publicKey) => {
2554
+ debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana account changed event received", {
2555
+ walletId: this.selectedWalletId,
2556
+ publicKey
2557
+ });
2558
+ const walletId = this.selectedWalletId;
2559
+ const state = this.getWalletState(walletId);
2560
+ const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.solana);
2561
+ if (publicKey) {
2562
+ const newAddresses = [...otherAddresses, { addressType: import_client3.AddressType.solana, address: publicKey }];
2563
+ this.setWalletState(walletId, {
2564
+ connected: true,
2565
+ addresses: newAddresses
2566
+ });
2567
+ const authUserId = await this.getAuthUserId("External wallet Solana account changed event");
2568
+ this.emit("connect", {
2569
+ addresses: newAddresses,
2570
+ source: "external-wallet-account-change",
2571
+ authUserId
2572
+ });
2573
+ } else {
2574
+ this.setWalletState(walletId, {
2575
+ connected: otherAddresses.length > 0,
2576
+ addresses: otherAddresses
2577
+ });
2578
+ this.emit("disconnect", {
2579
+ source: "external-wallet-account-change"
2580
+ });
2581
+ }
2582
+ };
2583
+ if (typeof walletInfo.providers.solana.on === "function") {
2584
+ walletInfo.providers.solana.on("accountChanged", handleExternalSolanaAccountChanged);
2585
+ this.browserInjectedCleanupFunctions.push(() => {
2586
+ if (typeof walletInfo.providers?.solana?.off === "function") {
2587
+ walletInfo.providers.solana.off("accountChanged", handleExternalSolanaAccountChanged);
2588
+ }
2589
+ });
2590
+ }
2591
+ }
2592
+ if (this.selectedWalletId) {
2593
+ this.externalWalletEventListenersSetup.add(this.selectedWalletId);
2594
+ }
904
2595
  }
905
2596
  };
906
2597
 
@@ -1215,7 +2906,7 @@ var BrowserAuthProvider = class {
1215
2906
  // OAuth session management - defaults to allow refresh unless explicitly clearing after logout
1216
2907
  clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
1217
2908
  allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
1218
- sdk_version: "1.0.0-beta.22",
2909
+ sdk_version: "1.0.0-beta.24",
1219
2910
  sdk_type: "browser",
1220
2911
  platform: detectBrowser().name
1221
2912
  });
@@ -1336,10 +3027,10 @@ var BrowserAuthProvider = class {
1336
3027
  };
1337
3028
 
1338
3029
  // src/providers/embedded/adapters/phantom-app.ts
1339
- var import_browser_injected_sdk3 = require("@phantom/browser-injected-sdk");
3030
+ var import_browser_injected_sdk4 = require("@phantom/browser-injected-sdk");
1340
3031
 
1341
3032
  // src/isPhantomLoginAvailable.ts
1342
- var import_browser_injected_sdk2 = require("@phantom/browser-injected-sdk");
3033
+ var import_browser_injected_sdk3 = require("@phantom/browser-injected-sdk");
1343
3034
  async function isPhantomLoginAvailable(timeoutMs = 3e3) {
1344
3035
  const extensionInstalled = await waitForExtension(timeoutMs);
1345
3036
  if (!extensionInstalled) {
@@ -1365,7 +3056,7 @@ async function waitForExtension(timeoutMs) {
1365
3056
  const checkInterval = 100;
1366
3057
  const checkForExtension = () => {
1367
3058
  try {
1368
- if ((0, import_browser_injected_sdk2.isPhantomExtensionInstalled)()) {
3059
+ if ((0, import_browser_injected_sdk3.isPhantomExtensionInstalled)()) {
1369
3060
  resolve(true);
1370
3061
  return;
1371
3062
  }
@@ -1388,7 +3079,7 @@ var BrowserPhantomAppProvider = class {
1388
3079
  * Check if the Phantom extension is installed in the browser
1389
3080
  */
1390
3081
  isAvailable() {
1391
- return (0, import_browser_injected_sdk3.isPhantomExtensionInstalled)();
3082
+ return (0, import_browser_injected_sdk4.isPhantomExtensionInstalled)();
1392
3083
  }
1393
3084
  /**
1394
3085
  * Authenticate using the Phantom browser extension
@@ -1479,15 +3170,19 @@ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvi
1479
3170
  // Full user agent for more detailed info
1480
3171
  [import_constants2.ANALYTICS_HEADERS.APP_ID]: config.appId,
1481
3172
  [import_constants2.ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
1482
- [import_constants2.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.22"
3173
+ [import_constants2.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.24"
1483
3174
  // Replaced at build time
1484
3175
  }
1485
3176
  };
1486
3177
  debug.log(DebugCategory.EMBEDDED_PROVIDER, "Detected platform", { platformName });
1487
3178
  const logger = new BrowserLogger();
1488
3179
  super(config, platform, logger);
3180
+ this.addressTypes = config.addressTypes;
1489
3181
  debug.info(DebugCategory.EMBEDDED_PROVIDER, "Browser EmbeddedProvider initialized");
1490
3182
  }
3183
+ getEnabledAddressTypes() {
3184
+ return this.addressTypes;
3185
+ }
1491
3186
  };
1492
3187
 
1493
3188
  // src/ProviderManager.ts
@@ -1893,37 +3588,14 @@ var ProviderManager = class {
1893
3588
  }
1894
3589
  };
1895
3590
 
1896
- // src/waitForPhantomExtension.ts
1897
- var import_browser_injected_sdk4 = require("@phantom/browser-injected-sdk");
1898
- async function waitForPhantomExtension(timeoutMs = 3e3) {
1899
- return new Promise((resolve) => {
1900
- const startTime = Date.now();
1901
- const checkInterval = 100;
1902
- const checkForExtension = () => {
1903
- try {
1904
- if ((0, import_browser_injected_sdk4.isPhantomExtensionInstalled)()) {
1905
- resolve(true);
1906
- return;
1907
- }
1908
- } catch (error) {
1909
- }
1910
- const elapsed = Date.now() - startTime;
1911
- if (elapsed >= timeoutMs) {
1912
- resolve(false);
1913
- return;
1914
- }
1915
- setTimeout(checkForExtension, checkInterval);
1916
- };
1917
- checkForExtension();
1918
- });
1919
- }
1920
-
1921
3591
  // src/BrowserSDK.ts
1922
3592
  var import_embedded_provider_core3 = require("@phantom/embedded-provider-core");
1923
3593
  var import_constants4 = require("@phantom/constants");
1924
3594
  var BROWSER_SDK_PROVIDER_TYPES = [...import_embedded_provider_core3.EMBEDDED_PROVIDER_AUTH_TYPES, "injected"];
1925
3595
  var BrowserSDK = class {
1926
3596
  constructor(config) {
3597
+ this.walletRegistry = getWalletRegistry();
3598
+ this.isLoading = true;
1927
3599
  debug.info(DebugCategory.BROWSER_SDK, "Initializing BrowserSDK", {
1928
3600
  providers: config.providers,
1929
3601
  embeddedWalletType: config.embeddedWalletType,
@@ -1959,7 +3631,14 @@ var BrowserSDK = class {
1959
3631
  `Invalid embeddedWalletType: ${config.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
1960
3632
  );
1961
3633
  }
3634
+ this.config = config;
1962
3635
  this.providerManager = new ProviderManager(config);
3636
+ void this.discoverWallets();
3637
+ }
3638
+ discoverWallets() {
3639
+ return this.walletRegistry.discover(this.config.addressTypes).finally(() => {
3640
+ this.isLoading = false;
3641
+ });
1963
3642
  }
1964
3643
  // ===== CHAIN API =====
1965
3644
  /**
@@ -2032,13 +3711,20 @@ var BrowserSDK = class {
2032
3711
  getCurrentProviderInfo() {
2033
3712
  return this.providerManager.getCurrentProviderInfo();
2034
3713
  }
2035
- // ===== UTILITY METHODS =====
2036
3714
  /**
2037
- * Check if Phantom extension is installed
3715
+ * Get enabled address types for the current provider
3716
+ * - For embedded provider: returns config.addressTypes
3717
+ * - For Phantom injected: returns config.addressTypes
3718
+ * - For discovered wallets: returns the wallet's addressTypes from registry
2038
3719
  */
2039
- static async isPhantomInstalled(timeoutMs) {
2040
- return waitForPhantomExtension(timeoutMs);
3720
+ getEnabledAddressTypes() {
3721
+ const currentProvider = this.providerManager.getCurrentProvider();
3722
+ if (!currentProvider) {
3723
+ return [];
3724
+ }
3725
+ return currentProvider.getEnabledAddressTypes();
2041
3726
  }
3727
+ // ===== UTILITY METHODS =====
2042
3728
  /**
2043
3729
  * Add event listener for provider events (connect, connect_start, connect_error, disconnect, error)
2044
3730
  * Works with both embedded and injected providers
@@ -2071,40 +3757,21 @@ var BrowserSDK = class {
2071
3757
  debug.log(DebugCategory.BROWSER_SDK, "Auto-connect failed for all providers");
2072
3758
  }
2073
3759
  }
2074
- /**
2075
- * Debug configuration methods
2076
- * These allow dynamic debug configuration without SDK reinstantiation
2077
- */
2078
- /**
2079
- * Enable debug logging
2080
- */
2081
3760
  enableDebug() {
2082
3761
  debug.enable();
2083
3762
  debug.info(DebugCategory.BROWSER_SDK, "Debug logging enabled");
2084
3763
  }
2085
- /**
2086
- * Disable debug logging
2087
- */
2088
3764
  disableDebug() {
2089
3765
  debug.disable();
2090
3766
  }
2091
- /**
2092
- * Set debug level
2093
- */
2094
3767
  setDebugLevel(level) {
2095
3768
  debug.setLevel(level);
2096
3769
  debug.info(DebugCategory.BROWSER_SDK, "Debug level updated", { level });
2097
3770
  }
2098
- /**
2099
- * Set debug callback function
2100
- */
2101
3771
  setDebugCallback(callback) {
2102
3772
  debug.setCallback(callback);
2103
3773
  debug.info(DebugCategory.BROWSER_SDK, "Debug callback updated");
2104
3774
  }
2105
- /**
2106
- * Configure debug settings all at once
2107
- */
2108
3775
  configureDebug(config) {
2109
3776
  if (config.enabled !== void 0) {
2110
3777
  if (config.enabled) {
@@ -2210,6 +3877,22 @@ var BrowserSDK = class {
2210
3877
  throw error;
2211
3878
  }
2212
3879
  }
3880
+ getDiscoveredWallets() {
3881
+ debug.log(DebugCategory.BROWSER_SDK, "Getting discovered wallets");
3882
+ try {
3883
+ const allWallets = this.walletRegistry.getByAddressTypes(this.config.addressTypes);
3884
+ debug.log(DebugCategory.BROWSER_SDK, "Retrieved discovered wallets", {
3885
+ count: allWallets.length,
3886
+ walletIds: allWallets.map((w) => w.id)
3887
+ });
3888
+ return allWallets;
3889
+ } catch (error) {
3890
+ debug.error(DebugCategory.BROWSER_SDK, "Failed to get discovered wallets", {
3891
+ error: error.message
3892
+ });
3893
+ return [];
3894
+ }
3895
+ }
2213
3896
  };
2214
3897
 
2215
3898
  // src/utils/deeplink.ts
@@ -2222,6 +3905,31 @@ function getDeeplinkToPhantom(ref) {
2222
3905
  return `https://phantom.app/ul/browse/${currentUrl}${refParam}`;
2223
3906
  }
2224
3907
 
3908
+ // src/waitForPhantomExtension.ts
3909
+ var import_browser_injected_sdk5 = require("@phantom/browser-injected-sdk");
3910
+ async function waitForPhantomExtension(timeoutMs = 3e3) {
3911
+ return new Promise((resolve) => {
3912
+ const startTime = Date.now();
3913
+ const checkInterval = 100;
3914
+ const checkForExtension = () => {
3915
+ try {
3916
+ if ((0, import_browser_injected_sdk5.isPhantomExtensionInstalled)()) {
3917
+ resolve(true);
3918
+ return;
3919
+ }
3920
+ } catch (error) {
3921
+ }
3922
+ const elapsed = Date.now() - startTime;
3923
+ if (elapsed >= timeoutMs) {
3924
+ resolve(false);
3925
+ return;
3926
+ }
3927
+ setTimeout(checkForExtension, checkInterval);
3928
+ };
3929
+ checkForExtension();
3930
+ });
3931
+ }
3932
+
2225
3933
  // src/index.ts
2226
3934
  var import_constants5 = require("@phantom/constants");
2227
- var import_client5 = require("@phantom/client");
3935
+ var import_client4 = require("@phantom/client");