@phantom/browser-sdk 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -15
- package/dist/index.d.ts +3 -3
- package/dist/index.js +574 -703
- package/dist/index.mjs +554 -683
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -30,11 +30,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
-
AddressType: () =>
|
|
33
|
+
AddressType: () => import_client5.AddressType,
|
|
34
34
|
BrowserSDK: () => BrowserSDK,
|
|
35
35
|
DebugCategory: () => DebugCategory,
|
|
36
36
|
DebugLevel: () => DebugLevel,
|
|
37
|
-
NetworkId: () =>
|
|
37
|
+
NetworkId: () => import_constants7.NetworkId,
|
|
38
|
+
PHANTOM_ICON: () => import_constants8.PHANTOM_ICON,
|
|
38
39
|
debug: () => debug,
|
|
39
40
|
detectBrowser: () => detectBrowser,
|
|
40
41
|
getBrowserDisplayName: () => getBrowserDisplayName,
|
|
@@ -51,7 +52,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
51
52
|
var import_client = require("@phantom/client");
|
|
52
53
|
|
|
53
54
|
// src/providers/injected/index.ts
|
|
54
|
-
var
|
|
55
|
+
var import_client4 = require("@phantom/client");
|
|
55
56
|
|
|
56
57
|
// src/debug.ts
|
|
57
58
|
var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
|
|
@@ -128,12 +129,27 @@ var DebugCategory = {
|
|
|
128
129
|
};
|
|
129
130
|
|
|
130
131
|
// src/wallets/discovery.ts
|
|
131
|
-
var
|
|
132
|
+
var import_constants = require("@phantom/constants");
|
|
133
|
+
var import_client3 = require("@phantom/client");
|
|
132
134
|
var import_browser_injected_sdk = require("@phantom/browser-injected-sdk");
|
|
133
135
|
var import_browser_injected_sdk2 = require("@phantom/browser-injected-sdk");
|
|
134
136
|
var import_solana = require("@phantom/browser-injected-sdk/solana");
|
|
135
137
|
var import_ethereum = require("@phantom/browser-injected-sdk/ethereum");
|
|
136
138
|
var import_auto_confirm = require("@phantom/browser-injected-sdk/auto-confirm");
|
|
139
|
+
|
|
140
|
+
// src/wallets/custom-wallets.ts
|
|
141
|
+
var import_client2 = require("@phantom/client");
|
|
142
|
+
var CUSTOM_WALLET_CONFIGS = [
|
|
143
|
+
{
|
|
144
|
+
id: "coinbase-wallet",
|
|
145
|
+
name: "Coinbase Wallet",
|
|
146
|
+
icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI4IDU2YzE1LjQ2NCAwIDI4LTEyLjUzNiAyOC0yOFM0My40NjQgMCAyOCAwIDAgMTIuNTM2IDAgMjhzMTIuNTM2IDI4IDI4IDI4WiIgZmlsbD0iIzFCNTNFNCIvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNyAyOGMwIDExLjU5OCA5LjQwMiAyMSAyMSAyMXMyMS05LjQwMiAyMS0yMVMzOS41OTggNyAyOCA3IDcgMTYuNDAyIDcgMjhabTE3LjIzNC02Ljc2NmEzIDMgMCAwIDAtMyAzdjcuNTMzYTMgMyAwIDAgMCAzIDNoNy41MzNhMyAzIDAgMCAwIDMtM3YtNy41MzNhMyAzIDAgMCAwLTMtM2gtNy41MzNaIiBmaWxsPSIjZmZmIi8+PC9zdmc+",
|
|
147
|
+
windowProperty: "coinbaseSolana",
|
|
148
|
+
addressTypes: [import_client2.AddressType.solana]
|
|
149
|
+
}
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
// src/wallets/discovery.ts
|
|
137
153
|
function generateWalletIdFromEIP6963(info) {
|
|
138
154
|
if (info.rdns) {
|
|
139
155
|
return info.rdns.split(".").reverse().join("-");
|
|
@@ -166,7 +182,7 @@ function processEIP6963Providers(providers) {
|
|
|
166
182
|
id: walletId,
|
|
167
183
|
name: info.name,
|
|
168
184
|
icon: info.icon,
|
|
169
|
-
addressTypes: [
|
|
185
|
+
addressTypes: [import_client3.AddressType.ethereum],
|
|
170
186
|
providers: {
|
|
171
187
|
// EIP-6963 provider implements EIP-1193 interface (IEthereumChain)
|
|
172
188
|
ethereum: provider
|
|
@@ -346,7 +362,7 @@ async function discoverSolanaWallets() {
|
|
|
346
362
|
return chainLower.startsWith("solana:") || chainLower === "solana";
|
|
347
363
|
}) || wallet.features && typeof wallet.features === "object" && Object.keys(wallet.features).some((featureKey) => {
|
|
348
364
|
const featureLower = featureKey.toLowerCase();
|
|
349
|
-
return featureLower.
|
|
365
|
+
return featureLower.startsWith("solana:");
|
|
350
366
|
});
|
|
351
367
|
if (!supportsSolana) {
|
|
352
368
|
const featureKeys = wallet.features ? Object.keys(wallet.features) : [];
|
|
@@ -376,7 +392,7 @@ async function discoverSolanaWallets() {
|
|
|
376
392
|
id: walletId,
|
|
377
393
|
name: wallet.name,
|
|
378
394
|
icon: wallet.icon,
|
|
379
|
-
addressTypes: [
|
|
395
|
+
addressTypes: [import_client3.AddressType.solana],
|
|
380
396
|
providers: {
|
|
381
397
|
// Cast to ISolanaChain - Wallet Standard wallets have compatible methods
|
|
382
398
|
// The InjectedWalletSolanaChain wrapper will handle the actual method calls
|
|
@@ -397,6 +413,51 @@ async function discoverSolanaWallets() {
|
|
|
397
413
|
walletNames: wallets.map((w) => w.name)
|
|
398
414
|
};
|
|
399
415
|
debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard Solana discovery completed", finalLogData);
|
|
416
|
+
const customWallets = discoverCustomSolanaWallets();
|
|
417
|
+
wallets.push(...customWallets);
|
|
418
|
+
return wallets;
|
|
419
|
+
}
|
|
420
|
+
function discoverCustomSolanaWallets() {
|
|
421
|
+
const wallets = [];
|
|
422
|
+
if (typeof window === "undefined") {
|
|
423
|
+
debug.log(DebugCategory.BROWSER_SDK, "Custom wallet discovery skipped (not in browser environment)");
|
|
424
|
+
return wallets;
|
|
425
|
+
}
|
|
426
|
+
debug.log(DebugCategory.BROWSER_SDK, "Starting custom Solana wallet discovery", {
|
|
427
|
+
configCount: CUSTOM_WALLET_CONFIGS.length
|
|
428
|
+
});
|
|
429
|
+
for (const config of CUSTOM_WALLET_CONFIGS) {
|
|
430
|
+
if (!config.addressTypes.includes(import_client3.AddressType.solana)) {
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
const provider = window[config.windowProperty];
|
|
434
|
+
if (!provider) {
|
|
435
|
+
debug.log(DebugCategory.BROWSER_SDK, "Custom wallet not found", {
|
|
436
|
+
walletId: config.id,
|
|
437
|
+
windowProperty: config.windowProperty
|
|
438
|
+
});
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
debug.log(DebugCategory.BROWSER_SDK, "Discovered custom Solana wallet", {
|
|
442
|
+
walletId: config.id,
|
|
443
|
+
walletName: config.name,
|
|
444
|
+
windowProperty: config.windowProperty
|
|
445
|
+
});
|
|
446
|
+
wallets.push({
|
|
447
|
+
id: config.id,
|
|
448
|
+
name: config.name,
|
|
449
|
+
icon: config.icon,
|
|
450
|
+
addressTypes: config.addressTypes,
|
|
451
|
+
providers: {
|
|
452
|
+
solana: provider
|
|
453
|
+
},
|
|
454
|
+
discovery: "custom"
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
debug.log(DebugCategory.BROWSER_SDK, "Custom Solana wallet discovery completed", {
|
|
458
|
+
discoveredCount: wallets.length,
|
|
459
|
+
walletIds: wallets.map((w) => w.id)
|
|
460
|
+
});
|
|
400
461
|
return wallets;
|
|
401
462
|
}
|
|
402
463
|
function discoverPhantomWallet(addressTypes) {
|
|
@@ -407,10 +468,10 @@ function discoverPhantomWallet(addressTypes) {
|
|
|
407
468
|
return null;
|
|
408
469
|
}
|
|
409
470
|
const plugins = [(0, import_browser_injected_sdk2.createExtensionPlugin)()];
|
|
410
|
-
if (addressTypes.includes(
|
|
471
|
+
if (addressTypes.includes(import_client3.AddressType.solana)) {
|
|
411
472
|
plugins.push((0, import_solana.createSolanaPlugin)());
|
|
412
473
|
}
|
|
413
|
-
if (addressTypes.includes(
|
|
474
|
+
if (addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
414
475
|
plugins.push((0, import_ethereum.createEthereumPlugin)());
|
|
415
476
|
}
|
|
416
477
|
plugins.push((0, import_auto_confirm.createAutoConfirmPlugin)());
|
|
@@ -418,12 +479,11 @@ function discoverPhantomWallet(addressTypes) {
|
|
|
418
479
|
return {
|
|
419
480
|
id: "phantom",
|
|
420
481
|
name: "Phantom",
|
|
421
|
-
icon:
|
|
422
|
-
// Icon will be rendered from icons package in UI components
|
|
482
|
+
icon: import_constants.PHANTOM_ICON,
|
|
423
483
|
addressTypes,
|
|
424
484
|
providers: {
|
|
425
|
-
solana: addressTypes.includes(
|
|
426
|
-
ethereum: addressTypes.includes(
|
|
485
|
+
solana: addressTypes.includes(import_client3.AddressType.solana) ? phantomInstance.solana : void 0,
|
|
486
|
+
ethereum: addressTypes.includes(import_client3.AddressType.ethereum) ? phantomInstance.ethereum : void 0
|
|
427
487
|
},
|
|
428
488
|
isPhantom: true,
|
|
429
489
|
phantomInstance,
|
|
@@ -488,67 +548,65 @@ async function discoverWallets(addressTypes) {
|
|
|
488
548
|
return Array.from(walletMap.values());
|
|
489
549
|
}
|
|
490
550
|
|
|
551
|
+
// src/wallets/registry.ts
|
|
552
|
+
var import_constants2 = require("@phantom/constants");
|
|
553
|
+
|
|
491
554
|
// src/providers/injected/chains/InjectedWalletSolanaChain.ts
|
|
492
555
|
var import_eventemitter3 = require("eventemitter3");
|
|
493
556
|
var import_buffer = require("buffer");
|
|
494
557
|
var InjectedWalletSolanaChain = class {
|
|
495
558
|
constructor(provider, walletId, walletName) {
|
|
559
|
+
// Expose eventEmitter for testing - allows tests to trigger events directly
|
|
496
560
|
this.eventEmitter = new import_eventemitter3.EventEmitter();
|
|
497
|
-
this._connected = false;
|
|
498
561
|
this._publicKey = null;
|
|
499
562
|
this.provider = provider;
|
|
500
563
|
this.walletId = walletId;
|
|
501
564
|
this.walletName = walletName;
|
|
502
565
|
this.setupEventListeners();
|
|
503
566
|
}
|
|
504
|
-
get connected() {
|
|
505
|
-
return this._connected;
|
|
506
|
-
}
|
|
507
567
|
get publicKey() {
|
|
508
568
|
return this._publicKey;
|
|
509
569
|
}
|
|
570
|
+
get isConnected() {
|
|
571
|
+
return this.provider.isConnected || !!this._publicKey;
|
|
572
|
+
}
|
|
510
573
|
async connect(options) {
|
|
511
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect", {
|
|
512
|
-
walletId: this.walletId,
|
|
513
|
-
walletName: this.walletName,
|
|
514
|
-
onlyIfTrusted: options?.onlyIfTrusted
|
|
515
|
-
});
|
|
516
574
|
try {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
|
|
575
|
+
await this.provider.connect(options);
|
|
576
|
+
const isConnected = this.provider.isConnected;
|
|
577
|
+
if (!isConnected || this.provider.publicKey === null) {
|
|
578
|
+
debug.error(DebugCategory.INJECTED_PROVIDER, "Provider not connected after connect() call", {
|
|
522
579
|
walletId: this.walletId,
|
|
523
580
|
walletName: this.walletName,
|
|
524
|
-
|
|
581
|
+
providerConnected: isConnected,
|
|
582
|
+
providerPublicKey: this.provider.publicKey
|
|
525
583
|
});
|
|
526
|
-
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
584
|
+
throw new Error("Provider not connected after connect() call");
|
|
585
|
+
}
|
|
586
|
+
let publicKey;
|
|
587
|
+
const providerPublicKey = this.provider.publicKey;
|
|
588
|
+
if (typeof providerPublicKey === "string") {
|
|
589
|
+
publicKey = providerPublicKey;
|
|
590
|
+
} else if (providerPublicKey !== null && providerPublicKey !== void 0 && typeof providerPublicKey.toString === "function") {
|
|
591
|
+
publicKey = providerPublicKey.toString();
|
|
592
|
+
} else {
|
|
593
|
+
debug.error(DebugCategory.INJECTED_PROVIDER, "Invalid publicKey format in provider state", {
|
|
532
594
|
walletId: this.walletId,
|
|
533
595
|
walletName: this.walletName,
|
|
534
|
-
|
|
596
|
+
publicKeyType: typeof providerPublicKey
|
|
535
597
|
});
|
|
536
|
-
|
|
537
|
-
}
|
|
538
|
-
if (Array.isArray(result) && result.length > 0) {
|
|
539
|
-
const firstAccount = result[0];
|
|
540
|
-
if (typeof firstAccount === "object" && firstAccount !== null && "address" in firstAccount) {
|
|
541
|
-
this._connected = true;
|
|
542
|
-
this._publicKey = firstAccount.address;
|
|
543
|
-
debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
|
|
544
|
-
walletId: this.walletId,
|
|
545
|
-
walletName: this.walletName,
|
|
546
|
-
publicKey: firstAccount.address
|
|
547
|
-
});
|
|
548
|
-
return { publicKey: firstAccount.address };
|
|
549
|
-
}
|
|
598
|
+
throw new Error("Invalid publicKey format in provider state");
|
|
550
599
|
}
|
|
551
|
-
|
|
600
|
+
if (!publicKey || publicKey.length === 0) {
|
|
601
|
+
throw new Error("Empty publicKey from provider");
|
|
602
|
+
}
|
|
603
|
+
this._publicKey = publicKey;
|
|
604
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
|
|
605
|
+
walletId: this.walletId,
|
|
606
|
+
walletName: this.walletName,
|
|
607
|
+
publicKey
|
|
608
|
+
});
|
|
609
|
+
return { publicKey };
|
|
552
610
|
} catch (error) {
|
|
553
611
|
debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect failed", {
|
|
554
612
|
walletId: this.walletId,
|
|
@@ -565,7 +623,6 @@ var InjectedWalletSolanaChain = class {
|
|
|
565
623
|
});
|
|
566
624
|
try {
|
|
567
625
|
await this.provider.disconnect();
|
|
568
|
-
this._connected = false;
|
|
569
626
|
this._publicKey = null;
|
|
570
627
|
debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana disconnected", {
|
|
571
628
|
walletId: this.walletId,
|
|
@@ -701,27 +758,19 @@ var InjectedWalletSolanaChain = class {
|
|
|
701
758
|
switchNetwork(_network) {
|
|
702
759
|
return Promise.resolve();
|
|
703
760
|
}
|
|
704
|
-
getPublicKey() {
|
|
705
|
-
return Promise.resolve(this._publicKey);
|
|
706
|
-
}
|
|
707
|
-
isConnected() {
|
|
708
|
-
return this._connected;
|
|
709
|
-
}
|
|
710
761
|
setupEventListeners() {
|
|
711
762
|
if (typeof this.provider.on === "function") {
|
|
712
763
|
this.provider.on("connect", (publicKey) => {
|
|
713
|
-
this._connected = true;
|
|
714
764
|
this._publicKey = publicKey;
|
|
715
765
|
this.eventEmitter.emit("connect", publicKey);
|
|
716
766
|
});
|
|
717
767
|
this.provider.on("disconnect", () => {
|
|
718
|
-
this._connected = false;
|
|
719
768
|
this._publicKey = null;
|
|
720
769
|
this.eventEmitter.emit("disconnect");
|
|
721
770
|
});
|
|
722
771
|
this.provider.on("accountChanged", (publicKey) => {
|
|
723
|
-
this._publicKey = publicKey;
|
|
724
|
-
this.eventEmitter.emit("accountChanged",
|
|
772
|
+
this._publicKey = publicKey ? publicKey : null;
|
|
773
|
+
this.eventEmitter.emit("accountChanged", this._publicKey);
|
|
725
774
|
});
|
|
726
775
|
}
|
|
727
776
|
}
|
|
@@ -734,26 +783,29 @@ var InjectedWalletSolanaChain = class {
|
|
|
734
783
|
};
|
|
735
784
|
|
|
736
785
|
// src/providers/injected/chains/WalletStandardSolanaAdapter.ts
|
|
786
|
+
var import_eventemitter32 = require("eventemitter3");
|
|
737
787
|
var import_parsers = require("@phantom/parsers");
|
|
788
|
+
var import_buffer2 = require("buffer");
|
|
738
789
|
var import_bs58 = __toESM(require("bs58"));
|
|
739
790
|
var WalletStandardSolanaAdapter = class {
|
|
740
791
|
constructor(wallet, walletId, walletName) {
|
|
741
|
-
this.
|
|
792
|
+
this.eventEmitter = new import_eventemitter32.EventEmitter();
|
|
742
793
|
this._publicKey = null;
|
|
743
794
|
this.wallet = wallet;
|
|
744
795
|
this.walletId = walletId;
|
|
745
796
|
this.walletName = walletName;
|
|
746
|
-
|
|
747
|
-
get connected() {
|
|
748
|
-
return this._connected;
|
|
797
|
+
this.setupEventListeners();
|
|
749
798
|
}
|
|
750
799
|
get publicKey() {
|
|
751
800
|
return this._publicKey;
|
|
752
801
|
}
|
|
802
|
+
get isConnected() {
|
|
803
|
+
return this._publicKey !== null;
|
|
804
|
+
}
|
|
753
805
|
async connect(_options) {
|
|
754
806
|
try {
|
|
755
|
-
const connectFeature = this.wallet.features
|
|
756
|
-
if (!connectFeature
|
|
807
|
+
const connectFeature = this.wallet.features["standard:connect"];
|
|
808
|
+
if (!connectFeature) {
|
|
757
809
|
throw new Error("Wallet Standard connect feature not available");
|
|
758
810
|
}
|
|
759
811
|
const connectResult = await connectFeature.connect();
|
|
@@ -774,14 +826,13 @@ var WalletStandardSolanaAdapter = class {
|
|
|
774
826
|
if (typeof firstAccount === "string") {
|
|
775
827
|
address = firstAccount;
|
|
776
828
|
} else if (typeof firstAccount === "object" && firstAccount !== null) {
|
|
777
|
-
address = firstAccount.address || firstAccount.publicKey?.toString() || (firstAccount.publicKey instanceof Uint8Array ? Buffer.from(firstAccount.publicKey).toString("hex") : void 0);
|
|
829
|
+
address = firstAccount.address || firstAccount.publicKey?.toString() || (firstAccount.publicKey instanceof Uint8Array ? import_buffer2.Buffer.from(firstAccount.publicKey).toString("hex") : void 0);
|
|
778
830
|
}
|
|
779
831
|
if (!address) {
|
|
780
832
|
throw new Error(
|
|
781
833
|
`Could not extract address from account. Account structure: ${JSON.stringify(firstAccount, null, 2)}`
|
|
782
834
|
);
|
|
783
835
|
}
|
|
784
|
-
this._connected = true;
|
|
785
836
|
this._publicKey = address;
|
|
786
837
|
return { publicKey: address };
|
|
787
838
|
} catch (error) {
|
|
@@ -795,11 +846,10 @@ var WalletStandardSolanaAdapter = class {
|
|
|
795
846
|
}
|
|
796
847
|
async disconnect() {
|
|
797
848
|
try {
|
|
798
|
-
const disconnectFeature = this.wallet.features
|
|
799
|
-
if (disconnectFeature
|
|
849
|
+
const disconnectFeature = this.wallet.features["standard:disconnect"];
|
|
850
|
+
if (disconnectFeature) {
|
|
800
851
|
await disconnectFeature.disconnect();
|
|
801
852
|
}
|
|
802
|
-
this._connected = false;
|
|
803
853
|
this._publicKey = null;
|
|
804
854
|
} catch (error) {
|
|
805
855
|
debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana disconnect failed", {
|
|
@@ -812,14 +862,14 @@ var WalletStandardSolanaAdapter = class {
|
|
|
812
862
|
}
|
|
813
863
|
async signMessage(message) {
|
|
814
864
|
try {
|
|
815
|
-
const signMessageFeature = this.wallet.features
|
|
816
|
-
if (!signMessageFeature
|
|
865
|
+
const signMessageFeature = this.wallet.features["solana:signMessage"];
|
|
866
|
+
if (!signMessageFeature) {
|
|
817
867
|
throw new Error("Wallet Standard signMessage feature not available");
|
|
818
868
|
}
|
|
819
869
|
const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
820
870
|
const result = await signMessageFeature.signMessage({
|
|
821
871
|
message: messageBytes,
|
|
822
|
-
account: this.wallet.accounts
|
|
872
|
+
account: this.wallet.accounts[0]
|
|
823
873
|
});
|
|
824
874
|
if (!Array.isArray(result) || result.length === 0) {
|
|
825
875
|
throw new Error(`Expected array result from signMessage, got: ${typeof result}`);
|
|
@@ -832,7 +882,7 @@ var WalletStandardSolanaAdapter = class {
|
|
|
832
882
|
if (signature.length === 0) {
|
|
833
883
|
throw new Error(`Signature is empty`);
|
|
834
884
|
}
|
|
835
|
-
const publicKey = signedMessageResult.account?.address || this.wallet.accounts
|
|
885
|
+
const publicKey = signedMessageResult.account?.address || this.wallet.accounts[0]?.address || this._publicKey || "";
|
|
836
886
|
return { signature, publicKey };
|
|
837
887
|
} catch (error) {
|
|
838
888
|
debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signMessage failed", {
|
|
@@ -845,8 +895,8 @@ var WalletStandardSolanaAdapter = class {
|
|
|
845
895
|
}
|
|
846
896
|
async signTransaction(transaction) {
|
|
847
897
|
try {
|
|
848
|
-
const signTransactionFeature = this.wallet.features
|
|
849
|
-
if (!signTransactionFeature
|
|
898
|
+
const signTransactionFeature = this.wallet.features["solana:signTransaction"];
|
|
899
|
+
if (!signTransactionFeature) {
|
|
850
900
|
throw new Error("Wallet Standard signTransaction feature not available");
|
|
851
901
|
}
|
|
852
902
|
if (!this.wallet.accounts || this.wallet.accounts.length === 0) {
|
|
@@ -865,7 +915,8 @@ var WalletStandardSolanaAdapter = class {
|
|
|
865
915
|
transactionData = firstItem.signedTransaction || firstItem.transaction;
|
|
866
916
|
}
|
|
867
917
|
} else if (results && typeof results === "object" && !Array.isArray(results)) {
|
|
868
|
-
|
|
918
|
+
const resultObj = results;
|
|
919
|
+
transactionData = resultObj.transaction || resultObj.signedTransaction;
|
|
869
920
|
}
|
|
870
921
|
if (!transactionData) {
|
|
871
922
|
throw new Error("No transaction data found in Wallet Standard result");
|
|
@@ -887,8 +938,8 @@ var WalletStandardSolanaAdapter = class {
|
|
|
887
938
|
}
|
|
888
939
|
async signAndSendTransaction(transaction) {
|
|
889
940
|
try {
|
|
890
|
-
const signAndSendTransactionFeature = this.wallet.features
|
|
891
|
-
if (!signAndSendTransactionFeature
|
|
941
|
+
const signAndSendTransactionFeature = this.wallet.features["solana:signAndSendTransaction"];
|
|
942
|
+
if (!signAndSendTransactionFeature) {
|
|
892
943
|
throw new Error("Wallet Standard signAndSendTransaction feature not available");
|
|
893
944
|
}
|
|
894
945
|
if (!this.wallet.accounts || this.wallet.accounts.length === 0) {
|
|
@@ -959,40 +1010,87 @@ var WalletStandardSolanaAdapter = class {
|
|
|
959
1010
|
throw error;
|
|
960
1011
|
}
|
|
961
1012
|
}
|
|
962
|
-
async switchNetwork(
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1013
|
+
async switchNetwork(_network) {
|
|
1014
|
+
return Promise.resolve();
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Set up event listeners for Wallet Standard events
|
|
1018
|
+
* Maps Wallet Standard "change" events to "accountChanged" events
|
|
1019
|
+
*
|
|
1020
|
+
* Note: Wallet Standard only has a "change" event. There are no "connect" or "disconnect" events.
|
|
1021
|
+
* Connection/disconnection is indicated by the presence or absence of accounts in the change event.
|
|
1022
|
+
*/
|
|
1023
|
+
setupEventListeners() {
|
|
1024
|
+
const eventsFeature = this.wallet.features["standard:events"];
|
|
1025
|
+
if (!eventsFeature) {
|
|
1026
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Wallet Standard events feature not available", {
|
|
971
1027
|
walletId: this.walletId,
|
|
972
|
-
walletName: this.walletName
|
|
973
|
-
network,
|
|
974
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1028
|
+
walletName: this.walletName
|
|
975
1029
|
});
|
|
976
|
-
|
|
1030
|
+
return;
|
|
977
1031
|
}
|
|
1032
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Wallet Standard event listeners", {
|
|
1033
|
+
walletId: this.walletId,
|
|
1034
|
+
walletName: this.walletName
|
|
1035
|
+
});
|
|
1036
|
+
eventsFeature.on("change", (properties) => {
|
|
1037
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Wallet Standard change event received", {
|
|
1038
|
+
walletId: this.walletId,
|
|
1039
|
+
walletName: this.walletName,
|
|
1040
|
+
hasAccounts: !!properties.accounts,
|
|
1041
|
+
accountCount: properties.accounts?.length || 0
|
|
1042
|
+
});
|
|
1043
|
+
if (properties.accounts !== void 0) {
|
|
1044
|
+
if (properties.accounts.length > 0) {
|
|
1045
|
+
const firstAccount = properties.accounts[0];
|
|
1046
|
+
const address = this.extractAccountAddress(firstAccount);
|
|
1047
|
+
if (address) {
|
|
1048
|
+
this._publicKey = address;
|
|
1049
|
+
this.eventEmitter.emit("accountChanged", address);
|
|
1050
|
+
this.eventEmitter.emit("connect", address);
|
|
1051
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Emitted accountChanged and connect events", {
|
|
1052
|
+
walletId: this.walletId,
|
|
1053
|
+
walletName: this.walletName,
|
|
1054
|
+
address
|
|
1055
|
+
});
|
|
1056
|
+
} else {
|
|
1057
|
+
this._publicKey = null;
|
|
1058
|
+
this.eventEmitter.emit("accountChanged", null);
|
|
1059
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Emitted accountChanged event (null - invalid account)", {
|
|
1060
|
+
walletId: this.walletId,
|
|
1061
|
+
walletName: this.walletName
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
} else {
|
|
1065
|
+
this._publicKey = null;
|
|
1066
|
+
this.eventEmitter.emit("accountChanged", null);
|
|
1067
|
+
this.eventEmitter.emit("disconnect");
|
|
1068
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Emitted accountChanged and disconnect events", {
|
|
1069
|
+
walletId: this.walletId,
|
|
1070
|
+
walletName: this.walletName
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
});
|
|
978
1075
|
}
|
|
979
|
-
|
|
980
|
-
return
|
|
981
|
-
}
|
|
982
|
-
isConnected() {
|
|
983
|
-
return this._connected;
|
|
1076
|
+
extractAccountAddress(account) {
|
|
1077
|
+
return account.address;
|
|
984
1078
|
}
|
|
985
|
-
on(
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1079
|
+
on(event, listener) {
|
|
1080
|
+
this.eventEmitter.on(event, listener);
|
|
1081
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Added event listener", {
|
|
1082
|
+
walletId: this.walletId,
|
|
1083
|
+
walletName: this.walletName,
|
|
1084
|
+
event
|
|
1085
|
+
});
|
|
990
1086
|
}
|
|
991
|
-
off(
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1087
|
+
off(event, listener) {
|
|
1088
|
+
this.eventEmitter.off(event, listener);
|
|
1089
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Removed event listener", {
|
|
1090
|
+
walletId: this.walletId,
|
|
1091
|
+
walletName: this.walletName,
|
|
1092
|
+
event
|
|
1093
|
+
});
|
|
996
1094
|
}
|
|
997
1095
|
/**
|
|
998
1096
|
* Serialize a transaction to Uint8Array for Wallet Standard API
|
|
@@ -1036,10 +1134,11 @@ var WalletStandardSolanaAdapter = class {
|
|
|
1036
1134
|
};
|
|
1037
1135
|
|
|
1038
1136
|
// src/providers/injected/chains/InjectedWalletEthereumChain.ts
|
|
1039
|
-
var
|
|
1137
|
+
var import_eventemitter33 = require("eventemitter3");
|
|
1040
1138
|
var InjectedWalletEthereumChain = class {
|
|
1041
1139
|
constructor(provider, walletId, walletName) {
|
|
1042
|
-
|
|
1140
|
+
// Expose eventEmitter for testing - allows tests to trigger events directly
|
|
1141
|
+
this.eventEmitter = new import_eventemitter33.EventEmitter();
|
|
1043
1142
|
this._connected = false;
|
|
1044
1143
|
this._chainId = "0x1";
|
|
1045
1144
|
this._accounts = [];
|
|
@@ -1048,9 +1147,6 @@ var InjectedWalletEthereumChain = class {
|
|
|
1048
1147
|
this.walletName = walletName;
|
|
1049
1148
|
this.setupEventListeners();
|
|
1050
1149
|
}
|
|
1051
|
-
get connected() {
|
|
1052
|
-
return this._connected;
|
|
1053
|
-
}
|
|
1054
1150
|
get chainId() {
|
|
1055
1151
|
return this._chainId;
|
|
1056
1152
|
}
|
|
@@ -1180,7 +1276,8 @@ var InjectedWalletEthereumChain = class {
|
|
|
1180
1276
|
address
|
|
1181
1277
|
});
|
|
1182
1278
|
try {
|
|
1183
|
-
const
|
|
1279
|
+
const providerAny = this.provider;
|
|
1280
|
+
const providerConnected = (typeof providerAny.isConnected === "function" ? providerAny.isConnected() : false) || (typeof providerAny.connected === "boolean" ? providerAny.connected : false);
|
|
1184
1281
|
if (!this._connected || this._accounts.length === 0 || !providerConnected) {
|
|
1185
1282
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Not connected, attempting to connect before signing", {
|
|
1186
1283
|
walletId: this.walletId,
|
|
@@ -1413,6 +1510,7 @@ var InjectedWalletEthereumChain = class {
|
|
|
1413
1510
|
});
|
|
1414
1511
|
this.provider.on("accountsChanged", (accounts) => {
|
|
1415
1512
|
this._accounts = accounts;
|
|
1513
|
+
this._connected = accounts.length > 0;
|
|
1416
1514
|
this.eventEmitter.emit("accountsChanged", accounts);
|
|
1417
1515
|
});
|
|
1418
1516
|
this.provider.on("chainChanged", (chainId) => {
|
|
@@ -1429,218 +1527,13 @@ var InjectedWalletEthereumChain = class {
|
|
|
1429
1527
|
}
|
|
1430
1528
|
};
|
|
1431
1529
|
|
|
1432
|
-
// src/providers/injected/chains/SolanaChain.ts
|
|
1433
|
-
var import_eventemitter33 = require("eventemitter3");
|
|
1434
|
-
var import_buffer2 = require("buffer");
|
|
1435
|
-
var PhantomSolanaChain = class {
|
|
1436
|
-
constructor(phantom) {
|
|
1437
|
-
this._publicKey = null;
|
|
1438
|
-
this.eventEmitter = new import_eventemitter33.EventEmitter();
|
|
1439
|
-
this.phantom = phantom;
|
|
1440
|
-
this.setupEventListeners();
|
|
1441
|
-
}
|
|
1442
|
-
// Wallet adapter compliant properties
|
|
1443
|
-
get connected() {
|
|
1444
|
-
return this._publicKey !== null;
|
|
1445
|
-
}
|
|
1446
|
-
get publicKey() {
|
|
1447
|
-
return this._publicKey;
|
|
1448
|
-
}
|
|
1449
|
-
// Connection methods
|
|
1450
|
-
async connect(options) {
|
|
1451
|
-
const result = await this.phantom.solana.connect(options);
|
|
1452
|
-
if (!result) {
|
|
1453
|
-
throw new Error("Failed to connect to Solana wallet");
|
|
1454
|
-
}
|
|
1455
|
-
const publicKey = typeof result === "string" ? result : "";
|
|
1456
|
-
this._publicKey = publicKey;
|
|
1457
|
-
return { publicKey };
|
|
1458
|
-
}
|
|
1459
|
-
async disconnect() {
|
|
1460
|
-
await this.phantom.solana.disconnect();
|
|
1461
|
-
this._publicKey = null;
|
|
1462
|
-
}
|
|
1463
|
-
// Standard wallet adapter methods
|
|
1464
|
-
async signMessage(message) {
|
|
1465
|
-
const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
1466
|
-
const result = await this.phantom.solana.signMessage(messageBytes);
|
|
1467
|
-
return {
|
|
1468
|
-
signature: result.signature instanceof Uint8Array ? result.signature : new Uint8Array(import_buffer2.Buffer.from(result.signature, "base64")),
|
|
1469
|
-
publicKey: this._publicKey || ""
|
|
1470
|
-
};
|
|
1471
|
-
}
|
|
1472
|
-
async signTransaction(transaction) {
|
|
1473
|
-
if (!this.connected) {
|
|
1474
|
-
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
1475
|
-
}
|
|
1476
|
-
try {
|
|
1477
|
-
const result = await this.phantom.solana.signTransaction(transaction);
|
|
1478
|
-
return result;
|
|
1479
|
-
} catch (error) {
|
|
1480
|
-
return Promise.reject(error);
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
async signAndSendTransaction(transaction) {
|
|
1484
|
-
const result = await this.phantom.solana.signAndSendTransaction(transaction);
|
|
1485
|
-
return { signature: result.signature };
|
|
1486
|
-
}
|
|
1487
|
-
async signAllTransactions(transactions) {
|
|
1488
|
-
if (!this.connected) {
|
|
1489
|
-
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
1490
|
-
}
|
|
1491
|
-
try {
|
|
1492
|
-
const result = await this.phantom.solana.signAllTransactions(transactions);
|
|
1493
|
-
return result;
|
|
1494
|
-
} catch (error) {
|
|
1495
|
-
return Promise.reject(error);
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
async signAndSendAllTransactions(transactions) {
|
|
1499
|
-
if (!this.connected) {
|
|
1500
|
-
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
1501
|
-
}
|
|
1502
|
-
try {
|
|
1503
|
-
const result = await this.phantom.solana.signAndSendAllTransactions(transactions);
|
|
1504
|
-
return { signatures: result.signatures };
|
|
1505
|
-
} catch (error) {
|
|
1506
|
-
return Promise.reject(error);
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
switchNetwork(_network) {
|
|
1510
|
-
return Promise.resolve();
|
|
1511
|
-
}
|
|
1512
|
-
// Legacy methods
|
|
1513
|
-
getPublicKey() {
|
|
1514
|
-
return Promise.resolve(this._publicKey);
|
|
1515
|
-
}
|
|
1516
|
-
isConnected() {
|
|
1517
|
-
return this.connected;
|
|
1518
|
-
}
|
|
1519
|
-
setupEventListeners() {
|
|
1520
|
-
this.phantom.solana.addEventListener("connect", (publicKey) => {
|
|
1521
|
-
this._publicKey = publicKey;
|
|
1522
|
-
this.eventEmitter.emit("connect", publicKey);
|
|
1523
|
-
});
|
|
1524
|
-
this.phantom.solana.addEventListener("disconnect", () => {
|
|
1525
|
-
this._publicKey = null;
|
|
1526
|
-
this.eventEmitter.emit("disconnect");
|
|
1527
|
-
});
|
|
1528
|
-
this.phantom.solana.addEventListener("accountChanged", (publicKey) => {
|
|
1529
|
-
this._publicKey = publicKey;
|
|
1530
|
-
this.eventEmitter.emit("accountChanged", publicKey);
|
|
1531
|
-
});
|
|
1532
|
-
}
|
|
1533
|
-
// Event methods for interface compliance
|
|
1534
|
-
on(event, listener) {
|
|
1535
|
-
this.eventEmitter.on(event, listener);
|
|
1536
|
-
}
|
|
1537
|
-
off(event, listener) {
|
|
1538
|
-
this.eventEmitter.off(event, listener);
|
|
1539
|
-
}
|
|
1540
|
-
};
|
|
1541
|
-
|
|
1542
|
-
// src/providers/injected/chains/EthereumChain.ts
|
|
1543
|
-
var import_eventemitter34 = require("eventemitter3");
|
|
1544
|
-
var PhantomEthereumChain = class {
|
|
1545
|
-
constructor(phantom) {
|
|
1546
|
-
this._chainId = "0x1";
|
|
1547
|
-
this._accounts = [];
|
|
1548
|
-
this.eventEmitter = new import_eventemitter34.EventEmitter();
|
|
1549
|
-
this.phantom = phantom;
|
|
1550
|
-
this.setupEventListeners();
|
|
1551
|
-
}
|
|
1552
|
-
// EIP-1193 compliant properties
|
|
1553
|
-
get connected() {
|
|
1554
|
-
return this._accounts.length > 0;
|
|
1555
|
-
}
|
|
1556
|
-
get chainId() {
|
|
1557
|
-
return this._chainId;
|
|
1558
|
-
}
|
|
1559
|
-
get accounts() {
|
|
1560
|
-
return this._accounts;
|
|
1561
|
-
}
|
|
1562
|
-
// EIP-1193 core method with eth_signTransaction support
|
|
1563
|
-
async request(args) {
|
|
1564
|
-
if (args.method === "eth_signTransaction") {
|
|
1565
|
-
const [transaction] = args.params;
|
|
1566
|
-
const result = await this.signTransaction(transaction);
|
|
1567
|
-
return result;
|
|
1568
|
-
}
|
|
1569
|
-
const phantomProvider = await this.phantom.ethereum.getProvider();
|
|
1570
|
-
return await phantomProvider.request(args);
|
|
1571
|
-
}
|
|
1572
|
-
// Connection methods
|
|
1573
|
-
async connect() {
|
|
1574
|
-
const accounts = await this.phantom.ethereum.getAccounts();
|
|
1575
|
-
this._accounts = accounts;
|
|
1576
|
-
return accounts;
|
|
1577
|
-
}
|
|
1578
|
-
async disconnect() {
|
|
1579
|
-
await this.phantom.ethereum.disconnect();
|
|
1580
|
-
this._accounts = [];
|
|
1581
|
-
}
|
|
1582
|
-
// Standard compliant methods (return raw values, not wrapped objects)
|
|
1583
|
-
async signPersonalMessage(message, address) {
|
|
1584
|
-
return await this.phantom.ethereum.signPersonalMessage(message, address);
|
|
1585
|
-
}
|
|
1586
|
-
async signTypedData(typedData, address) {
|
|
1587
|
-
return await this.phantom.ethereum.signTypedData(typedData, address);
|
|
1588
|
-
}
|
|
1589
|
-
async signTransaction(transaction) {
|
|
1590
|
-
return await this.phantom.ethereum.signTransaction(transaction);
|
|
1591
|
-
}
|
|
1592
|
-
async sendTransaction(transaction) {
|
|
1593
|
-
return await this.phantom.ethereum.sendTransaction(transaction);
|
|
1594
|
-
}
|
|
1595
|
-
async switchChain(chainId) {
|
|
1596
|
-
const hexChainId = typeof chainId === "string" ? chainId.toLowerCase().startsWith("0x") ? chainId : `0x${parseInt(chainId, 10).toString(16)}` : `0x${chainId.toString(16)}`;
|
|
1597
|
-
await this.phantom.ethereum.switchChain(hexChainId);
|
|
1598
|
-
this._chainId = hexChainId;
|
|
1599
|
-
this.eventEmitter.emit("chainChanged", this._chainId);
|
|
1600
|
-
}
|
|
1601
|
-
async getChainId() {
|
|
1602
|
-
const chainId = await this.phantom.ethereum.getChainId();
|
|
1603
|
-
return parseInt(chainId, 16);
|
|
1604
|
-
}
|
|
1605
|
-
async getAccounts() {
|
|
1606
|
-
return await this.phantom.ethereum.getAccounts();
|
|
1607
|
-
}
|
|
1608
|
-
isConnected() {
|
|
1609
|
-
return this.connected;
|
|
1610
|
-
}
|
|
1611
|
-
setupEventListeners() {
|
|
1612
|
-
this.phantom.ethereum.addEventListener("connect", (accounts) => {
|
|
1613
|
-
this._accounts = accounts;
|
|
1614
|
-
this.eventEmitter.emit("connect", { chainId: this._chainId });
|
|
1615
|
-
this.eventEmitter.emit("accountsChanged", accounts);
|
|
1616
|
-
});
|
|
1617
|
-
this.phantom.ethereum.addEventListener("disconnect", () => {
|
|
1618
|
-
this._accounts = [];
|
|
1619
|
-
this.eventEmitter.emit("disconnect", { code: 4900, message: "Provider disconnected" });
|
|
1620
|
-
this.eventEmitter.emit("accountsChanged", []);
|
|
1621
|
-
});
|
|
1622
|
-
this.phantom.ethereum.addEventListener("accountsChanged", (accounts) => {
|
|
1623
|
-
this._accounts = accounts;
|
|
1624
|
-
this.eventEmitter.emit("accountsChanged", accounts);
|
|
1625
|
-
});
|
|
1626
|
-
this.phantom.ethereum.addEventListener("chainChanged", (chainId) => {
|
|
1627
|
-
this._chainId = chainId;
|
|
1628
|
-
this.eventEmitter.emit("chainChanged", chainId);
|
|
1629
|
-
});
|
|
1630
|
-
}
|
|
1631
|
-
// Event methods for interface compliance
|
|
1632
|
-
on(event, listener) {
|
|
1633
|
-
this.eventEmitter.on(event, listener);
|
|
1634
|
-
}
|
|
1635
|
-
off(event, listener) {
|
|
1636
|
-
this.eventEmitter.off(event, listener);
|
|
1637
|
-
}
|
|
1638
|
-
};
|
|
1639
|
-
|
|
1640
1530
|
// src/wallets/registry.ts
|
|
1641
1531
|
function isPhantomWallet(wallet) {
|
|
1642
1532
|
return wallet !== void 0 && wallet.id === "phantom" && "isPhantom" in wallet && wallet.isPhantom === true;
|
|
1643
1533
|
}
|
|
1534
|
+
function isWalletStandardWallet(provider) {
|
|
1535
|
+
return provider !== null && typeof provider === "object" && "features" in provider && typeof provider.features === "object";
|
|
1536
|
+
}
|
|
1644
1537
|
var InjectedWalletRegistry = class {
|
|
1645
1538
|
constructor() {
|
|
1646
1539
|
this.wallets = /* @__PURE__ */ new Map();
|
|
@@ -1649,8 +1542,7 @@ var InjectedWalletRegistry = class {
|
|
|
1649
1542
|
register(info) {
|
|
1650
1543
|
const wrappedProviders = {};
|
|
1651
1544
|
if (info.providers?.solana) {
|
|
1652
|
-
|
|
1653
|
-
if (isWalletStandard) {
|
|
1545
|
+
if (isWalletStandardWallet(info.providers.solana)) {
|
|
1654
1546
|
wrappedProviders.solana = new WalletStandardSolanaAdapter(info.providers.solana, info.id, info.name);
|
|
1655
1547
|
debug.log(DebugCategory.BROWSER_SDK, "Wrapped Wallet Standard Solana wallet with adapter", {
|
|
1656
1548
|
walletId: info.id,
|
|
@@ -1680,26 +1572,26 @@ var InjectedWalletRegistry = class {
|
|
|
1680
1572
|
/**
|
|
1681
1573
|
* Register Phantom wallet with its instance
|
|
1682
1574
|
* This creates wrapped providers and stores the Phantom instance for auto-confirm access
|
|
1575
|
+
* Uses unified InjectedWallet chains for both Phantom and external wallets
|
|
1683
1576
|
*/
|
|
1684
1577
|
registerPhantom(phantomInstance, addressTypes) {
|
|
1685
1578
|
const wrappedProviders = {};
|
|
1686
1579
|
if (addressTypes.includes(import_client.AddressType.solana) && phantomInstance.solana) {
|
|
1687
|
-
wrappedProviders.solana = new
|
|
1688
|
-
debug.log(DebugCategory.BROWSER_SDK, "Created
|
|
1580
|
+
wrappedProviders.solana = new InjectedWalletSolanaChain(phantomInstance.solana, "phantom", "Phantom");
|
|
1581
|
+
debug.log(DebugCategory.BROWSER_SDK, "Created InjectedWalletSolanaChain wrapper for Phantom", {
|
|
1689
1582
|
walletId: "phantom"
|
|
1690
1583
|
});
|
|
1691
1584
|
}
|
|
1692
1585
|
if (addressTypes.includes(import_client.AddressType.ethereum) && phantomInstance.ethereum) {
|
|
1693
|
-
wrappedProviders.ethereum = new
|
|
1694
|
-
debug.log(DebugCategory.BROWSER_SDK, "Created
|
|
1586
|
+
wrappedProviders.ethereum = new InjectedWalletEthereumChain(phantomInstance.ethereum, "phantom", "Phantom");
|
|
1587
|
+
debug.log(DebugCategory.BROWSER_SDK, "Created InjectedWalletEthereumChain wrapper for Phantom", {
|
|
1695
1588
|
walletId: "phantom"
|
|
1696
1589
|
});
|
|
1697
1590
|
}
|
|
1698
1591
|
const phantomWallet = {
|
|
1699
1592
|
id: "phantom",
|
|
1700
1593
|
name: "Phantom",
|
|
1701
|
-
icon:
|
|
1702
|
-
// Icon will be rendered from icons package in UI components
|
|
1594
|
+
icon: import_constants2.PHANTOM_ICON,
|
|
1703
1595
|
addressTypes,
|
|
1704
1596
|
providers: wrappedProviders,
|
|
1705
1597
|
isPhantom: true,
|
|
@@ -1776,15 +1668,16 @@ var WAS_CONNECTED_KEY = "phantom-injected-was-connected";
|
|
|
1776
1668
|
var WAS_CONNECTED_VALUE = "true";
|
|
1777
1669
|
var LAST_WALLET_ID_KEY = "phantom-injected-last-wallet-id";
|
|
1778
1670
|
var InjectedProvider = class {
|
|
1779
|
-
//
|
|
1671
|
+
// Store cleanups per walletId
|
|
1780
1672
|
constructor(config) {
|
|
1781
1673
|
this.selectedWalletId = null;
|
|
1782
1674
|
this.walletStates = /* @__PURE__ */ new Map();
|
|
1783
1675
|
// Event management
|
|
1784
1676
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
1785
|
-
this.browserInjectedCleanupFunctions = [];
|
|
1786
1677
|
this.eventsInitialized = false;
|
|
1787
|
-
this.
|
|
1678
|
+
this.eventListenersSetup = /* @__PURE__ */ new Set();
|
|
1679
|
+
// Track walletId that have listeners set up
|
|
1680
|
+
this.eventListenerCleanups = /* @__PURE__ */ new Map();
|
|
1788
1681
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Initializing InjectedProvider", { config });
|
|
1789
1682
|
this.addressTypes = config.addressTypes;
|
|
1790
1683
|
this.walletRegistry = getWalletRegistry();
|
|
@@ -1815,9 +1708,12 @@ var InjectedProvider = class {
|
|
|
1815
1708
|
});
|
|
1816
1709
|
}
|
|
1817
1710
|
}
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1711
|
+
/**
|
|
1712
|
+
* Helper method to get a chain provider with consistent error handling
|
|
1713
|
+
*/
|
|
1714
|
+
getChainProvider(addressType, providerKey, chainName) {
|
|
1715
|
+
if (!this.addressTypes.includes(addressType)) {
|
|
1716
|
+
throw new Error(`${chainName} not enabled for this provider`);
|
|
1821
1717
|
}
|
|
1822
1718
|
const walletId = this.selectedWalletId || "phantom";
|
|
1823
1719
|
const walletInfo = this.walletRegistry.getById(walletId);
|
|
@@ -1832,46 +1728,29 @@ var InjectedProvider = class {
|
|
|
1832
1728
|
`Wallet "${walletId}" not found. Please ensure wallet discovery has completed. Make sure you call sdk.discoverWallets() and await it before accessing chain properties.`
|
|
1833
1729
|
);
|
|
1834
1730
|
}
|
|
1835
|
-
|
|
1731
|
+
const provider = walletInfo.providers?.[providerKey];
|
|
1732
|
+
if (!provider) {
|
|
1836
1733
|
throw new Error(
|
|
1837
|
-
`Selected wallet "${walletInfo.name}" does not support
|
|
1734
|
+
`Selected wallet "${walletInfo.name}" does not support ${chainName}. This wallet only supports: ${walletInfo.addressTypes.join(", ")}. Make sure your SDK config includes ${chainName} in addressTypes.`
|
|
1838
1735
|
);
|
|
1839
1736
|
}
|
|
1840
|
-
return
|
|
1737
|
+
return provider;
|
|
1738
|
+
}
|
|
1739
|
+
get solana() {
|
|
1740
|
+
return this.getChainProvider(import_client4.AddressType.solana, "solana", "Solana");
|
|
1841
1741
|
}
|
|
1842
1742
|
/**
|
|
1843
1743
|
* Access to Ethereum chain operations
|
|
1844
1744
|
*/
|
|
1845
1745
|
get ethereum() {
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
throw new Error(
|
|
1855
|
-
`Wallet "${walletId}" not found. Wallet discovery is still in progress. Please wait for sdk.discoverWallets() to complete before accessing chain properties.`
|
|
1856
|
-
);
|
|
1857
|
-
}
|
|
1858
|
-
throw new Error(
|
|
1859
|
-
`Wallet "${walletId}" not found. Please ensure wallet discovery has completed. Make sure you call sdk.discoverWallets() and await it before accessing chain properties.`
|
|
1860
|
-
);
|
|
1861
|
-
}
|
|
1862
|
-
if (!walletInfo.providers?.ethereum) {
|
|
1863
|
-
throw new Error(
|
|
1864
|
-
`Selected wallet "${walletInfo.name}" does not support Ethereum. This wallet only supports: ${walletInfo.addressTypes.join(", ")}. Make sure your SDK config includes Ethereum in addressTypes.`
|
|
1865
|
-
);
|
|
1866
|
-
}
|
|
1867
|
-
return walletInfo.providers.ethereum;
|
|
1868
|
-
}
|
|
1869
|
-
validateAndSelectWallet(requestedWalletId) {
|
|
1870
|
-
if (!this.walletRegistry.has(requestedWalletId)) {
|
|
1871
|
-
debug.error(DebugCategory.INJECTED_PROVIDER, "Unknown injected wallet id requested", {
|
|
1872
|
-
walletId: requestedWalletId
|
|
1873
|
-
});
|
|
1874
|
-
throw new Error(`Unknown injected wallet id: ${requestedWalletId}`);
|
|
1746
|
+
return this.getChainProvider(import_client4.AddressType.ethereum, "ethereum", "Ethereum");
|
|
1747
|
+
}
|
|
1748
|
+
validateAndSelectWallet(requestedWalletId) {
|
|
1749
|
+
if (!this.walletRegistry.has(requestedWalletId)) {
|
|
1750
|
+
debug.error(DebugCategory.INJECTED_PROVIDER, "Unknown injected wallet id requested", {
|
|
1751
|
+
walletId: requestedWalletId
|
|
1752
|
+
});
|
|
1753
|
+
throw new Error(`Unknown injected wallet id: ${requestedWalletId}`);
|
|
1875
1754
|
}
|
|
1876
1755
|
const walletInfo = this.walletRegistry.getById(requestedWalletId);
|
|
1877
1756
|
if (!walletInfo || !walletInfo.providers) {
|
|
@@ -1902,16 +1781,10 @@ var InjectedProvider = class {
|
|
|
1902
1781
|
options
|
|
1903
1782
|
});
|
|
1904
1783
|
if (!options?.skipEventListeners) {
|
|
1905
|
-
this.
|
|
1906
|
-
if (this.selectedWalletId === "phantom" && isPhantomWallet(walletInfo)) {
|
|
1907
|
-
this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
|
|
1908
|
-
this.browserInjectedCleanupFunctions = [];
|
|
1909
|
-
this.setupBrowserInjectedEvents();
|
|
1910
|
-
this.eventsInitialized = true;
|
|
1911
|
-
}
|
|
1784
|
+
this.setupEventListeners(walletInfo);
|
|
1912
1785
|
}
|
|
1913
1786
|
const connectedAddresses = [];
|
|
1914
|
-
if (this.addressTypes.includes(
|
|
1787
|
+
if (this.addressTypes.includes(import_client4.AddressType.solana) && walletInfo.providers?.solana) {
|
|
1915
1788
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection", {
|
|
1916
1789
|
walletId: this.selectedWalletId,
|
|
1917
1790
|
walletName: walletInfo.name,
|
|
@@ -1923,7 +1796,7 @@ var InjectedProvider = class {
|
|
|
1923
1796
|
);
|
|
1924
1797
|
const address = result.publicKey;
|
|
1925
1798
|
connectedAddresses.push({
|
|
1926
|
-
addressType:
|
|
1799
|
+
addressType: import_client4.AddressType.solana,
|
|
1927
1800
|
address
|
|
1928
1801
|
});
|
|
1929
1802
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", {
|
|
@@ -1944,7 +1817,7 @@ var InjectedProvider = class {
|
|
|
1944
1817
|
throw err;
|
|
1945
1818
|
}
|
|
1946
1819
|
}
|
|
1947
|
-
if (this.addressTypes.includes(
|
|
1820
|
+
if (this.addressTypes.includes(import_client4.AddressType.ethereum) && walletInfo.providers?.ethereum) {
|
|
1948
1821
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Ethereum connection", {
|
|
1949
1822
|
walletId: this.selectedWalletId,
|
|
1950
1823
|
walletName: walletInfo.name,
|
|
@@ -1960,7 +1833,7 @@ var InjectedProvider = class {
|
|
|
1960
1833
|
if (accounts.length > 0) {
|
|
1961
1834
|
connectedAddresses.push(
|
|
1962
1835
|
...accounts.map((address) => ({
|
|
1963
|
-
addressType:
|
|
1836
|
+
addressType: import_client4.AddressType.ethereum,
|
|
1964
1837
|
address
|
|
1965
1838
|
}))
|
|
1966
1839
|
);
|
|
@@ -2040,7 +1913,8 @@ var InjectedProvider = class {
|
|
|
2040
1913
|
this.emit("connect", {
|
|
2041
1914
|
addresses: connectedAddresses,
|
|
2042
1915
|
source: "manual-connect",
|
|
2043
|
-
authUserId
|
|
1916
|
+
authUserId,
|
|
1917
|
+
walletId
|
|
2044
1918
|
});
|
|
2045
1919
|
return result;
|
|
2046
1920
|
}
|
|
@@ -2052,12 +1926,13 @@ var InjectedProvider = class {
|
|
|
2052
1926
|
if (authOptions.provider !== "injected") {
|
|
2053
1927
|
throw new Error(`Invalid provider for injected connection: ${authOptions.provider}. Must be "injected"`);
|
|
2054
1928
|
}
|
|
1929
|
+
const requestedWalletId = authOptions.walletId || "phantom";
|
|
2055
1930
|
this.emit("connect_start", {
|
|
2056
1931
|
source: "manual-connect",
|
|
2057
|
-
providerType: "injected"
|
|
1932
|
+
providerType: "injected",
|
|
1933
|
+
walletId: requestedWalletId
|
|
2058
1934
|
});
|
|
2059
1935
|
try {
|
|
2060
|
-
const requestedWalletId = authOptions.walletId || "phantom";
|
|
2061
1936
|
const walletInfo = this.validateAndSelectWallet(requestedWalletId);
|
|
2062
1937
|
const connectedAddresses = await this.connectToWallet(walletInfo);
|
|
2063
1938
|
return await this.finalizeConnection(connectedAddresses, "injected", this.selectedWalletId || void 0);
|
|
@@ -2073,7 +1948,7 @@ var InjectedProvider = class {
|
|
|
2073
1948
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
|
|
2074
1949
|
const walletInfo = this.walletRegistry.getById(this.selectedWalletId || "phantom");
|
|
2075
1950
|
if (walletInfo?.providers) {
|
|
2076
|
-
if (this.addressTypes.includes(
|
|
1951
|
+
if (this.addressTypes.includes(import_client4.AddressType.solana) && walletInfo.providers.solana) {
|
|
2077
1952
|
try {
|
|
2078
1953
|
await walletInfo.providers.solana.disconnect();
|
|
2079
1954
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
|
|
@@ -2081,7 +1956,7 @@ var InjectedProvider = class {
|
|
|
2081
1956
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
|
|
2082
1957
|
}
|
|
2083
1958
|
}
|
|
2084
|
-
if (this.addressTypes.includes(
|
|
1959
|
+
if (this.addressTypes.includes(import_client4.AddressType.ethereum) && walletInfo.providers.ethereum) {
|
|
2085
1960
|
try {
|
|
2086
1961
|
await walletInfo.providers.ethereum.disconnect();
|
|
2087
1962
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected successfully");
|
|
@@ -2090,10 +1965,14 @@ var InjectedProvider = class {
|
|
|
2090
1965
|
}
|
|
2091
1966
|
}
|
|
2092
1967
|
}
|
|
2093
|
-
this.
|
|
2094
|
-
|
|
1968
|
+
const walletId = this.selectedWalletId || "phantom";
|
|
1969
|
+
const cleanups = this.eventListenerCleanups.get(walletId);
|
|
1970
|
+
if (cleanups) {
|
|
1971
|
+
cleanups.forEach((cleanup) => cleanup());
|
|
1972
|
+
this.eventListenerCleanups.delete(walletId);
|
|
1973
|
+
}
|
|
1974
|
+
this.eventListenersSetup.delete(walletId);
|
|
2095
1975
|
if (this.selectedWalletId) {
|
|
2096
|
-
this.externalWalletEventListenersSetup.delete(this.selectedWalletId);
|
|
2097
1976
|
this.setWalletState(this.selectedWalletId, {
|
|
2098
1977
|
connected: false,
|
|
2099
1978
|
addresses: []
|
|
@@ -2162,13 +2041,7 @@ var InjectedProvider = class {
|
|
|
2162
2041
|
});
|
|
2163
2042
|
return;
|
|
2164
2043
|
}
|
|
2165
|
-
this.
|
|
2166
|
-
if (this.selectedWalletId === "phantom" && isPhantomWallet(walletInfo)) {
|
|
2167
|
-
this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
|
|
2168
|
-
this.browserInjectedCleanupFunctions = [];
|
|
2169
|
-
this.setupBrowserInjectedEvents();
|
|
2170
|
-
this.eventsInitialized = true;
|
|
2171
|
-
}
|
|
2044
|
+
this.setupEventListeners(walletInfo);
|
|
2172
2045
|
if (this.selectedWalletId) {
|
|
2173
2046
|
this.setWalletState(this.selectedWalletId, {
|
|
2174
2047
|
connected: true,
|
|
@@ -2179,7 +2052,8 @@ var InjectedProvider = class {
|
|
|
2179
2052
|
this.emit("connect", {
|
|
2180
2053
|
addresses: connectedAddresses,
|
|
2181
2054
|
source: "auto-connect",
|
|
2182
|
-
authUserId
|
|
2055
|
+
authUserId,
|
|
2056
|
+
walletId: this.selectedWalletId
|
|
2183
2057
|
});
|
|
2184
2058
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Auto-connect successful", {
|
|
2185
2059
|
addressCount: connectedAddresses.length,
|
|
@@ -2209,6 +2083,170 @@ var InjectedProvider = class {
|
|
|
2209
2083
|
setWalletState(walletId, state) {
|
|
2210
2084
|
this.walletStates.set(walletId, state);
|
|
2211
2085
|
}
|
|
2086
|
+
/**
|
|
2087
|
+
* Update wallet state with new addresses for a specific address type
|
|
2088
|
+
* Replaces all existing addresses of the given type with the new addresses
|
|
2089
|
+
* @param walletId - The wallet ID to update
|
|
2090
|
+
* @param newAddresses - Array of new addresses (strings) for the address type
|
|
2091
|
+
* @param addressType - The type of addresses being updated
|
|
2092
|
+
* @returns The updated addresses array
|
|
2093
|
+
*/
|
|
2094
|
+
updateWalletAddresses(walletId, newAddresses, addressType) {
|
|
2095
|
+
const state = this.getWalletState(walletId);
|
|
2096
|
+
const otherAddresses = state.addresses.filter((addr) => addr.addressType !== addressType);
|
|
2097
|
+
const addressesOfType = newAddresses.map((address) => ({ addressType, address }));
|
|
2098
|
+
const updatedAddresses = [...otherAddresses, ...addressesOfType];
|
|
2099
|
+
this.setWalletState(walletId, {
|
|
2100
|
+
connected: updatedAddresses.length > 0,
|
|
2101
|
+
addresses: updatedAddresses
|
|
2102
|
+
});
|
|
2103
|
+
return updatedAddresses;
|
|
2104
|
+
}
|
|
2105
|
+
/**
|
|
2106
|
+
* Helper to construct account change source string
|
|
2107
|
+
*/
|
|
2108
|
+
getAccountChangeSource(source) {
|
|
2109
|
+
return `${source}-account-change`;
|
|
2110
|
+
}
|
|
2111
|
+
/**
|
|
2112
|
+
* Create a handler for Solana connect events
|
|
2113
|
+
*/
|
|
2114
|
+
createSolanaConnectHandler(walletId, source) {
|
|
2115
|
+
return async (publicKey) => {
|
|
2116
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey, walletId });
|
|
2117
|
+
const newAddresses = this.updateWalletAddresses(walletId, [publicKey], import_client4.AddressType.solana);
|
|
2118
|
+
const authUserId = await this.getAuthUserId("Solana connect event");
|
|
2119
|
+
this.emit("connect", {
|
|
2120
|
+
addresses: newAddresses,
|
|
2121
|
+
source,
|
|
2122
|
+
authUserId,
|
|
2123
|
+
walletId: this.selectedWalletId
|
|
2124
|
+
});
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Create a handler for Solana disconnect events
|
|
2129
|
+
*/
|
|
2130
|
+
createSolanaDisconnectHandler(walletId, source) {
|
|
2131
|
+
return () => {
|
|
2132
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnect event received", { walletId });
|
|
2133
|
+
const state = this.getWalletState(walletId);
|
|
2134
|
+
const filteredAddresses = state.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.solana);
|
|
2135
|
+
this.setWalletState(walletId, {
|
|
2136
|
+
connected: filteredAddresses.length > 0,
|
|
2137
|
+
addresses: filteredAddresses
|
|
2138
|
+
});
|
|
2139
|
+
this.emit("disconnect", {
|
|
2140
|
+
source
|
|
2141
|
+
});
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2144
|
+
/**
|
|
2145
|
+
* Create a handler for Solana account change events
|
|
2146
|
+
* Can receive string | null per Wallet Standard
|
|
2147
|
+
*/
|
|
2148
|
+
createSolanaAccountChangeHandler(walletId, source) {
|
|
2149
|
+
return async (publicKey) => {
|
|
2150
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey, walletId });
|
|
2151
|
+
if (publicKey) {
|
|
2152
|
+
const newAddresses = this.updateWalletAddresses(walletId, [publicKey], import_client4.AddressType.solana);
|
|
2153
|
+
const authUserId = await this.getAuthUserId("Solana account changed event");
|
|
2154
|
+
this.emit("connect", {
|
|
2155
|
+
addresses: newAddresses,
|
|
2156
|
+
source: this.getAccountChangeSource(source),
|
|
2157
|
+
authUserId,
|
|
2158
|
+
walletId: this.selectedWalletId
|
|
2159
|
+
});
|
|
2160
|
+
} else {
|
|
2161
|
+
const state = this.getWalletState(walletId);
|
|
2162
|
+
const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.solana);
|
|
2163
|
+
this.setWalletState(walletId, {
|
|
2164
|
+
connected: otherAddresses.length > 0,
|
|
2165
|
+
addresses: otherAddresses
|
|
2166
|
+
});
|
|
2167
|
+
this.emit("disconnect", {
|
|
2168
|
+
source: this.getAccountChangeSource(source)
|
|
2169
|
+
});
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
}
|
|
2173
|
+
/**
|
|
2174
|
+
* Create a handler for Ethereum connect events
|
|
2175
|
+
* EIP-1193 connect event receives { chainId: string }, but we need to get accounts separately
|
|
2176
|
+
*/
|
|
2177
|
+
createEthereumConnectHandler(walletId, source) {
|
|
2178
|
+
return async (connectInfo) => {
|
|
2179
|
+
let accounts = [];
|
|
2180
|
+
if (Array.isArray(connectInfo)) {
|
|
2181
|
+
accounts = connectInfo;
|
|
2182
|
+
} else {
|
|
2183
|
+
try {
|
|
2184
|
+
const walletInfo = this.walletRegistry.getById(walletId);
|
|
2185
|
+
if (walletInfo?.providers?.ethereum) {
|
|
2186
|
+
accounts = await walletInfo.providers.ethereum.getAccounts();
|
|
2187
|
+
}
|
|
2188
|
+
} catch (error) {
|
|
2189
|
+
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to get accounts on connect", { error });
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts, walletId });
|
|
2193
|
+
if (accounts.length > 0) {
|
|
2194
|
+
const newAddresses = this.updateWalletAddresses(walletId, accounts, import_client4.AddressType.ethereum);
|
|
2195
|
+
const authUserId = await this.getAuthUserId("Ethereum connect event");
|
|
2196
|
+
this.emit("connect", {
|
|
2197
|
+
addresses: newAddresses,
|
|
2198
|
+
source,
|
|
2199
|
+
authUserId,
|
|
2200
|
+
walletId: this.selectedWalletId
|
|
2201
|
+
});
|
|
2202
|
+
}
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
/**
|
|
2206
|
+
* Create a handler for Ethereum disconnect events
|
|
2207
|
+
*/
|
|
2208
|
+
createEthereumDisconnectHandler(walletId, source) {
|
|
2209
|
+
return () => {
|
|
2210
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received", { walletId });
|
|
2211
|
+
const state = this.getWalletState(walletId);
|
|
2212
|
+
const filteredAddresses = state.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.ethereum);
|
|
2213
|
+
this.setWalletState(walletId, {
|
|
2214
|
+
connected: filteredAddresses.length > 0,
|
|
2215
|
+
addresses: filteredAddresses
|
|
2216
|
+
});
|
|
2217
|
+
this.emit("disconnect", {
|
|
2218
|
+
source
|
|
2219
|
+
});
|
|
2220
|
+
};
|
|
2221
|
+
}
|
|
2222
|
+
/**
|
|
2223
|
+
* Create a handler for Ethereum account change events
|
|
2224
|
+
*/
|
|
2225
|
+
createEthereumAccountChangeHandler(walletId, source) {
|
|
2226
|
+
return async (accounts) => {
|
|
2227
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts, walletId });
|
|
2228
|
+
if (accounts && accounts.length > 0) {
|
|
2229
|
+
const newAddresses = this.updateWalletAddresses(walletId, accounts, import_client4.AddressType.ethereum);
|
|
2230
|
+
const authUserId = await this.getAuthUserId("Ethereum accounts changed event");
|
|
2231
|
+
this.emit("connect", {
|
|
2232
|
+
addresses: newAddresses,
|
|
2233
|
+
source: this.getAccountChangeSource(source),
|
|
2234
|
+
authUserId,
|
|
2235
|
+
walletId: this.selectedWalletId
|
|
2236
|
+
});
|
|
2237
|
+
} else {
|
|
2238
|
+
const state = this.getWalletState(walletId);
|
|
2239
|
+
const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client4.AddressType.ethereum);
|
|
2240
|
+
this.setWalletState(walletId, {
|
|
2241
|
+
connected: otherAddresses.length > 0,
|
|
2242
|
+
addresses: otherAddresses
|
|
2243
|
+
});
|
|
2244
|
+
this.emit("disconnect", {
|
|
2245
|
+
source: this.getAccountChangeSource(source)
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
};
|
|
2249
|
+
}
|
|
2212
2250
|
getAddresses() {
|
|
2213
2251
|
const walletId = this.selectedWalletId || "phantom";
|
|
2214
2252
|
return this.getWalletState(walletId).addresses;
|
|
@@ -2302,19 +2340,22 @@ var InjectedProvider = class {
|
|
|
2302
2340
|
on(event, callback) {
|
|
2303
2341
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Adding event listener", { event });
|
|
2304
2342
|
if (!this.eventsInitialized) {
|
|
2305
|
-
this.
|
|
2306
|
-
|
|
2343
|
+
const walletId = this.selectedWalletId || "phantom";
|
|
2344
|
+
const walletInfo = this.walletRegistry.getById(walletId);
|
|
2345
|
+
if (walletInfo) {
|
|
2346
|
+
this.setupEventListeners(walletInfo);
|
|
2347
|
+
}
|
|
2307
2348
|
}
|
|
2308
2349
|
if (!this.eventListeners.has(event)) {
|
|
2309
2350
|
this.eventListeners.set(event, /* @__PURE__ */ new Set());
|
|
2310
2351
|
}
|
|
2311
|
-
this.eventListeners.get(event)
|
|
2352
|
+
this.eventListeners.get(event)?.add(callback);
|
|
2312
2353
|
}
|
|
2313
2354
|
off(event, callback) {
|
|
2314
2355
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Removing event listener", { event });
|
|
2315
2356
|
if (this.eventListeners.has(event)) {
|
|
2316
|
-
this.eventListeners.get(event)
|
|
2317
|
-
if (this.eventListeners.get(event)
|
|
2357
|
+
this.eventListeners.get(event)?.delete(callback);
|
|
2358
|
+
if (this.eventListeners.get(event)?.size === 0) {
|
|
2318
2359
|
this.eventListeners.delete(event);
|
|
2319
2360
|
}
|
|
2320
2361
|
}
|
|
@@ -2336,246 +2377,89 @@ var InjectedProvider = class {
|
|
|
2336
2377
|
});
|
|
2337
2378
|
}
|
|
2338
2379
|
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2380
|
+
/**
|
|
2381
|
+
* Set up Solana event listeners for any provider (Phantom or external)
|
|
2382
|
+
*/
|
|
2383
|
+
setupSolanaEventListeners(provider, walletId, source) {
|
|
2384
|
+
if (typeof provider.on !== "function")
|
|
2343
2385
|
return;
|
|
2344
|
-
}
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
}
|
|
2350
|
-
if (this.addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
2351
|
-
this.setupEthereumEvents(walletInfo.phantomInstance);
|
|
2352
|
-
}
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2355
|
-
setupSolanaEvents(phantom) {
|
|
2356
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners");
|
|
2357
|
-
const handleSolanaConnect = async (publicKey) => {
|
|
2358
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey });
|
|
2359
|
-
const walletId = this.selectedWalletId || "phantom";
|
|
2360
|
-
const state = this.getWalletState(walletId);
|
|
2361
|
-
const solanaAddress = { addressType: import_client3.AddressType.solana, address: publicKey };
|
|
2362
|
-
const hasSolana = state.addresses.some((addr) => addr.addressType === import_client3.AddressType.solana);
|
|
2363
|
-
const newAddresses = hasSolana ? state.addresses.map((addr) => addr.addressType === import_client3.AddressType.solana ? solanaAddress : addr) : [...state.addresses, solanaAddress];
|
|
2364
|
-
this.setWalletState(walletId, {
|
|
2365
|
-
connected: true,
|
|
2366
|
-
addresses: newAddresses
|
|
2367
|
-
});
|
|
2368
|
-
const authUserId = await this.getAuthUserId("Solana connect event");
|
|
2369
|
-
this.emit("connect", {
|
|
2370
|
-
addresses: newAddresses,
|
|
2371
|
-
source: "injected-extension",
|
|
2372
|
-
authUserId
|
|
2373
|
-
});
|
|
2386
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners", { walletId, source });
|
|
2387
|
+
const handlers = {
|
|
2388
|
+
connect: this.createSolanaConnectHandler(walletId, source),
|
|
2389
|
+
disconnect: this.createSolanaDisconnectHandler(walletId, source),
|
|
2390
|
+
accountChanged: this.createSolanaAccountChangeHandler(walletId, source)
|
|
2374
2391
|
};
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
const handleSolanaAccountChanged = async (publicKey) => {
|
|
2389
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey });
|
|
2390
|
-
const walletId = this.selectedWalletId || "phantom";
|
|
2391
|
-
const state = this.getWalletState(walletId);
|
|
2392
|
-
const solanaIndex = state.addresses.findIndex((addr) => addr.addressType === import_client3.AddressType.solana);
|
|
2393
|
-
const newAddresses = solanaIndex >= 0 ? state.addresses.map(
|
|
2394
|
-
(addr, idx) => idx === solanaIndex ? { addressType: import_client3.AddressType.solana, address: publicKey } : addr
|
|
2395
|
-
) : [...state.addresses, { addressType: import_client3.AddressType.solana, address: publicKey }];
|
|
2396
|
-
this.setWalletState(walletId, {
|
|
2397
|
-
connected: true,
|
|
2398
|
-
addresses: newAddresses
|
|
2399
|
-
});
|
|
2400
|
-
const authUserId = await this.getAuthUserId("Solana account changed event");
|
|
2401
|
-
this.emit("connect", {
|
|
2402
|
-
addresses: newAddresses,
|
|
2403
|
-
source: "injected-extension-account-change",
|
|
2404
|
-
authUserId
|
|
2405
|
-
});
|
|
2406
|
-
};
|
|
2407
|
-
const cleanupConnect = phantom.solana.addEventListener("connect", handleSolanaConnect);
|
|
2408
|
-
const cleanupDisconnect = phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
|
|
2409
|
-
const cleanupAccountChanged = phantom.solana.addEventListener("accountChanged", handleSolanaAccountChanged);
|
|
2410
|
-
this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountChanged);
|
|
2411
|
-
}
|
|
2412
|
-
setupEthereumEvents(phantom) {
|
|
2413
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners");
|
|
2414
|
-
const handleEthereumConnect = async (accounts) => {
|
|
2415
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts });
|
|
2416
|
-
const walletId = this.selectedWalletId || "phantom";
|
|
2417
|
-
const state = this.getWalletState(walletId);
|
|
2418
|
-
const ethAddresses = accounts.map((address) => ({ addressType: import_client3.AddressType.ethereum, address }));
|
|
2419
|
-
const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
|
|
2420
|
-
const newAddresses = [...otherAddresses, ...ethAddresses];
|
|
2421
|
-
this.setWalletState(walletId, {
|
|
2422
|
-
connected: true,
|
|
2423
|
-
addresses: newAddresses
|
|
2424
|
-
});
|
|
2425
|
-
const authUserId = await this.getAuthUserId("Ethereum connect event");
|
|
2426
|
-
this.emit("connect", {
|
|
2427
|
-
addresses: newAddresses,
|
|
2428
|
-
source: "injected-extension",
|
|
2429
|
-
authUserId
|
|
2430
|
-
});
|
|
2431
|
-
};
|
|
2432
|
-
const handleEthereumDisconnect = () => {
|
|
2433
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received");
|
|
2434
|
-
const walletId = this.selectedWalletId || "phantom";
|
|
2435
|
-
const state = this.getWalletState(walletId);
|
|
2436
|
-
const filteredAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
|
|
2437
|
-
this.setWalletState(walletId, {
|
|
2438
|
-
connected: filteredAddresses.length > 0,
|
|
2439
|
-
addresses: filteredAddresses
|
|
2440
|
-
});
|
|
2441
|
-
this.emit("disconnect", {
|
|
2442
|
-
source: "injected-extension"
|
|
2443
|
-
});
|
|
2444
|
-
};
|
|
2445
|
-
const handleEthereumAccountsChanged = async (accounts) => {
|
|
2446
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts });
|
|
2447
|
-
const walletId = this.selectedWalletId || "phantom";
|
|
2448
|
-
const state = this.getWalletState(walletId);
|
|
2449
|
-
const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
|
|
2450
|
-
if (accounts && accounts.length > 0) {
|
|
2451
|
-
const ethAddresses = accounts.map((address) => ({ addressType: import_client3.AddressType.ethereum, address }));
|
|
2452
|
-
const newAddresses = [...otherAddresses, ...ethAddresses];
|
|
2453
|
-
this.setWalletState(walletId, {
|
|
2454
|
-
connected: true,
|
|
2455
|
-
addresses: newAddresses
|
|
2456
|
-
});
|
|
2457
|
-
const authUserId = await this.getAuthUserId("Ethereum accounts changed event");
|
|
2458
|
-
this.emit("connect", {
|
|
2459
|
-
addresses: newAddresses,
|
|
2460
|
-
source: "injected-extension-account-change",
|
|
2461
|
-
authUserId
|
|
2462
|
-
});
|
|
2463
|
-
} else {
|
|
2464
|
-
this.setWalletState(walletId, {
|
|
2465
|
-
connected: otherAddresses.length > 0,
|
|
2466
|
-
addresses: otherAddresses
|
|
2467
|
-
});
|
|
2468
|
-
this.emit("disconnect", {
|
|
2469
|
-
source: "injected-extension-account-change"
|
|
2470
|
-
});
|
|
2471
|
-
}
|
|
2472
|
-
};
|
|
2473
|
-
const cleanupConnect = phantom.ethereum.addEventListener("connect", handleEthereumConnect);
|
|
2474
|
-
const cleanupDisconnect = phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
|
|
2475
|
-
const cleanupAccountsChanged = phantom.ethereum.addEventListener("accountsChanged", handleEthereumAccountsChanged);
|
|
2476
|
-
this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountsChanged);
|
|
2392
|
+
provider.on("connect", handlers.connect);
|
|
2393
|
+
provider.on("disconnect", handlers.disconnect);
|
|
2394
|
+
provider.on("accountChanged", handlers.accountChanged);
|
|
2395
|
+
const cleanups = [];
|
|
2396
|
+
if (typeof provider.off === "function") {
|
|
2397
|
+
cleanups.push(
|
|
2398
|
+
() => provider.off("connect", handlers.connect),
|
|
2399
|
+
() => provider.off("disconnect", handlers.disconnect),
|
|
2400
|
+
() => provider.off("accountChanged", handlers.accountChanged)
|
|
2401
|
+
);
|
|
2402
|
+
}
|
|
2403
|
+
const existingCleanups = this.eventListenerCleanups.get(walletId) || [];
|
|
2404
|
+
this.eventListenerCleanups.set(walletId, [...existingCleanups, ...cleanups]);
|
|
2477
2405
|
}
|
|
2478
|
-
|
|
2479
|
-
|
|
2406
|
+
/**
|
|
2407
|
+
* Set up Ethereum event listeners for any provider (Phantom or external)
|
|
2408
|
+
*/
|
|
2409
|
+
setupEthereumEventListeners(provider, walletId, source) {
|
|
2410
|
+
if (typeof provider.on !== "function")
|
|
2480
2411
|
return;
|
|
2412
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners", { walletId, source });
|
|
2413
|
+
const handlers = {
|
|
2414
|
+
connect: this.createEthereumConnectHandler(walletId, source),
|
|
2415
|
+
disconnect: this.createEthereumDisconnectHandler(walletId, source),
|
|
2416
|
+
accountsChanged: this.createEthereumAccountChangeHandler(walletId, source)
|
|
2417
|
+
};
|
|
2418
|
+
provider.on("connect", handlers.connect);
|
|
2419
|
+
provider.on("disconnect", handlers.disconnect);
|
|
2420
|
+
provider.on("accountsChanged", handlers.accountsChanged);
|
|
2421
|
+
const cleanups = [];
|
|
2422
|
+
if (typeof provider.off === "function") {
|
|
2423
|
+
cleanups.push(
|
|
2424
|
+
() => provider.off("connect", handlers.connect),
|
|
2425
|
+
() => provider.off("disconnect", handlers.disconnect),
|
|
2426
|
+
() => provider.off("accountsChanged", handlers.accountsChanged)
|
|
2427
|
+
);
|
|
2481
2428
|
}
|
|
2482
|
-
|
|
2429
|
+
const existingCleanups = this.eventListenerCleanups.get(walletId) || [];
|
|
2430
|
+
this.eventListenerCleanups.set(walletId, [...existingCleanups, ...cleanups]);
|
|
2431
|
+
}
|
|
2432
|
+
/**
|
|
2433
|
+
* Unified event listener setup for all wallet types (Phantom and external).
|
|
2434
|
+
* Cleans up listeners for previously selected wallets to prevent stale events
|
|
2435
|
+
* from causing walletId flicker during connections.
|
|
2436
|
+
*/
|
|
2437
|
+
setupEventListeners(walletInfo) {
|
|
2438
|
+
const walletId = this.selectedWalletId || "phantom";
|
|
2439
|
+
if (this.eventListenersSetup.has(walletId)) {
|
|
2440
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Event listeners already set up for wallet", { walletId });
|
|
2483
2441
|
return;
|
|
2484
2442
|
}
|
|
2485
|
-
|
|
2486
|
-
walletId
|
|
2487
|
-
|
|
2488
|
-
if (walletInfo.providers?.ethereum) {
|
|
2489
|
-
const handleExternalEthereumAccountsChanged = async (accounts) => {
|
|
2490
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Ethereum accounts changed event received", {
|
|
2491
|
-
walletId: this.selectedWalletId,
|
|
2492
|
-
accounts
|
|
2493
|
-
});
|
|
2494
|
-
const walletId = this.selectedWalletId;
|
|
2495
|
-
const state = this.getWalletState(walletId);
|
|
2496
|
-
const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
|
|
2497
|
-
if (accounts && accounts.length > 0) {
|
|
2498
|
-
const ethAddresses = accounts.map((address) => ({ addressType: import_client3.AddressType.ethereum, address }));
|
|
2499
|
-
const newAddresses = [...otherAddresses, ...ethAddresses];
|
|
2500
|
-
this.setWalletState(walletId, {
|
|
2501
|
-
connected: true,
|
|
2502
|
-
addresses: newAddresses
|
|
2503
|
-
});
|
|
2504
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Updated Ethereum addresses after account change", {
|
|
2505
|
-
walletId,
|
|
2506
|
-
oldCount: 0,
|
|
2507
|
-
// We filtered them out
|
|
2508
|
-
newCount: accounts.length,
|
|
2509
|
-
addresses: newAddresses.filter((addr) => addr.addressType === import_client3.AddressType.ethereum)
|
|
2510
|
-
});
|
|
2511
|
-
const authUserId = await this.getAuthUserId("External wallet Ethereum accounts changed event");
|
|
2512
|
-
this.emit("connect", {
|
|
2513
|
-
addresses: newAddresses,
|
|
2514
|
-
source: "external-wallet-account-change",
|
|
2515
|
-
authUserId
|
|
2516
|
-
});
|
|
2517
|
-
} else {
|
|
2518
|
-
this.setWalletState(walletId, {
|
|
2519
|
-
connected: otherAddresses.length > 0,
|
|
2520
|
-
addresses: otherAddresses
|
|
2521
|
-
});
|
|
2522
|
-
this.emit("disconnect", {
|
|
2523
|
-
source: "external-wallet-account-change"
|
|
2524
|
-
});
|
|
2525
|
-
}
|
|
2526
|
-
};
|
|
2527
|
-
if (typeof walletInfo.providers.ethereum.on === "function") {
|
|
2528
|
-
walletInfo.providers.ethereum.on("accountsChanged", handleExternalEthereumAccountsChanged);
|
|
2529
|
-
this.browserInjectedCleanupFunctions.push(() => {
|
|
2530
|
-
if (typeof walletInfo.providers?.ethereum?.off === "function") {
|
|
2531
|
-
walletInfo.providers.ethereum.off("accountsChanged", handleExternalEthereumAccountsChanged);
|
|
2532
|
-
}
|
|
2533
|
-
});
|
|
2443
|
+
for (const existingWalletId of this.eventListenersSetup) {
|
|
2444
|
+
if (existingWalletId === walletId) {
|
|
2445
|
+
continue;
|
|
2534
2446
|
}
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
walletId: this.selectedWalletId,
|
|
2540
|
-
publicKey
|
|
2541
|
-
});
|
|
2542
|
-
const walletId = this.selectedWalletId;
|
|
2543
|
-
const state = this.getWalletState(walletId);
|
|
2544
|
-
const otherAddresses = state.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.solana);
|
|
2545
|
-
if (publicKey) {
|
|
2546
|
-
const newAddresses = [...otherAddresses, { addressType: import_client3.AddressType.solana, address: publicKey }];
|
|
2547
|
-
this.setWalletState(walletId, {
|
|
2548
|
-
connected: true,
|
|
2549
|
-
addresses: newAddresses
|
|
2550
|
-
});
|
|
2551
|
-
const authUserId = await this.getAuthUserId("External wallet Solana account changed event");
|
|
2552
|
-
this.emit("connect", {
|
|
2553
|
-
addresses: newAddresses,
|
|
2554
|
-
source: "external-wallet-account-change",
|
|
2555
|
-
authUserId
|
|
2556
|
-
});
|
|
2557
|
-
} else {
|
|
2558
|
-
this.setWalletState(walletId, {
|
|
2559
|
-
connected: otherAddresses.length > 0,
|
|
2560
|
-
addresses: otherAddresses
|
|
2561
|
-
});
|
|
2562
|
-
this.emit("disconnect", {
|
|
2563
|
-
source: "external-wallet-account-change"
|
|
2564
|
-
});
|
|
2565
|
-
}
|
|
2566
|
-
};
|
|
2567
|
-
if (typeof walletInfo.providers.solana.on === "function") {
|
|
2568
|
-
walletInfo.providers.solana.on("accountChanged", handleExternalSolanaAccountChanged);
|
|
2569
|
-
this.browserInjectedCleanupFunctions.push(() => {
|
|
2570
|
-
if (typeof walletInfo.providers?.solana?.off === "function") {
|
|
2571
|
-
walletInfo.providers.solana.off("accountChanged", handleExternalSolanaAccountChanged);
|
|
2572
|
-
}
|
|
2573
|
-
});
|
|
2447
|
+
const cleanups = this.eventListenerCleanups.get(existingWalletId);
|
|
2448
|
+
if (cleanups) {
|
|
2449
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Cleaning up event listeners for wallet", { existingWalletId });
|
|
2450
|
+
cleanups.forEach((cleanup) => cleanup());
|
|
2574
2451
|
}
|
|
2452
|
+
this.eventListenersSetup.delete(existingWalletId);
|
|
2575
2453
|
}
|
|
2576
|
-
|
|
2577
|
-
|
|
2454
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up event listeners", { walletId });
|
|
2455
|
+
if (this.addressTypes.includes(import_client4.AddressType.solana) && walletInfo.providers?.solana) {
|
|
2456
|
+
this.setupSolanaEventListeners(walletInfo.providers.solana, walletId, "wallet");
|
|
2457
|
+
}
|
|
2458
|
+
if (this.addressTypes.includes(import_client4.AddressType.ethereum) && walletInfo.providers?.ethereum) {
|
|
2459
|
+
this.setupEthereumEventListeners(walletInfo.providers.ethereum, walletId, "wallet");
|
|
2578
2460
|
}
|
|
2461
|
+
this.eventListenersSetup.add(walletId);
|
|
2462
|
+
this.eventsInitialized = true;
|
|
2579
2463
|
}
|
|
2580
2464
|
};
|
|
2581
2465
|
|
|
@@ -2715,7 +2599,7 @@ var BrowserURLParamsAccessor = class {
|
|
|
2715
2599
|
var browserUrlParamsAccessor = new BrowserURLParamsAccessor();
|
|
2716
2600
|
|
|
2717
2601
|
// src/providers/embedded/adapters/auth.ts
|
|
2718
|
-
var
|
|
2602
|
+
var import_constants3 = require("@phantom/constants");
|
|
2719
2603
|
|
|
2720
2604
|
// src/utils/browser-detection.ts
|
|
2721
2605
|
function parseBrowserFromUserAgent(userAgent, hasBraveAPI) {
|
|
@@ -2880,7 +2764,7 @@ var BrowserAuthProvider = class {
|
|
|
2880
2764
|
provider: phantomOptions.provider,
|
|
2881
2765
|
authUrl: phantomOptions.authUrl
|
|
2882
2766
|
});
|
|
2883
|
-
const baseUrl = phantomOptions.authUrl ||
|
|
2767
|
+
const baseUrl = phantomOptions.authUrl || import_constants3.DEFAULT_AUTH_URL;
|
|
2884
2768
|
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Using auth URL", { baseUrl });
|
|
2885
2769
|
const params = new URLSearchParams({
|
|
2886
2770
|
public_key: phantomOptions.publicKey,
|
|
@@ -2890,9 +2774,10 @@ var BrowserAuthProvider = class {
|
|
|
2890
2774
|
// OAuth session management - defaults to allow refresh unless explicitly clearing after logout
|
|
2891
2775
|
clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
|
|
2892
2776
|
allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
|
|
2893
|
-
sdk_version: "1.0.
|
|
2777
|
+
sdk_version: "1.0.3",
|
|
2894
2778
|
sdk_type: "browser",
|
|
2895
|
-
platform: detectBrowser().name
|
|
2779
|
+
platform: detectBrowser().name,
|
|
2780
|
+
algorithm: phantomOptions.algorithm || import_constants3.DEFAULT_AUTHENTICATOR_ALGORITHM
|
|
2896
2781
|
});
|
|
2897
2782
|
if (phantomOptions.provider) {
|
|
2898
2783
|
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
|
|
@@ -3013,28 +2898,9 @@ var BrowserAuthProvider = class {
|
|
|
3013
2898
|
// src/providers/embedded/adapters/phantom-app.ts
|
|
3014
2899
|
var import_browser_injected_sdk4 = require("@phantom/browser-injected-sdk");
|
|
3015
2900
|
|
|
3016
|
-
// src/
|
|
2901
|
+
// src/waitForPhantomExtension.ts
|
|
3017
2902
|
var import_browser_injected_sdk3 = require("@phantom/browser-injected-sdk");
|
|
3018
|
-
async function
|
|
3019
|
-
const extensionInstalled = await waitForExtension(timeoutMs);
|
|
3020
|
-
if (!extensionInstalled) {
|
|
3021
|
-
return false;
|
|
3022
|
-
}
|
|
3023
|
-
try {
|
|
3024
|
-
if (!window.phantom?.app?.features || typeof window.phantom.app.features !== "function") {
|
|
3025
|
-
return false;
|
|
3026
|
-
}
|
|
3027
|
-
const response = await window.phantom.app.features();
|
|
3028
|
-
if (!Array.isArray(response.features)) {
|
|
3029
|
-
return false;
|
|
3030
|
-
}
|
|
3031
|
-
return response.features.includes("phantom_login");
|
|
3032
|
-
} catch (error) {
|
|
3033
|
-
console.error("Error checking Phantom extension features", error);
|
|
3034
|
-
return false;
|
|
3035
|
-
}
|
|
3036
|
-
}
|
|
3037
|
-
async function waitForExtension(timeoutMs) {
|
|
2903
|
+
async function waitForPhantomExtension(timeoutMs = 3e3) {
|
|
3038
2904
|
return new Promise((resolve) => {
|
|
3039
2905
|
const startTime = Date.now();
|
|
3040
2906
|
const checkInterval = 100;
|
|
@@ -3057,6 +2923,27 @@ async function waitForExtension(timeoutMs) {
|
|
|
3057
2923
|
});
|
|
3058
2924
|
}
|
|
3059
2925
|
|
|
2926
|
+
// src/isPhantomLoginAvailable.ts
|
|
2927
|
+
async function isPhantomLoginAvailable(timeoutMs = 3e3) {
|
|
2928
|
+
const extensionInstalled = await waitForPhantomExtension(timeoutMs);
|
|
2929
|
+
if (!extensionInstalled) {
|
|
2930
|
+
return false;
|
|
2931
|
+
}
|
|
2932
|
+
try {
|
|
2933
|
+
if (!window.phantom?.app?.features || typeof window.phantom.app.features !== "function") {
|
|
2934
|
+
return false;
|
|
2935
|
+
}
|
|
2936
|
+
const response = await window.phantom.app.features();
|
|
2937
|
+
if (!Array.isArray(response.features)) {
|
|
2938
|
+
return false;
|
|
2939
|
+
}
|
|
2940
|
+
return response.features.includes("phantom_login");
|
|
2941
|
+
} catch (error) {
|
|
2942
|
+
console.error("Error checking Phantom extension features", error);
|
|
2943
|
+
return false;
|
|
2944
|
+
}
|
|
2945
|
+
}
|
|
2946
|
+
|
|
3060
2947
|
// src/providers/embedded/adapters/phantom-app.ts
|
|
3061
2948
|
var BrowserPhantomAppProvider = class {
|
|
3062
2949
|
/**
|
|
@@ -3126,7 +3013,7 @@ var BrowserLogger = class {
|
|
|
3126
3013
|
};
|
|
3127
3014
|
|
|
3128
3015
|
// src/providers/embedded/index.ts
|
|
3129
|
-
var
|
|
3016
|
+
var import_constants4 = require("@phantom/constants");
|
|
3130
3017
|
var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvider {
|
|
3131
3018
|
constructor(config) {
|
|
3132
3019
|
debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
|
|
@@ -3147,14 +3034,14 @@ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvi
|
|
|
3147
3034
|
name: platformName,
|
|
3148
3035
|
// Use detected browser name and version for identification
|
|
3149
3036
|
analyticsHeaders: {
|
|
3150
|
-
[
|
|
3151
|
-
[
|
|
3037
|
+
[import_constants4.ANALYTICS_HEADERS.SDK_TYPE]: "browser",
|
|
3038
|
+
[import_constants4.ANALYTICS_HEADERS.PLATFORM]: browserName,
|
|
3152
3039
|
// firefox, chrome, safari, etc.
|
|
3153
|
-
[
|
|
3040
|
+
[import_constants4.ANALYTICS_HEADERS.PLATFORM_VERSION]: version,
|
|
3154
3041
|
// Full user agent for more detailed info
|
|
3155
|
-
[
|
|
3156
|
-
[
|
|
3157
|
-
[
|
|
3042
|
+
[import_constants4.ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
3043
|
+
[import_constants4.ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
3044
|
+
[import_constants4.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.3"
|
|
3158
3045
|
// Replaced at build time
|
|
3159
3046
|
}
|
|
3160
3047
|
};
|
|
@@ -3171,7 +3058,7 @@ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvi
|
|
|
3171
3058
|
|
|
3172
3059
|
// src/ProviderManager.ts
|
|
3173
3060
|
var import_embedded_provider_core2 = require("@phantom/embedded-provider-core");
|
|
3174
|
-
var
|
|
3061
|
+
var import_constants5 = require("@phantom/constants");
|
|
3175
3062
|
|
|
3176
3063
|
// src/utils/auth-callback.ts
|
|
3177
3064
|
function isAuthFailureCallback(searchParams) {
|
|
@@ -3191,11 +3078,12 @@ function isAuthCallbackUrl(searchParams) {
|
|
|
3191
3078
|
}
|
|
3192
3079
|
|
|
3193
3080
|
// src/utils/deeplink.ts
|
|
3194
|
-
function getDeeplinkToPhantom(ref) {
|
|
3195
|
-
|
|
3081
|
+
function getDeeplinkToPhantom(ref, currentHref) {
|
|
3082
|
+
const resolvedHref = currentHref ?? window.location.href;
|
|
3083
|
+
if (!resolvedHref.startsWith("http:") && !resolvedHref.startsWith("https:")) {
|
|
3196
3084
|
throw new Error("Invalid URL protocol - only HTTP/HTTPS URLs are supported for deeplinks");
|
|
3197
3085
|
}
|
|
3198
|
-
const currentUrl = encodeURIComponent(
|
|
3086
|
+
const currentUrl = encodeURIComponent(resolvedHref);
|
|
3199
3087
|
const refParam = ref ? `?ref=${encodeURIComponent(ref)}` : "";
|
|
3200
3088
|
return `https://phantom.app/ul/browse/${currentUrl}${refParam}`;
|
|
3201
3089
|
}
|
|
@@ -3291,8 +3179,14 @@ var ProviderManager = class {
|
|
|
3291
3179
|
} else if (requestedProvider === "deeplink") {
|
|
3292
3180
|
try {
|
|
3293
3181
|
const deeplinkUrl = getDeeplinkToPhantom();
|
|
3294
|
-
if (typeof window !== "undefined") {
|
|
3295
|
-
|
|
3182
|
+
if (typeof window !== "undefined" && window.location) {
|
|
3183
|
+
try {
|
|
3184
|
+
window.location.href = deeplinkUrl;
|
|
3185
|
+
} catch (error) {
|
|
3186
|
+
debug.warn(DebugCategory.PROVIDER_MANAGER, "Failed to set deeplink location", {
|
|
3187
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3188
|
+
});
|
|
3189
|
+
}
|
|
3296
3190
|
}
|
|
3297
3191
|
return {
|
|
3298
3192
|
addresses: [],
|
|
@@ -3437,7 +3331,7 @@ var ProviderManager = class {
|
|
|
3437
3331
|
if (!this.eventListeners.has(event)) {
|
|
3438
3332
|
this.eventListeners.set(event, /* @__PURE__ */ new Set());
|
|
3439
3333
|
}
|
|
3440
|
-
this.eventListeners.get(event)
|
|
3334
|
+
this.eventListeners.get(event)?.add(callback);
|
|
3441
3335
|
this.ensureProviderEventForwarding();
|
|
3442
3336
|
}
|
|
3443
3337
|
/**
|
|
@@ -3446,8 +3340,8 @@ var ProviderManager = class {
|
|
|
3446
3340
|
off(event, callback) {
|
|
3447
3341
|
debug.log(DebugCategory.PROVIDER_MANAGER, "Removing event listener", { event });
|
|
3448
3342
|
if (this.eventListeners.has(event)) {
|
|
3449
|
-
this.eventListeners.get(event)
|
|
3450
|
-
if (this.eventListeners.get(event)
|
|
3343
|
+
this.eventListeners.get(event)?.delete(callback);
|
|
3344
|
+
if (this.eventListeners.get(event)?.size === 0) {
|
|
3451
3345
|
this.eventListeners.delete(event);
|
|
3452
3346
|
}
|
|
3453
3347
|
}
|
|
@@ -3555,8 +3449,8 @@ var ProviderManager = class {
|
|
|
3555
3449
|
if (!this.config.appId) {
|
|
3556
3450
|
throw new Error("appId is required for embedded provider");
|
|
3557
3451
|
}
|
|
3558
|
-
const apiBaseUrl = this.config.apiBaseUrl ||
|
|
3559
|
-
const authUrl = this.config.authOptions?.authUrl ||
|
|
3452
|
+
const apiBaseUrl = this.config.apiBaseUrl || import_constants5.DEFAULT_WALLET_API_URL;
|
|
3453
|
+
const authUrl = this.config.authOptions?.authUrl || import_constants5.DEFAULT_AUTH_URL;
|
|
3560
3454
|
provider = new EmbeddedProvider({
|
|
3561
3455
|
apiBaseUrl,
|
|
3562
3456
|
appId: this.config.appId,
|
|
@@ -3565,7 +3459,7 @@ var ProviderManager = class {
|
|
|
3565
3459
|
authUrl,
|
|
3566
3460
|
redirectUrl: this.config.authOptions?.redirectUrl || this.getValidatedCurrentUrl()
|
|
3567
3461
|
},
|
|
3568
|
-
embeddedWalletType: embeddedWalletType ||
|
|
3462
|
+
embeddedWalletType: embeddedWalletType || import_constants5.DEFAULT_EMBEDDED_WALLET_TYPE,
|
|
3569
3463
|
addressTypes: this.config.addressTypes || [import_client.AddressType.solana]
|
|
3570
3464
|
});
|
|
3571
3465
|
} else {
|
|
@@ -3601,7 +3495,7 @@ var ProviderManager = class {
|
|
|
3601
3495
|
|
|
3602
3496
|
// src/BrowserSDK.ts
|
|
3603
3497
|
var import_embedded_provider_core3 = require("@phantom/embedded-provider-core");
|
|
3604
|
-
var
|
|
3498
|
+
var import_constants6 = require("@phantom/constants");
|
|
3605
3499
|
var BROWSER_SDK_PROVIDER_TYPES = [
|
|
3606
3500
|
...import_embedded_provider_core3.EMBEDDED_PROVIDER_AUTH_TYPES,
|
|
3607
3501
|
"injected",
|
|
@@ -3637,7 +3531,7 @@ var BrowserSDK = class {
|
|
|
3637
3531
|
});
|
|
3638
3532
|
throw new Error("appId is required when using embedded providers (google, apple, phantom, etc.)");
|
|
3639
3533
|
}
|
|
3640
|
-
const embeddedWalletType = config.embeddedWalletType ||
|
|
3534
|
+
const embeddedWalletType = config.embeddedWalletType || import_constants6.DEFAULT_EMBEDDED_WALLET_TYPE;
|
|
3641
3535
|
if (!["app-wallet", "user-wallet"].includes(embeddedWalletType)) {
|
|
3642
3536
|
debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType", {
|
|
3643
3537
|
embeddedWalletType: config.embeddedWalletType
|
|
@@ -3763,6 +3657,7 @@ var BrowserSDK = class {
|
|
|
3763
3657
|
*/
|
|
3764
3658
|
async autoConnect() {
|
|
3765
3659
|
debug.log(DebugCategory.BROWSER_SDK, "Attempting auto-connect with fallback strategy");
|
|
3660
|
+
await this.discoverWallets();
|
|
3766
3661
|
const result = await this.providerManager.autoConnect();
|
|
3767
3662
|
if (result) {
|
|
3768
3663
|
debug.info(DebugCategory.BROWSER_SDK, "Auto-connect successful", {
|
|
@@ -3910,31 +3805,7 @@ var BrowserSDK = class {
|
|
|
3910
3805
|
}
|
|
3911
3806
|
};
|
|
3912
3807
|
|
|
3913
|
-
// src/waitForPhantomExtension.ts
|
|
3914
|
-
var import_browser_injected_sdk5 = require("@phantom/browser-injected-sdk");
|
|
3915
|
-
async function waitForPhantomExtension(timeoutMs = 3e3) {
|
|
3916
|
-
return new Promise((resolve) => {
|
|
3917
|
-
const startTime = Date.now();
|
|
3918
|
-
const checkInterval = 100;
|
|
3919
|
-
const checkForExtension = () => {
|
|
3920
|
-
try {
|
|
3921
|
-
if ((0, import_browser_injected_sdk5.isPhantomExtensionInstalled)()) {
|
|
3922
|
-
resolve(true);
|
|
3923
|
-
return;
|
|
3924
|
-
}
|
|
3925
|
-
} catch (error) {
|
|
3926
|
-
}
|
|
3927
|
-
const elapsed = Date.now() - startTime;
|
|
3928
|
-
if (elapsed >= timeoutMs) {
|
|
3929
|
-
resolve(false);
|
|
3930
|
-
return;
|
|
3931
|
-
}
|
|
3932
|
-
setTimeout(checkForExtension, checkInterval);
|
|
3933
|
-
};
|
|
3934
|
-
checkForExtension();
|
|
3935
|
-
});
|
|
3936
|
-
}
|
|
3937
|
-
|
|
3938
3808
|
// src/index.ts
|
|
3939
|
-
var
|
|
3940
|
-
var
|
|
3809
|
+
var import_constants7 = require("@phantom/constants");
|
|
3810
|
+
var import_client5 = require("@phantom/client");
|
|
3811
|
+
var import_constants8 = require("@phantom/constants");
|