@phantom/browser-sdk 1.0.0-beta.1 → 1.0.0-beta.11
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 +37 -60
- package/dist/index.d.ts +48 -15
- package/dist/index.js +307 -92
- package/dist/index.mjs +304 -89
- package/package.json +9 -8
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
import { AddressType } from "@phantom/client";
|
|
3
|
+
|
|
1
4
|
// src/providers/injected/index.ts
|
|
2
|
-
import { AddressType as
|
|
5
|
+
import { AddressType as AddressType4 } from "@phantom/client";
|
|
3
6
|
import { createPhantom, createExtensionPlugin } from "@phantom/browser-injected-sdk";
|
|
4
7
|
import { createSolanaPlugin } from "@phantom/browser-injected-sdk/solana";
|
|
5
8
|
import { createEthereumPlugin } from "@phantom/browser-injected-sdk/ethereum";
|
|
@@ -83,7 +86,7 @@ var DebugCategory = {
|
|
|
83
86
|
|
|
84
87
|
// src/providers/injected/chains/SolanaChain.ts
|
|
85
88
|
import { EventEmitter } from "eventemitter3";
|
|
86
|
-
import { AddressType } from "@phantom/client";
|
|
89
|
+
import { AddressType as AddressType2 } from "@phantom/client";
|
|
87
90
|
import { Buffer } from "buffer";
|
|
88
91
|
var InjectedSolanaChain = class {
|
|
89
92
|
constructor(phantom, callbacks) {
|
|
@@ -108,7 +111,7 @@ var InjectedSolanaChain = class {
|
|
|
108
111
|
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
109
112
|
}
|
|
110
113
|
const addresses = this.callbacks.getAddresses();
|
|
111
|
-
const solanaAddress = addresses.find((addr) => addr.addressType ===
|
|
114
|
+
const solanaAddress = addresses.find((addr) => addr.addressType === AddressType2.solana);
|
|
112
115
|
if (!solanaAddress) {
|
|
113
116
|
return Promise.reject(new Error("Solana not enabled for this provider"));
|
|
114
117
|
}
|
|
@@ -127,17 +130,42 @@ var InjectedSolanaChain = class {
|
|
|
127
130
|
publicKey: this._publicKey || ""
|
|
128
131
|
};
|
|
129
132
|
}
|
|
130
|
-
signTransaction(
|
|
131
|
-
|
|
132
|
-
new Error("
|
|
133
|
-
|
|
133
|
+
async signTransaction(transaction) {
|
|
134
|
+
if (!this.callbacks.isConnected()) {
|
|
135
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
const result = await this.phantom.solana.signTransaction(transaction);
|
|
139
|
+
return result;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return Promise.reject(error);
|
|
142
|
+
}
|
|
134
143
|
}
|
|
135
144
|
async signAndSendTransaction(transaction) {
|
|
136
145
|
const result = await this.phantom.solana.signAndSendTransaction(transaction);
|
|
137
146
|
return { signature: result.signature };
|
|
138
147
|
}
|
|
139
|
-
signAllTransactions(
|
|
140
|
-
|
|
148
|
+
async signAllTransactions(transactions) {
|
|
149
|
+
if (!this.callbacks.isConnected()) {
|
|
150
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const result = await this.phantom.solana.signAllTransactions(transactions);
|
|
154
|
+
return result;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
return Promise.reject(error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async signAndSendAllTransactions(transactions) {
|
|
160
|
+
if (!this.callbacks.isConnected()) {
|
|
161
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const result = await this.phantom.solana.signAndSendAllTransactions(transactions);
|
|
165
|
+
return { signatures: result.signatures };
|
|
166
|
+
} catch (error) {
|
|
167
|
+
return Promise.reject(error);
|
|
168
|
+
}
|
|
141
169
|
}
|
|
142
170
|
switchNetwork(_network) {
|
|
143
171
|
return Promise.resolve();
|
|
@@ -163,7 +191,7 @@ var InjectedSolanaChain = class {
|
|
|
163
191
|
this.eventEmitter.emit("accountChanged", publicKey);
|
|
164
192
|
});
|
|
165
193
|
this.callbacks.on("connect", (data) => {
|
|
166
|
-
const solanaAddress = data.addresses?.find((addr) => addr.addressType ===
|
|
194
|
+
const solanaAddress = data.addresses?.find((addr) => addr.addressType === AddressType2.solana);
|
|
167
195
|
if (solanaAddress) {
|
|
168
196
|
this.updateConnectionState(true, solanaAddress.address);
|
|
169
197
|
}
|
|
@@ -174,7 +202,7 @@ var InjectedSolanaChain = class {
|
|
|
174
202
|
}
|
|
175
203
|
syncInitialState() {
|
|
176
204
|
if (this.callbacks.isConnected()) {
|
|
177
|
-
const solanaAddress = this.callbacks.getAddresses().find((addr) => addr.addressType ===
|
|
205
|
+
const solanaAddress = this.callbacks.getAddresses().find((addr) => addr.addressType === AddressType2.solana);
|
|
178
206
|
if (solanaAddress) {
|
|
179
207
|
this.updateConnectionState(true, solanaAddress.address);
|
|
180
208
|
}
|
|
@@ -195,7 +223,7 @@ var InjectedSolanaChain = class {
|
|
|
195
223
|
|
|
196
224
|
// src/providers/injected/chains/EthereumChain.ts
|
|
197
225
|
import { EventEmitter as EventEmitter2 } from "eventemitter3";
|
|
198
|
-
import { AddressType as
|
|
226
|
+
import { AddressType as AddressType3 } from "@phantom/client";
|
|
199
227
|
var InjectedEthereumChain = class {
|
|
200
228
|
constructor(phantom, callbacks) {
|
|
201
229
|
this._connected = false;
|
|
@@ -217,8 +245,13 @@ var InjectedEthereumChain = class {
|
|
|
217
245
|
get accounts() {
|
|
218
246
|
return this._accounts;
|
|
219
247
|
}
|
|
220
|
-
// EIP-1193 core method
|
|
248
|
+
// EIP-1193 core method with eth_signTransaction support
|
|
221
249
|
async request(args) {
|
|
250
|
+
if (args.method === "eth_signTransaction") {
|
|
251
|
+
const [transaction] = args.params;
|
|
252
|
+
const result = await this.signTransaction(transaction);
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
222
255
|
const provider = await this.phantom.ethereum.getProvider();
|
|
223
256
|
return await provider.request(args);
|
|
224
257
|
}
|
|
@@ -228,7 +261,7 @@ var InjectedEthereumChain = class {
|
|
|
228
261
|
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
229
262
|
}
|
|
230
263
|
const addresses = this.callbacks.getAddresses();
|
|
231
|
-
const ethAddresses = addresses.filter((addr) => addr.addressType ===
|
|
264
|
+
const ethAddresses = addresses.filter((addr) => addr.addressType === AddressType3.ethereum).map((addr) => addr.address);
|
|
232
265
|
this.updateConnectionState(true, ethAddresses);
|
|
233
266
|
return Promise.resolve(ethAddresses);
|
|
234
267
|
}
|
|
@@ -242,6 +275,9 @@ var InjectedEthereumChain = class {
|
|
|
242
275
|
async signTypedData(typedData, address) {
|
|
243
276
|
return await this.phantom.ethereum.signTypedData(typedData, address);
|
|
244
277
|
}
|
|
278
|
+
async signTransaction(transaction) {
|
|
279
|
+
return await this.phantom.ethereum.signTransaction(transaction);
|
|
280
|
+
}
|
|
245
281
|
async sendTransaction(transaction) {
|
|
246
282
|
return await this.phantom.ethereum.sendTransaction(transaction);
|
|
247
283
|
}
|
|
@@ -280,7 +316,7 @@ var InjectedEthereumChain = class {
|
|
|
280
316
|
this.eventEmitter.emit("chainChanged", chainId);
|
|
281
317
|
});
|
|
282
318
|
this.callbacks.on("connect", (data) => {
|
|
283
|
-
const ethAddresses = data.addresses?.filter((addr) => addr.addressType ===
|
|
319
|
+
const ethAddresses = data.addresses?.filter((addr) => addr.addressType === AddressType3.ethereum)?.map((addr) => addr.address) || [];
|
|
284
320
|
if (ethAddresses.length > 0) {
|
|
285
321
|
this.updateConnectionState(true, ethAddresses);
|
|
286
322
|
}
|
|
@@ -291,7 +327,7 @@ var InjectedEthereumChain = class {
|
|
|
291
327
|
}
|
|
292
328
|
syncInitialState() {
|
|
293
329
|
if (this.callbacks.isConnected()) {
|
|
294
|
-
const ethAddresses = this.callbacks.getAddresses().filter((addr) => addr.addressType ===
|
|
330
|
+
const ethAddresses = this.callbacks.getAddresses().filter((addr) => addr.addressType === AddressType3.ethereum).map((addr) => addr.address);
|
|
295
331
|
if (ethAddresses.length > 0) {
|
|
296
332
|
this.updateConnectionState(true, ethAddresses);
|
|
297
333
|
}
|
|
@@ -323,11 +359,11 @@ var InjectedProvider = class {
|
|
|
323
359
|
this.addressTypes = config.addressTypes;
|
|
324
360
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Address types configured", { addressTypes: this.addressTypes });
|
|
325
361
|
const plugins = [createExtensionPlugin()];
|
|
326
|
-
if (this.addressTypes.includes(
|
|
362
|
+
if (this.addressTypes.includes(AddressType4.solana)) {
|
|
327
363
|
plugins.push(createSolanaPlugin());
|
|
328
364
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana plugin added");
|
|
329
365
|
}
|
|
330
|
-
if (this.addressTypes.includes(
|
|
366
|
+
if (this.addressTypes.includes(AddressType4.ethereum)) {
|
|
331
367
|
plugins.push(createEthereumPlugin());
|
|
332
368
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
|
|
333
369
|
}
|
|
@@ -338,10 +374,10 @@ var InjectedProvider = class {
|
|
|
338
374
|
});
|
|
339
375
|
this.phantom = createPhantom({ plugins });
|
|
340
376
|
const callbacks = this.createCallbacks();
|
|
341
|
-
if (this.addressTypes.includes(
|
|
377
|
+
if (this.addressTypes.includes(AddressType4.solana)) {
|
|
342
378
|
this._solanaChain = new InjectedSolanaChain(this.phantom, callbacks);
|
|
343
379
|
}
|
|
344
|
-
if (this.addressTypes.includes(
|
|
380
|
+
if (this.addressTypes.includes(AddressType4.ethereum)) {
|
|
345
381
|
this._ethereumChain = new InjectedEthereumChain(this.phantom, callbacks);
|
|
346
382
|
}
|
|
347
383
|
debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
|
|
@@ -350,7 +386,7 @@ var InjectedProvider = class {
|
|
|
350
386
|
* Access to Solana chain operations
|
|
351
387
|
*/
|
|
352
388
|
get solana() {
|
|
353
|
-
if (!this.addressTypes.includes(
|
|
389
|
+
if (!this.addressTypes.includes(AddressType4.solana)) {
|
|
354
390
|
throw new Error("Solana not enabled for this provider");
|
|
355
391
|
}
|
|
356
392
|
if (!this._solanaChain) {
|
|
@@ -362,7 +398,7 @@ var InjectedProvider = class {
|
|
|
362
398
|
* Access to Ethereum chain operations
|
|
363
399
|
*/
|
|
364
400
|
get ethereum() {
|
|
365
|
-
if (!this.addressTypes.includes(
|
|
401
|
+
if (!this.addressTypes.includes(AddressType4.ethereum)) {
|
|
366
402
|
throw new Error("Ethereum not enabled for this provider");
|
|
367
403
|
}
|
|
368
404
|
if (!this._ethereumChain) {
|
|
@@ -392,13 +428,13 @@ var InjectedProvider = class {
|
|
|
392
428
|
}
|
|
393
429
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Phantom extension detected");
|
|
394
430
|
const connectedAddresses = [];
|
|
395
|
-
if (this.addressTypes.includes(
|
|
431
|
+
if (this.addressTypes.includes(AddressType4.solana)) {
|
|
396
432
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
|
|
397
433
|
try {
|
|
398
434
|
const publicKey = await this.phantom.solana.connect();
|
|
399
435
|
if (publicKey) {
|
|
400
436
|
connectedAddresses.push({
|
|
401
|
-
addressType:
|
|
437
|
+
addressType: AddressType4.solana,
|
|
402
438
|
address: publicKey
|
|
403
439
|
});
|
|
404
440
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
|
|
@@ -407,13 +443,13 @@ var InjectedProvider = class {
|
|
|
407
443
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana", { error: err });
|
|
408
444
|
}
|
|
409
445
|
}
|
|
410
|
-
if (this.addressTypes.includes(
|
|
446
|
+
if (this.addressTypes.includes(AddressType4.ethereum)) {
|
|
411
447
|
try {
|
|
412
448
|
const accounts = await this.phantom.ethereum.connect();
|
|
413
449
|
if (accounts && accounts.length > 0) {
|
|
414
450
|
connectedAddresses.push(
|
|
415
451
|
...accounts.map((address) => ({
|
|
416
|
-
addressType:
|
|
452
|
+
addressType: AddressType4.ethereum,
|
|
417
453
|
address
|
|
418
454
|
}))
|
|
419
455
|
);
|
|
@@ -455,7 +491,7 @@ var InjectedProvider = class {
|
|
|
455
491
|
}
|
|
456
492
|
async disconnect() {
|
|
457
493
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
|
|
458
|
-
if (this.addressTypes.includes(
|
|
494
|
+
if (this.addressTypes.includes(AddressType4.solana)) {
|
|
459
495
|
try {
|
|
460
496
|
await this.phantom.solana.disconnect();
|
|
461
497
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
|
|
@@ -463,7 +499,7 @@ var InjectedProvider = class {
|
|
|
463
499
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
|
|
464
500
|
}
|
|
465
501
|
}
|
|
466
|
-
if (this.addressTypes.includes(
|
|
502
|
+
if (this.addressTypes.includes(AddressType4.ethereum)) {
|
|
467
503
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected (no-op)");
|
|
468
504
|
}
|
|
469
505
|
this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
|
|
@@ -475,6 +511,87 @@ var InjectedProvider = class {
|
|
|
475
511
|
});
|
|
476
512
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Injected provider disconnected successfully");
|
|
477
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Attempt auto-connection using onlyIfTrusted parameter
|
|
516
|
+
* This will only connect if the dApp is already trusted by the user
|
|
517
|
+
* Should be called after setting up event listeners
|
|
518
|
+
*/
|
|
519
|
+
async autoConnect() {
|
|
520
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting auto-connect with onlyIfTrusted=true");
|
|
521
|
+
this.emit("connect_start", {
|
|
522
|
+
source: "auto-connect",
|
|
523
|
+
providerType: "injected"
|
|
524
|
+
});
|
|
525
|
+
try {
|
|
526
|
+
if (!this.phantom.extension?.isInstalled?.()) {
|
|
527
|
+
debug.warn(DebugCategory.INJECTED_PROVIDER, "Phantom wallet extension not found for auto-connect");
|
|
528
|
+
this.emit("connect_error", {
|
|
529
|
+
error: "Phantom wallet not found",
|
|
530
|
+
source: "auto-connect"
|
|
531
|
+
});
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
const connectedAddresses = [];
|
|
535
|
+
if (this.addressTypes.includes(AddressType4.solana)) {
|
|
536
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana auto-connect");
|
|
537
|
+
try {
|
|
538
|
+
const publicKey = await this.phantom.solana.connect({ onlyIfTrusted: true });
|
|
539
|
+
if (publicKey) {
|
|
540
|
+
connectedAddresses.push({
|
|
541
|
+
addressType: AddressType4.solana,
|
|
542
|
+
address: publicKey
|
|
543
|
+
});
|
|
544
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana auto-connected successfully", { address: publicKey });
|
|
545
|
+
}
|
|
546
|
+
} catch (err) {
|
|
547
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana auto-connect failed (expected if not trusted)", { error: err });
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (this.addressTypes.includes(AddressType4.ethereum)) {
|
|
551
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Ethereum auto-connect");
|
|
552
|
+
try {
|
|
553
|
+
const accounts = await this.phantom.ethereum.connect({ onlyIfTrusted: true });
|
|
554
|
+
if (accounts && accounts.length > 0) {
|
|
555
|
+
connectedAddresses.push(
|
|
556
|
+
...accounts.map((address) => ({
|
|
557
|
+
addressType: AddressType4.ethereum,
|
|
558
|
+
address
|
|
559
|
+
}))
|
|
560
|
+
);
|
|
561
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connected successfully", { addresses: accounts });
|
|
562
|
+
}
|
|
563
|
+
} catch (err) {
|
|
564
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connect failed (expected if not trusted)", { error: err });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (connectedAddresses.length === 0) {
|
|
568
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Auto-connect failed: no trusted connections available");
|
|
569
|
+
this.emit("connect_error", {
|
|
570
|
+
error: "No trusted connections available",
|
|
571
|
+
source: "auto-connect"
|
|
572
|
+
});
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
this.addresses = connectedAddresses;
|
|
576
|
+
this.connected = true;
|
|
577
|
+
this.emit("connect", {
|
|
578
|
+
addresses: this.addresses,
|
|
579
|
+
source: "auto-connect"
|
|
580
|
+
});
|
|
581
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Auto-connect successful", {
|
|
582
|
+
addressCount: connectedAddresses.length,
|
|
583
|
+
addresses: connectedAddresses.map((addr) => ({ type: addr.addressType, address: addr.address.substring(0, 8) + "..." }))
|
|
584
|
+
});
|
|
585
|
+
} catch (error) {
|
|
586
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Auto-connect failed with error", {
|
|
587
|
+
error: error instanceof Error ? error.message : String(error)
|
|
588
|
+
});
|
|
589
|
+
this.emit("connect_error", {
|
|
590
|
+
error: error instanceof Error ? error.message : "Auto-connect failed",
|
|
591
|
+
source: "auto-connect"
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
478
595
|
getAddresses() {
|
|
479
596
|
return this.addresses;
|
|
480
597
|
}
|
|
@@ -538,10 +655,10 @@ var InjectedProvider = class {
|
|
|
538
655
|
}
|
|
539
656
|
setupBrowserInjectedEvents() {
|
|
540
657
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up browser-injected-sdk event listeners");
|
|
541
|
-
if (this.addressTypes.includes(
|
|
658
|
+
if (this.addressTypes.includes(AddressType4.solana)) {
|
|
542
659
|
this.setupSolanaEvents();
|
|
543
660
|
}
|
|
544
|
-
if (this.addressTypes.includes(
|
|
661
|
+
if (this.addressTypes.includes(AddressType4.ethereum)) {
|
|
545
662
|
this.setupEthereumEvents();
|
|
546
663
|
}
|
|
547
664
|
}
|
|
@@ -549,8 +666,8 @@ var InjectedProvider = class {
|
|
|
549
666
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners");
|
|
550
667
|
const handleSolanaConnect = (publicKey) => {
|
|
551
668
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey });
|
|
552
|
-
const solanaAddress = { addressType:
|
|
553
|
-
if (!this.addresses.find((addr) => addr.addressType ===
|
|
669
|
+
const solanaAddress = { addressType: AddressType4.solana, address: publicKey };
|
|
670
|
+
if (!this.addresses.find((addr) => addr.addressType === AddressType4.solana)) {
|
|
554
671
|
this.addresses.push(solanaAddress);
|
|
555
672
|
}
|
|
556
673
|
this.connected = true;
|
|
@@ -561,19 +678,19 @@ var InjectedProvider = class {
|
|
|
561
678
|
};
|
|
562
679
|
const handleSolanaDisconnect = () => {
|
|
563
680
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnect event received");
|
|
564
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
565
|
-
this.connected =
|
|
681
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType4.solana);
|
|
682
|
+
this.connected = false;
|
|
566
683
|
this.emit("disconnect", {
|
|
567
684
|
source: "injected-extension"
|
|
568
685
|
});
|
|
569
686
|
};
|
|
570
687
|
const handleSolanaAccountChanged = (publicKey) => {
|
|
571
688
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey });
|
|
572
|
-
const solanaIndex = this.addresses.findIndex((addr) => addr.addressType ===
|
|
689
|
+
const solanaIndex = this.addresses.findIndex((addr) => addr.addressType === AddressType4.solana);
|
|
573
690
|
if (solanaIndex >= 0) {
|
|
574
|
-
this.addresses[solanaIndex] = { addressType:
|
|
691
|
+
this.addresses[solanaIndex] = { addressType: AddressType4.solana, address: publicKey };
|
|
575
692
|
} else {
|
|
576
|
-
this.addresses.push({ addressType:
|
|
693
|
+
this.addresses.push({ addressType: AddressType4.solana, address: publicKey });
|
|
577
694
|
}
|
|
578
695
|
this.emit("connect", {
|
|
579
696
|
addresses: this.addresses,
|
|
@@ -582,21 +699,18 @@ var InjectedProvider = class {
|
|
|
582
699
|
};
|
|
583
700
|
const cleanupConnect = this.phantom.solana.addEventListener("connect", handleSolanaConnect);
|
|
584
701
|
const cleanupDisconnect = this.phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
|
|
585
|
-
const cleanupAccountChanged = this.phantom.solana.addEventListener(
|
|
586
|
-
"accountChanged",
|
|
587
|
-
handleSolanaAccountChanged
|
|
588
|
-
);
|
|
702
|
+
const cleanupAccountChanged = this.phantom.solana.addEventListener("accountChanged", handleSolanaAccountChanged);
|
|
589
703
|
this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountChanged);
|
|
590
704
|
}
|
|
591
705
|
setupEthereumEvents() {
|
|
592
706
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners");
|
|
593
707
|
const handleEthereumConnect = (accounts) => {
|
|
594
708
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts });
|
|
595
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
709
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType4.ethereum);
|
|
596
710
|
if (accounts && accounts.length > 0) {
|
|
597
711
|
this.addresses.push(
|
|
598
712
|
...accounts.map((address) => ({
|
|
599
|
-
addressType:
|
|
713
|
+
addressType: AddressType4.ethereum,
|
|
600
714
|
address
|
|
601
715
|
}))
|
|
602
716
|
);
|
|
@@ -609,27 +723,32 @@ var InjectedProvider = class {
|
|
|
609
723
|
};
|
|
610
724
|
const handleEthereumDisconnect = () => {
|
|
611
725
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received");
|
|
612
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
613
|
-
this.connected =
|
|
726
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType4.ethereum);
|
|
727
|
+
this.connected = false;
|
|
614
728
|
this.emit("disconnect", {
|
|
615
729
|
source: "injected-extension"
|
|
616
730
|
});
|
|
617
731
|
};
|
|
618
732
|
const handleEthereumAccountsChanged = (accounts) => {
|
|
619
733
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts });
|
|
620
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
734
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType4.ethereum);
|
|
621
735
|
if (accounts && accounts.length > 0) {
|
|
622
736
|
this.addresses.push(
|
|
623
737
|
...accounts.map((address) => ({
|
|
624
|
-
addressType:
|
|
738
|
+
addressType: AddressType4.ethereum,
|
|
625
739
|
address
|
|
626
740
|
}))
|
|
627
741
|
);
|
|
742
|
+
this.emit("connect", {
|
|
743
|
+
addresses: this.addresses,
|
|
744
|
+
source: "injected-extension-account-change"
|
|
745
|
+
});
|
|
746
|
+
} else {
|
|
747
|
+
this.connected = false;
|
|
748
|
+
this.emit("disconnect", {
|
|
749
|
+
source: "injected-extension-account-change"
|
|
750
|
+
});
|
|
628
751
|
}
|
|
629
|
-
this.emit("connect", {
|
|
630
|
-
addresses: this.addresses,
|
|
631
|
-
source: "injected-extension-account-change"
|
|
632
|
-
});
|
|
633
752
|
};
|
|
634
753
|
const cleanupConnect = this.phantom.ethereum.addEventListener("connect", handleEthereumConnect);
|
|
635
754
|
const cleanupDisconnect = this.phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
|
|
@@ -758,15 +877,19 @@ var BrowserURLParamsAccessor = class {
|
|
|
758
877
|
};
|
|
759
878
|
var browserUrlParamsAccessor = new BrowserURLParamsAccessor();
|
|
760
879
|
|
|
761
|
-
// src/constants.ts
|
|
762
|
-
var DEFAULT_AUTH_URL = "https://connect.phantom.app";
|
|
763
|
-
var DEFAULT_WALLET_API_URL = "https://api.phantom.app/v1/wallets";
|
|
764
|
-
|
|
765
880
|
// src/providers/embedded/adapters/auth.ts
|
|
881
|
+
import { DEFAULT_AUTH_URL } from "@phantom/constants";
|
|
766
882
|
var BrowserAuthProvider = class {
|
|
767
883
|
constructor(urlParamsAccessor) {
|
|
768
884
|
this.urlParamsAccessor = urlParamsAccessor;
|
|
769
885
|
}
|
|
886
|
+
getValidatedCurrentUrl() {
|
|
887
|
+
const currentUrl = window.location.href;
|
|
888
|
+
if (!currentUrl.startsWith("http:") && !currentUrl.startsWith("https:")) {
|
|
889
|
+
throw new Error("Invalid URL protocol - only HTTP/HTTPS URLs are supported");
|
|
890
|
+
}
|
|
891
|
+
return currentUrl;
|
|
892
|
+
}
|
|
770
893
|
authenticate(options) {
|
|
771
894
|
return new Promise((resolve) => {
|
|
772
895
|
if ("jwtToken" in options) {
|
|
@@ -774,8 +897,7 @@ var BrowserAuthProvider = class {
|
|
|
774
897
|
}
|
|
775
898
|
const phantomOptions = options;
|
|
776
899
|
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Starting Phantom Connect authentication", {
|
|
777
|
-
|
|
778
|
-
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
900
|
+
publicKey: phantomOptions.publicKey,
|
|
779
901
|
appId: phantomOptions.appId,
|
|
780
902
|
provider: phantomOptions.provider,
|
|
781
903
|
authUrl: phantomOptions.authUrl,
|
|
@@ -784,12 +906,12 @@ var BrowserAuthProvider = class {
|
|
|
784
906
|
const baseUrl = phantomOptions.authUrl || DEFAULT_AUTH_URL;
|
|
785
907
|
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Using auth URL", { baseUrl });
|
|
786
908
|
const params = new URLSearchParams({
|
|
787
|
-
|
|
788
|
-
parent_organization_id: phantomOptions.parentOrganizationId,
|
|
909
|
+
public_key: phantomOptions.publicKey,
|
|
789
910
|
app_id: phantomOptions.appId,
|
|
790
|
-
redirect_uri: phantomOptions.redirectUrl || (typeof window !== "undefined" ?
|
|
911
|
+
redirect_uri: phantomOptions.redirectUrl || (typeof window !== "undefined" ? this.getValidatedCurrentUrl() : ""),
|
|
791
912
|
session_id: phantomOptions.sessionId,
|
|
792
|
-
clear_previous_session: true.toString()
|
|
913
|
+
clear_previous_session: true.toString(),
|
|
914
|
+
sdk_version: "1.0.0-beta.11"
|
|
793
915
|
});
|
|
794
916
|
if (phantomOptions.provider) {
|
|
795
917
|
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
|
|
@@ -805,8 +927,7 @@ var BrowserAuthProvider = class {
|
|
|
805
927
|
params.append("authData", JSON.stringify(phantomOptions.customAuthData));
|
|
806
928
|
}
|
|
807
929
|
const authContext = {
|
|
808
|
-
|
|
809
|
-
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
930
|
+
publicKey: phantomOptions.publicKey,
|
|
810
931
|
appId: phantomOptions.appId,
|
|
811
932
|
provider: phantomOptions.provider,
|
|
812
933
|
sessionId: phantomOptions.sessionId
|
|
@@ -815,6 +936,9 @@ var BrowserAuthProvider = class {
|
|
|
815
936
|
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Stored auth context in session storage", { authContext });
|
|
816
937
|
const authUrl = `${baseUrl}?${params.toString()}`;
|
|
817
938
|
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Redirecting to Phantom Connect", { authUrl });
|
|
939
|
+
if (!authUrl.startsWith("https:") && !authUrl.startsWith("http://localhost")) {
|
|
940
|
+
throw new Error("Invalid auth URL - only HTTPS URLs are allowed for authentication");
|
|
941
|
+
}
|
|
818
942
|
window.location.href = authUrl;
|
|
819
943
|
resolve();
|
|
820
944
|
});
|
|
@@ -870,10 +994,30 @@ var BrowserAuthProvider = class {
|
|
|
870
994
|
sessionId,
|
|
871
995
|
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : void 0
|
|
872
996
|
});
|
|
997
|
+
const organizationId = this.urlParamsAccessor.getParam("organization_id");
|
|
998
|
+
const expiresInMs = this.urlParamsAccessor.getParam("expires_in_ms");
|
|
999
|
+
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Auth redirect parameters", {
|
|
1000
|
+
walletId,
|
|
1001
|
+
organizationId,
|
|
1002
|
+
sessionId,
|
|
1003
|
+
accountDerivationIndex,
|
|
1004
|
+
expiresInMs
|
|
1005
|
+
});
|
|
1006
|
+
if (!organizationId) {
|
|
1007
|
+
debug.error(DebugCategory.PHANTOM_CONNECT_AUTH, "Missing organization_id in auth response");
|
|
1008
|
+
throw new Error("Missing organization_id in auth response");
|
|
1009
|
+
}
|
|
1010
|
+
if (organizationId.startsWith("temp-")) {
|
|
1011
|
+
debug.warn(DebugCategory.PHANTOM_CONNECT_AUTH, "Received temporary organization_id, server may not be configured properly", {
|
|
1012
|
+
organizationId
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
873
1015
|
return {
|
|
874
1016
|
walletId,
|
|
1017
|
+
organizationId,
|
|
875
1018
|
userInfo: context,
|
|
876
|
-
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) :
|
|
1019
|
+
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : 0,
|
|
1020
|
+
expiresInMs: expiresInMs ? parseInt(expiresInMs) : 0
|
|
877
1021
|
};
|
|
878
1022
|
} catch (error) {
|
|
879
1023
|
sessionStorage.removeItem("phantom-auth-context");
|
|
@@ -903,7 +1047,7 @@ function parseBrowserFromUserAgent(userAgent, hasBraveAPI) {
|
|
|
903
1047
|
let name = "unknown";
|
|
904
1048
|
let version = "unknown";
|
|
905
1049
|
if (!userAgent || typeof userAgent !== "string") {
|
|
906
|
-
return { name, version };
|
|
1050
|
+
return { name, version, userAgent: "unknown" };
|
|
907
1051
|
}
|
|
908
1052
|
try {
|
|
909
1053
|
if (userAgent.includes("Edg/")) {
|
|
@@ -985,11 +1129,11 @@ function parseBrowserFromUserAgent(userAgent, hasBraveAPI) {
|
|
|
985
1129
|
}
|
|
986
1130
|
} catch (error) {
|
|
987
1131
|
}
|
|
988
|
-
return { name, version };
|
|
1132
|
+
return { name, version, userAgent };
|
|
989
1133
|
}
|
|
990
1134
|
function detectBrowser() {
|
|
991
1135
|
if (typeof window === "undefined" || !window.navigator?.userAgent) {
|
|
992
|
-
return { name: "unknown", version: "unknown" };
|
|
1136
|
+
return { name: "unknown", version: "unknown", userAgent: "unknown" };
|
|
993
1137
|
}
|
|
994
1138
|
const userAgent = window.navigator.userAgent;
|
|
995
1139
|
const hasBraveAPI = !!navigator.brave;
|
|
@@ -1004,25 +1148,70 @@ function getBrowserDisplayName() {
|
|
|
1004
1148
|
const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
1005
1149
|
return version !== "unknown" ? `${capitalizedName} ${version}` : capitalizedName;
|
|
1006
1150
|
}
|
|
1151
|
+
function isMobileDevice() {
|
|
1152
|
+
if (typeof window === "undefined" || !window.navigator?.userAgent) {
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
const userAgent = window.navigator.userAgent.toLowerCase();
|
|
1156
|
+
const mobilePatterns = [
|
|
1157
|
+
/android/,
|
|
1158
|
+
/iphone|ipad|ipod/,
|
|
1159
|
+
/blackberry/,
|
|
1160
|
+
/windows phone/,
|
|
1161
|
+
/mobile/,
|
|
1162
|
+
/tablet/,
|
|
1163
|
+
/silk/,
|
|
1164
|
+
/kindle/,
|
|
1165
|
+
/opera mini/,
|
|
1166
|
+
/opera mobi/
|
|
1167
|
+
];
|
|
1168
|
+
const isMobileUA = mobilePatterns.some((pattern) => pattern.test(userAgent));
|
|
1169
|
+
let isSmallScreen = false;
|
|
1170
|
+
try {
|
|
1171
|
+
isSmallScreen = window.screen.width <= 768 || window.screen.height <= 768;
|
|
1172
|
+
} catch (error) {
|
|
1173
|
+
isSmallScreen = false;
|
|
1174
|
+
}
|
|
1175
|
+
let isTouchDevice = false;
|
|
1176
|
+
try {
|
|
1177
|
+
isTouchDevice = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
1178
|
+
} catch (error) {
|
|
1179
|
+
isTouchDevice = false;
|
|
1180
|
+
}
|
|
1181
|
+
return isMobileUA || isSmallScreen && isTouchDevice;
|
|
1182
|
+
}
|
|
1007
1183
|
|
|
1008
1184
|
// src/providers/embedded/index.ts
|
|
1185
|
+
import { ANALYTICS_HEADERS } from "@phantom/constants";
|
|
1009
1186
|
var EmbeddedProvider = class extends CoreEmbeddedProvider {
|
|
1010
1187
|
constructor(config) {
|
|
1011
1188
|
debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
|
|
1012
1189
|
const urlParamsAccessor = new BrowserURLParamsAccessor();
|
|
1013
1190
|
const stamper = new IndexedDbStamper({
|
|
1014
|
-
dbName: `phantom-embedded-sdk-${config.
|
|
1191
|
+
dbName: `phantom-embedded-sdk-${config.appId}`,
|
|
1015
1192
|
storeName: "crypto-keys",
|
|
1016
1193
|
keyName: "signing-key"
|
|
1017
1194
|
});
|
|
1018
1195
|
const platformName = getPlatformName();
|
|
1196
|
+
const { name: browserName, version } = detectBrowser();
|
|
1019
1197
|
const platform = {
|
|
1020
1198
|
storage: new BrowserStorage(),
|
|
1021
1199
|
authProvider: new BrowserAuthProvider(urlParamsAccessor),
|
|
1022
1200
|
urlParamsAccessor,
|
|
1023
1201
|
stamper,
|
|
1024
|
-
name: platformName
|
|
1202
|
+
name: platformName,
|
|
1025
1203
|
// Use detected browser name and version for identification
|
|
1204
|
+
analyticsHeaders: {
|
|
1205
|
+
[ANALYTICS_HEADERS.SDK_TYPE]: "browser",
|
|
1206
|
+
[ANALYTICS_HEADERS.PLATFORM]: browserName,
|
|
1207
|
+
// firefox, chrome, safari, etc.
|
|
1208
|
+
[ANALYTICS_HEADERS.PLATFORM_VERSION]: version,
|
|
1209
|
+
// Full user agent for more detailed info
|
|
1210
|
+
[ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
1211
|
+
[ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
1212
|
+
[ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.11"
|
|
1213
|
+
// Replaced at build time
|
|
1214
|
+
}
|
|
1026
1215
|
};
|
|
1027
1216
|
debug.log(DebugCategory.EMBEDDED_PROVIDER, "Detected platform", { platformName });
|
|
1028
1217
|
const logger = new BrowserLogger();
|
|
@@ -1032,6 +1221,7 @@ var EmbeddedProvider = class extends CoreEmbeddedProvider {
|
|
|
1032
1221
|
};
|
|
1033
1222
|
|
|
1034
1223
|
// src/ProviderManager.ts
|
|
1224
|
+
import { DEFAULT_WALLET_API_URL, DEFAULT_EMBEDDED_WALLET_TYPE, DEFAULT_AUTH_URL as DEFAULT_AUTH_URL2 } from "@phantom/constants";
|
|
1035
1225
|
var ProviderManager = class {
|
|
1036
1226
|
// Track which providers have forwarding set up
|
|
1037
1227
|
constructor(config) {
|
|
@@ -1050,6 +1240,15 @@ var ProviderManager = class {
|
|
|
1050
1240
|
currentProviderKey: this.currentProviderKey
|
|
1051
1241
|
});
|
|
1052
1242
|
}
|
|
1243
|
+
getValidatedCurrentUrl() {
|
|
1244
|
+
if (typeof window === "undefined")
|
|
1245
|
+
return "";
|
|
1246
|
+
const currentUrl = window.location.href;
|
|
1247
|
+
if (!currentUrl.startsWith("http:") && !currentUrl.startsWith("https:")) {
|
|
1248
|
+
throw new Error("Invalid URL protocol - only HTTP/HTTPS URLs are supported");
|
|
1249
|
+
}
|
|
1250
|
+
return currentUrl;
|
|
1251
|
+
}
|
|
1053
1252
|
/**
|
|
1054
1253
|
* Switch to a different provider type
|
|
1055
1254
|
*/
|
|
@@ -1081,7 +1280,8 @@ var ProviderManager = class {
|
|
|
1081
1280
|
getCurrentProviderInfo() {
|
|
1082
1281
|
if (!this.currentProviderKey)
|
|
1083
1282
|
return null;
|
|
1084
|
-
const
|
|
1283
|
+
const parts = this.currentProviderKey.split("-");
|
|
1284
|
+
const [type, embeddedWalletType] = parts;
|
|
1085
1285
|
return {
|
|
1086
1286
|
type,
|
|
1087
1287
|
embeddedWalletType
|
|
@@ -1227,7 +1427,7 @@ var ProviderManager = class {
|
|
|
1227
1427
|
*/
|
|
1228
1428
|
setDefaultProvider() {
|
|
1229
1429
|
const defaultType = this.config.providerType || "embedded";
|
|
1230
|
-
const defaultEmbeddedType = this.config.embeddedWalletType || "
|
|
1430
|
+
const defaultEmbeddedType = this.config.embeddedWalletType || "user-wallet";
|
|
1231
1431
|
this.createProvider(defaultType, defaultEmbeddedType);
|
|
1232
1432
|
this.switchProvider(defaultType, { embeddedWalletType: defaultEmbeddedType });
|
|
1233
1433
|
}
|
|
@@ -1241,22 +1441,27 @@ var ProviderManager = class {
|
|
|
1241
1441
|
let provider;
|
|
1242
1442
|
if (type === "injected") {
|
|
1243
1443
|
provider = new InjectedProvider({
|
|
1244
|
-
|
|
1245
|
-
addressTypes: this.config.addressTypes
|
|
1444
|
+
addressTypes: this.config.addressTypes || [AddressType.solana]
|
|
1246
1445
|
});
|
|
1247
|
-
} else {
|
|
1248
|
-
if (!this.config.
|
|
1249
|
-
throw new Error("
|
|
1446
|
+
} else if (type === "embedded") {
|
|
1447
|
+
if (!this.config.appId) {
|
|
1448
|
+
throw new Error("appId is required for embedded provider");
|
|
1250
1449
|
}
|
|
1450
|
+
const apiBaseUrl = this.config.apiBaseUrl || DEFAULT_WALLET_API_URL;
|
|
1451
|
+
const authUrl = this.config.authOptions?.authUrl || DEFAULT_AUTH_URL2;
|
|
1251
1452
|
provider = new EmbeddedProvider({
|
|
1252
|
-
apiBaseUrl
|
|
1253
|
-
organizationId: this.config.appId,
|
|
1453
|
+
apiBaseUrl,
|
|
1254
1454
|
appId: this.config.appId,
|
|
1255
|
-
authOptions:
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1455
|
+
authOptions: {
|
|
1456
|
+
...this.config.authOptions || {},
|
|
1457
|
+
authUrl,
|
|
1458
|
+
redirectUrl: this.config.authOptions?.redirectUrl || this.getValidatedCurrentUrl()
|
|
1459
|
+
},
|
|
1460
|
+
embeddedWalletType: embeddedWalletType || DEFAULT_EMBEDDED_WALLET_TYPE,
|
|
1461
|
+
addressTypes: this.config.addressTypes || [AddressType.solana]
|
|
1259
1462
|
});
|
|
1463
|
+
} else {
|
|
1464
|
+
throw new Error(`Unsupported provider type: ${type}`);
|
|
1260
1465
|
}
|
|
1261
1466
|
this.providers.set(key, provider);
|
|
1262
1467
|
}
|
|
@@ -1266,8 +1471,10 @@ var ProviderManager = class {
|
|
|
1266
1471
|
getProviderKey(type, embeddedWalletType) {
|
|
1267
1472
|
if (type === "injected") {
|
|
1268
1473
|
return "injected";
|
|
1474
|
+
} else if (type === "embedded") {
|
|
1475
|
+
return `embedded-${embeddedWalletType || "app-wallet"}`;
|
|
1269
1476
|
}
|
|
1270
|
-
|
|
1477
|
+
throw new Error(`Unsupported provider type: ${type}`);
|
|
1271
1478
|
}
|
|
1272
1479
|
/**
|
|
1273
1480
|
* Save provider preference to localStorage
|
|
@@ -1328,6 +1535,7 @@ async function waitForPhantomExtension(timeoutMs = 3e3) {
|
|
|
1328
1535
|
}
|
|
1329
1536
|
|
|
1330
1537
|
// src/BrowserSDK.ts
|
|
1538
|
+
import { DEFAULT_EMBEDDED_WALLET_TYPE as DEFAULT_EMBEDDED_WALLET_TYPE2 } from "@phantom/constants";
|
|
1331
1539
|
var BrowserSDK = class {
|
|
1332
1540
|
constructor(config) {
|
|
1333
1541
|
debug.info(DebugCategory.BROWSER_SDK, "Initializing BrowserSDK", {
|
|
@@ -1339,7 +1547,7 @@ var BrowserSDK = class {
|
|
|
1339
1547
|
debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType", { providerType: config.providerType });
|
|
1340
1548
|
throw new Error(`Invalid providerType: ${config.providerType}. Must be "injected" or "embedded".`);
|
|
1341
1549
|
}
|
|
1342
|
-
const embeddedWalletType = config.embeddedWalletType ||
|
|
1550
|
+
const embeddedWalletType = config.embeddedWalletType || DEFAULT_EMBEDDED_WALLET_TYPE2;
|
|
1343
1551
|
if (config.providerType === "embedded" && !["app-wallet", "user-wallet"].includes(embeddedWalletType)) {
|
|
1344
1552
|
debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType", {
|
|
1345
1553
|
embeddedWalletType: config.embeddedWalletType
|
|
@@ -1475,7 +1683,7 @@ var BrowserSDK = class {
|
|
|
1475
1683
|
async autoConnect() {
|
|
1476
1684
|
debug.log(DebugCategory.BROWSER_SDK, "Attempting auto-connect");
|
|
1477
1685
|
const currentProvider = this.providerManager.getCurrentProvider();
|
|
1478
|
-
if (currentProvider
|
|
1686
|
+
if (currentProvider) {
|
|
1479
1687
|
await currentProvider.autoConnect();
|
|
1480
1688
|
} else {
|
|
1481
1689
|
debug.warn(DebugCategory.BROWSER_SDK, "Current provider does not support auto-connect", {
|
|
@@ -1624,8 +1832,15 @@ var BrowserSDK = class {
|
|
|
1624
1832
|
}
|
|
1625
1833
|
};
|
|
1626
1834
|
|
|
1627
|
-
// src/
|
|
1628
|
-
|
|
1835
|
+
// src/utils/deeplink.ts
|
|
1836
|
+
function getDeeplinkToPhantom(ref) {
|
|
1837
|
+
if (!window.location.href.startsWith("http:") && !window.location.href.startsWith("https:")) {
|
|
1838
|
+
throw new Error("Invalid URL protocol - only HTTP/HTTPS URLs are supported for deeplinks");
|
|
1839
|
+
}
|
|
1840
|
+
const currentUrl = encodeURIComponent(window.location.href);
|
|
1841
|
+
const refParam = ref ? `?ref=${encodeURIComponent(ref)}` : "";
|
|
1842
|
+
return `https://phantom.app/ul/browse/${currentUrl}${refParam}`;
|
|
1843
|
+
}
|
|
1629
1844
|
|
|
1630
1845
|
// src/index.ts
|
|
1631
1846
|
import { NetworkId } from "@phantom/constants";
|
|
@@ -1633,15 +1848,15 @@ import { AddressType as AddressType5 } from "@phantom/client";
|
|
|
1633
1848
|
export {
|
|
1634
1849
|
AddressType5 as AddressType,
|
|
1635
1850
|
BrowserSDK,
|
|
1636
|
-
DEFAULT_AUTH_URL,
|
|
1637
|
-
DEFAULT_WALLET_API_URL,
|
|
1638
1851
|
DebugCategory,
|
|
1639
1852
|
DebugLevel,
|
|
1640
1853
|
NetworkId,
|
|
1641
1854
|
debug,
|
|
1642
1855
|
detectBrowser,
|
|
1643
1856
|
getBrowserDisplayName,
|
|
1857
|
+
getDeeplinkToPhantom,
|
|
1644
1858
|
getPlatformName,
|
|
1859
|
+
isMobileDevice,
|
|
1645
1860
|
parseBrowserFromUserAgent,
|
|
1646
1861
|
waitForPhantomExtension
|
|
1647
1862
|
};
|