@phantom/browser-sdk 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,14 +17,31 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var src_exports = {};
22
32
  __export(src_exports, {
23
- AddressType: () => import_client3.AddressType,
33
+ AddressType: () => import_client2.AddressType,
24
34
  BrowserSDK: () => BrowserSDK,
25
- NetworkId: () => import_client3.NetworkId
35
+ DEFAULT_AUTH_URL: () => DEFAULT_AUTH_URL,
36
+ DEFAULT_WALLET_API_URL: () => DEFAULT_WALLET_API_URL,
37
+ DebugCategory: () => DebugCategory,
38
+ DebugLevel: () => DebugLevel,
39
+ NetworkId: () => import_constants3.NetworkId,
40
+ debug: () => debug,
41
+ detectBrowser: () => detectBrowser,
42
+ getBrowserDisplayName: () => getBrowserDisplayName,
43
+ getPlatformName: () => getPlatformName,
44
+ parseBrowserFromUserAgent: () => parseBrowserFromUserAgent
26
45
  });
27
46
  module.exports = __toCommonJS(src_exports);
28
47
 
@@ -31,26 +50,121 @@ var import_client = require("@phantom/client");
31
50
  var import_browser_injected_sdk = require("@phantom/browser-injected-sdk");
32
51
  var import_solana = require("@phantom/browser-injected-sdk/solana");
33
52
  var import_ethereum = require("@phantom/browser-injected-sdk/ethereum");
53
+
54
+ // src/debug.ts
55
+ var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
56
+ DebugLevel2[DebugLevel2["ERROR"] = 0] = "ERROR";
57
+ DebugLevel2[DebugLevel2["WARN"] = 1] = "WARN";
58
+ DebugLevel2[DebugLevel2["INFO"] = 2] = "INFO";
59
+ DebugLevel2[DebugLevel2["DEBUG"] = 3] = "DEBUG";
60
+ return DebugLevel2;
61
+ })(DebugLevel || {});
62
+ var Debug = class {
63
+ constructor() {
64
+ this.level = 0 /* ERROR */;
65
+ this.enabled = false;
66
+ }
67
+ static getInstance() {
68
+ if (!Debug.instance) {
69
+ Debug.instance = new Debug();
70
+ }
71
+ return Debug.instance;
72
+ }
73
+ setCallback(callback) {
74
+ this.callback = callback;
75
+ }
76
+ setLevel(level) {
77
+ this.level = level;
78
+ }
79
+ enable() {
80
+ this.enabled = true;
81
+ }
82
+ disable() {
83
+ this.enabled = false;
84
+ }
85
+ writeLog(level, category, message, data) {
86
+ if (!this.enabled || level > this.level) {
87
+ return;
88
+ }
89
+ const debugMessage = {
90
+ timestamp: Date.now(),
91
+ level,
92
+ category,
93
+ message,
94
+ data
95
+ };
96
+ if (this.callback) {
97
+ this.callback(debugMessage);
98
+ }
99
+ }
100
+ error(category, message, data) {
101
+ this.writeLog(0 /* ERROR */, category, message, data);
102
+ }
103
+ warn(category, message, data) {
104
+ this.writeLog(1 /* WARN */, category, message, data);
105
+ }
106
+ info(category, message, data) {
107
+ this.writeLog(2 /* INFO */, category, message, data);
108
+ }
109
+ debug(category, message, data) {
110
+ this.writeLog(3 /* DEBUG */, category, message, data);
111
+ }
112
+ log(category, message, data) {
113
+ this.writeLog(3 /* DEBUG */, category, message, data);
114
+ }
115
+ };
116
+ var debug = Debug.getInstance();
117
+ var DebugCategory = {
118
+ BROWSER_SDK: "BrowserSDK",
119
+ PROVIDER_MANAGER: "ProviderManager",
120
+ EMBEDDED_PROVIDER: "EmbeddedProvider",
121
+ INJECTED_PROVIDER: "InjectedProvider",
122
+ PHANTOM_CONNECT_AUTH: "PhantomConnectAuth",
123
+ JWT_AUTH: "JWTAuth",
124
+ STORAGE: "Storage",
125
+ SESSION: "Session"
126
+ };
127
+
128
+ // src/providers/injected/index.ts
129
+ var import_base64url = require("@phantom/base64url");
130
+ var import_constants = require("@phantom/constants");
131
+ var import_bs58 = __toESM(require("bs58"));
34
132
  var InjectedProvider = class {
35
133
  constructor(config) {
36
134
  this.connected = false;
37
135
  this.addresses = [];
136
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Initializing InjectedProvider", { config });
38
137
  this.addressTypes = config.addressTypes || [import_client.AddressType.solana, import_client.AddressType.ethereum];
138
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Address types configured", { addressTypes: this.addressTypes });
39
139
  const plugins = [(0, import_browser_injected_sdk.createExtensionPlugin)()];
40
140
  if (this.addressTypes.includes(import_client.AddressType.solana)) {
41
141
  plugins.push((0, import_solana.createSolanaPlugin)());
142
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Solana plugin added");
42
143
  }
43
144
  if (this.addressTypes.includes(import_client.AddressType.ethereum)) {
44
145
  plugins.push((0, import_ethereum.createEthereumPlugin)());
146
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
45
147
  }
148
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Creating Phantom instance with plugins", {
149
+ pluginCount: plugins.length
150
+ });
46
151
  this.phantom = (0, import_browser_injected_sdk.createPhantom)({ plugins });
152
+ debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
47
153
  }
48
- async connect() {
154
+ async connect(authOptions) {
155
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider connect", {
156
+ addressTypes: this.addressTypes,
157
+ authOptionsIgnored: !!authOptions
158
+ // Note: authOptions are ignored for injected provider
159
+ });
49
160
  if (!this.phantom.extension.isInstalled()) {
161
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Phantom wallet extension not found");
50
162
  throw new Error("Phantom wallet not found");
51
163
  }
164
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Phantom extension detected");
52
165
  const connectedAddresses = [];
53
166
  if (this.addressTypes.includes(import_client.AddressType.solana)) {
167
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
54
168
  try {
55
169
  const publicKey = await this.phantom.solana.connect();
56
170
  if (publicKey) {
@@ -58,9 +172,10 @@ var InjectedProvider = class {
58
172
  addressType: import_client.AddressType.solana,
59
173
  address: publicKey
60
174
  });
175
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
61
176
  }
62
177
  } catch (err) {
63
- console.error("Failed to connect Solana:", err);
178
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana", { error: err });
64
179
  }
65
180
  }
66
181
  if (this.addressTypes.includes(import_client.AddressType.ethereum)) {
@@ -75,7 +190,7 @@ var InjectedProvider = class {
75
190
  );
76
191
  }
77
192
  } catch (err) {
78
- console.error("Failed to connect Ethereum:", err);
193
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum", { error: err });
79
194
  }
80
195
  }
81
196
  if (connectedAddresses.length === 0) {
@@ -84,7 +199,8 @@ var InjectedProvider = class {
84
199
  this.addresses = connectedAddresses;
85
200
  this.connected = true;
86
201
  return {
87
- addresses: this.addresses
202
+ addresses: this.addresses,
203
+ status: "completed"
88
204
  // walletId is not applicable for injected providers
89
205
  };
90
206
  }
@@ -111,18 +227,24 @@ var InjectedProvider = class {
111
227
  throw new Error("Wallet not connected");
112
228
  }
113
229
  const networkPrefix = params.networkId.split(":")[0].toLowerCase();
230
+ let signatureResult;
114
231
  if (networkPrefix === "solana") {
115
232
  const { signature } = await this.phantom.solana.signMessage(new TextEncoder().encode(params.message));
116
- return Array.from(signature).map((b) => b.toString(16).padStart(2, "0")).join("");
233
+ signatureResult = import_bs58.default.encode(signature);
117
234
  } else if (networkPrefix === "ethereum" || networkPrefix === "polygon" || networkPrefix === "eip155") {
118
235
  const address = this.addresses.find((addr) => addr.addressType === import_client.AddressType.ethereum)?.address;
119
236
  if (!address) {
120
237
  throw new Error("No address available");
121
238
  }
122
239
  const signature = await this.phantom.ethereum.signPersonalMessage(params.message, address);
123
- return signature;
240
+ signatureResult = signature;
241
+ } else {
242
+ throw new Error(`Network ${params.networkId} is not supported for injected wallets`);
124
243
  }
125
- throw new Error(`Network ${params.networkId} is not supported for injected wallets`);
244
+ return {
245
+ signature: signatureResult,
246
+ rawSignature: (0, import_base64url.base64urlEncode)(signatureResult)
247
+ };
126
248
  }
127
249
  async signAndSendTransaction(params) {
128
250
  if (!this.connected) {
@@ -133,7 +255,9 @@ var InjectedProvider = class {
133
255
  const transaction = params.transaction;
134
256
  const result = await this.phantom.solana.signAndSendTransaction(transaction);
135
257
  return {
136
- rawTransaction: result.signature
258
+ hash: result.signature,
259
+ rawTransaction: (0, import_base64url.base64urlEncode)(result.signature),
260
+ blockExplorer: (0, import_constants.getExplorerUrl)(params.networkId, "transaction", result.signature)
137
261
  };
138
262
  } else if (networkPrefix === "ethereum" || networkPrefix === "polygon" || networkPrefix === "eip155") {
139
263
  const toHex = (value) => {
@@ -156,7 +280,9 @@ var InjectedProvider = class {
156
280
  };
157
281
  const txHash = await this.phantom.ethereum.sendTransaction(txRequest);
158
282
  return {
159
- rawTransaction: txHash
283
+ hash: txHash,
284
+ rawTransaction: (0, import_base64url.base64urlEncode)(txHash),
285
+ blockExplorer: (0, import_constants.getExplorerUrl)(params.networkId, "transaction", txHash)
160
286
  };
161
287
  }
162
288
  throw new Error(`Network ${params.networkId} is not supported for injected wallets`);
@@ -170,11 +296,11 @@ var InjectedProvider = class {
170
296
  };
171
297
 
172
298
  // src/providers/embedded/index.ts
173
- var import_client2 = require("@phantom/client");
174
- var import_api_key_stamper = require("@phantom/api-key-stamper");
299
+ var import_embedded_provider_core = require("@phantom/embedded-provider-core");
300
+ var import_indexed_db_stamper = require("@phantom/indexed-db-stamper");
175
301
 
176
- // src/providers/embedded/storage.ts
177
- var IndexedDBStorage = class {
302
+ // src/providers/embedded/adapters/storage.ts
303
+ var BrowserStorage = class {
178
304
  constructor() {
179
305
  this.dbName = "phantom-browser-sdk";
180
306
  this.storeName = "sessions";
@@ -194,149 +320,339 @@ var IndexedDBStorage = class {
194
320
  });
195
321
  }
196
322
  async getSession() {
323
+ debug.log(DebugCategory.STORAGE, "Getting session from IndexedDB");
197
324
  const db = await this.getDB();
198
325
  return new Promise((resolve, reject) => {
199
326
  const transaction = db.transaction([this.storeName], "readonly");
200
327
  const store = transaction.objectStore(this.storeName);
201
328
  const request = store.get("currentSession");
202
- request.onsuccess = () => resolve(request.result || null);
203
- request.onerror = () => reject(request.error);
329
+ request.onsuccess = () => {
330
+ const session = request.result || null;
331
+ debug.log(DebugCategory.STORAGE, "Retrieved session from IndexedDB", {
332
+ hasSession: !!session,
333
+ sessionId: session?.sessionId
334
+ });
335
+ resolve(session);
336
+ };
337
+ request.onerror = () => {
338
+ debug.error(DebugCategory.STORAGE, "Failed to get session from IndexedDB", { error: request.error });
339
+ reject(request.error);
340
+ };
204
341
  });
205
342
  }
206
343
  async saveSession(session) {
344
+ debug.log(DebugCategory.STORAGE, "Saving session to IndexedDB", {
345
+ sessionId: session.sessionId,
346
+ walletId: session.walletId,
347
+ status: session.status
348
+ });
207
349
  const db = await this.getDB();
208
350
  return new Promise((resolve, reject) => {
209
351
  const transaction = db.transaction([this.storeName], "readwrite");
210
352
  const store = transaction.objectStore(this.storeName);
211
353
  const request = store.put(session, "currentSession");
212
- request.onsuccess = () => resolve();
213
- request.onerror = () => reject(request.error);
354
+ request.onsuccess = () => {
355
+ debug.log(DebugCategory.STORAGE, "Successfully saved session to IndexedDB");
356
+ resolve();
357
+ };
358
+ request.onerror = () => {
359
+ debug.error(DebugCategory.STORAGE, "Failed to save session to IndexedDB", { error: request.error });
360
+ reject(request.error);
361
+ };
214
362
  });
215
363
  }
216
364
  async clearSession() {
365
+ debug.log(DebugCategory.STORAGE, "Clearing session from IndexedDB");
217
366
  const db = await this.getDB();
218
367
  return new Promise((resolve, reject) => {
219
368
  const transaction = db.transaction([this.storeName], "readwrite");
220
369
  const store = transaction.objectStore(this.storeName);
221
370
  const request = store.delete("currentSession");
222
- request.onsuccess = () => resolve();
223
- request.onerror = () => reject(request.error);
371
+ request.onsuccess = () => {
372
+ debug.log(DebugCategory.STORAGE, "Successfully cleared session from IndexedDB");
373
+ resolve();
374
+ };
375
+ request.onerror = () => {
376
+ debug.error(DebugCategory.STORAGE, "Failed to clear session from IndexedDB", { error: request.error });
377
+ reject(request.error);
378
+ };
224
379
  });
225
380
  }
226
381
  };
227
382
 
228
- // src/providers/embedded/auth.ts
229
- var IframeAuth = class {
230
- async authenticate(_options) {
231
- await new Promise((resolve) => setTimeout(resolve, 100));
232
- return {
233
- walletId: `wallet-${Date.now()}`
234
- };
383
+ // src/providers/embedded/adapters/url-params.ts
384
+ var BrowserURLParamsAccessor = class {
385
+ getParam(key) {
386
+ const urlParams = new URLSearchParams(window.location.search);
387
+ return urlParams.get(key);
235
388
  }
236
389
  };
390
+ var browserUrlParamsAccessor = new BrowserURLParamsAccessor();
237
391
 
238
- // src/providers/embedded/index.ts
239
- var import_parsers = require("@phantom/parsers");
240
- var EmbeddedProvider = class {
241
- constructor(config) {
242
- this.client = null;
243
- this.walletId = null;
244
- this.addresses = [];
245
- this.config = config;
246
- this.storage = new IndexedDBStorage();
247
- config.solanaProvider;
248
- }
249
- async connect() {
250
- let session = await this.storage.getSession();
251
- if (!session) {
252
- const keypair = (0, import_client2.generateKeyPair)();
253
- const stamper2 = new import_api_key_stamper.ApiKeyStamper({
254
- apiSecretKey: keypair.secretKey
392
+ // src/constants.ts
393
+ var DEFAULT_AUTH_URL = "https://connect.phantom.app";
394
+ var DEFAULT_WALLET_API_URL = "https://api.phantom.app/v1/wallets";
395
+
396
+ // src/providers/embedded/adapters/auth.ts
397
+ var BrowserAuthProvider = class {
398
+ constructor(urlParamsAccessor) {
399
+ this.urlParamsAccessor = urlParamsAccessor;
400
+ }
401
+ authenticate(options) {
402
+ return new Promise((resolve) => {
403
+ if ("jwtToken" in options) {
404
+ throw new Error("JWT authentication should be handled by the core JWTAuth class");
405
+ }
406
+ const phantomOptions = options;
407
+ debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Starting Phantom Connect authentication", {
408
+ organizationId: phantomOptions.organizationId,
409
+ parentOrganizationId: phantomOptions.parentOrganizationId,
410
+ provider: phantomOptions.provider,
411
+ authUrl: phantomOptions.authUrl,
412
+ hasCustomData: !!phantomOptions.customAuthData
255
413
  });
256
- const tempClient = new import_client2.PhantomClient(
257
- {
258
- apiBaseUrl: this.config.apiBaseUrl
259
- },
260
- stamper2
261
- );
262
- const uid = Date.now();
263
- const organizationName = `${this.config.organizationId}-${uid}`;
264
- const { organizationId } = await tempClient.createOrganization(organizationName, keypair);
265
- let walletId;
266
- if (this.config.embeddedWalletType === "user-wallet") {
267
- const auth = new IframeAuth();
268
- const authResult = await auth.authenticate({
269
- iframeUrl: this.config.authUrl || "https://auth-flow.phantom.app",
270
- organizationId,
271
- parentOrganizationId: this.config.organizationId,
272
- embeddedWalletType: this.config.embeddedWalletType
414
+ const baseUrl = phantomOptions.authUrl || DEFAULT_AUTH_URL;
415
+ debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Using auth URL", { baseUrl });
416
+ const params = new URLSearchParams({
417
+ organization_id: phantomOptions.organizationId,
418
+ parent_organization_id: phantomOptions.parentOrganizationId,
419
+ redirect_uri: phantomOptions.redirectUrl || (typeof window !== "undefined" ? window.location.href : ""),
420
+ session_id: phantomOptions.sessionId,
421
+ clear_previous_session: true.toString()
422
+ });
423
+ if (phantomOptions.provider) {
424
+ debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
425
+ provider: phantomOptions.provider
273
426
  });
274
- walletId = authResult.walletId;
427
+ params.append("provider", phantomOptions.provider);
275
428
  } else {
276
- const wallet = await tempClient.createWallet(`Wallet ${Date.now()}`);
277
- walletId = wallet.walletId;
429
+ debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "No provider specified, defaulting to Google");
430
+ params.append("provider", "google");
431
+ }
432
+ if (phantomOptions.customAuthData) {
433
+ debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Adding custom auth data");
434
+ params.append("authData", JSON.stringify(phantomOptions.customAuthData));
435
+ }
436
+ const authContext = {
437
+ organizationId: phantomOptions.organizationId,
438
+ parentOrganizationId: phantomOptions.parentOrganizationId,
439
+ provider: phantomOptions.provider,
440
+ sessionId: phantomOptions.sessionId
441
+ };
442
+ sessionStorage.setItem("phantom-auth-context", JSON.stringify(authContext));
443
+ debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Stored auth context in session storage", { authContext });
444
+ const authUrl = `${baseUrl}?${params.toString()}`;
445
+ debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Redirecting to Phantom Connect", { authUrl });
446
+ window.location.href = authUrl;
447
+ resolve();
448
+ });
449
+ }
450
+ resumeAuthFromRedirect() {
451
+ try {
452
+ const walletId = this.urlParamsAccessor.getParam("wallet_id");
453
+ const sessionId = this.urlParamsAccessor.getParam("session_id");
454
+ const error = this.urlParamsAccessor.getParam("error");
455
+ const errorDescription = this.urlParamsAccessor.getParam("error_description");
456
+ if (error) {
457
+ const errorMsg = errorDescription || error;
458
+ switch (error) {
459
+ case "access_denied":
460
+ throw new Error(`Authentication cancelled: ${errorMsg}`);
461
+ case "invalid_request":
462
+ throw new Error(`Invalid authentication request: ${errorMsg}`);
463
+ case "server_error":
464
+ throw new Error(`Authentication server error: ${errorMsg}`);
465
+ case "temporarily_unavailable":
466
+ throw new Error(`Authentication service temporarily unavailable: ${errorMsg}`);
467
+ default:
468
+ throw new Error(`Authentication failed: ${errorMsg}`);
469
+ }
278
470
  }
279
- session = {
471
+ if (!walletId || !sessionId) {
472
+ debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Missing auth parameters in URL", {
473
+ hasWalletId: !!walletId,
474
+ hasSessionId: !!sessionId
475
+ });
476
+ return null;
477
+ }
478
+ const contextStr = sessionStorage.getItem("phantom-auth-context");
479
+ let context = {};
480
+ if (contextStr) {
481
+ try {
482
+ context = JSON.parse(contextStr);
483
+ } catch (parseError) {
484
+ debug.warn(DebugCategory.PHANTOM_CONNECT_AUTH, "Failed to parse stored auth context", { error: parseError });
485
+ }
486
+ }
487
+ if (context.sessionId && sessionId !== context.sessionId) {
488
+ debug.error(DebugCategory.PHANTOM_CONNECT_AUTH, "Session ID mismatch", {
489
+ urlSessionId: sessionId,
490
+ storedSessionId: context.sessionId
491
+ });
492
+ throw new Error("Session ID mismatch - possible session corruption or replay attack");
493
+ }
494
+ sessionStorage.removeItem("phantom-auth-context");
495
+ debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Successfully resumed auth from redirect", {
280
496
  walletId,
281
- organizationId: this.config.organizationId,
282
- keypair
497
+ sessionId
498
+ });
499
+ return {
500
+ walletId,
501
+ userInfo: context
283
502
  };
284
- await this.storage.saveSession(session);
503
+ } catch (error) {
504
+ sessionStorage.removeItem("phantom-auth-context");
505
+ throw error;
285
506
  }
286
- const stamper = new import_api_key_stamper.ApiKeyStamper({
287
- apiSecretKey: session.keypair.secretKey
288
- });
289
- this.client = new import_client2.PhantomClient(
290
- {
291
- apiBaseUrl: this.config.apiBaseUrl,
292
- organizationId: session.organizationId
293
- },
294
- stamper
295
- );
296
- this.walletId = session.walletId;
297
- const addresses = await this.client.getWalletAddresses(session.walletId);
298
- this.addresses = addresses.filter((addr) => this.config.addressTypes.some((type) => type === addr.addressType)).map((addr) => ({
299
- addressType: addr.addressType,
300
- address: addr.address
301
- }));
302
- return {
303
- walletId: this.walletId,
304
- addresses: this.addresses
305
- };
306
507
  }
307
- async disconnect() {
308
- await this.storage.clearSession();
309
- this.client = null;
310
- this.walletId = null;
311
- this.addresses = [];
508
+ };
509
+
510
+ // src/providers/embedded/adapters/logger.ts
511
+ var BrowserLogger = class {
512
+ info(category, message, data) {
513
+ debug.info(category, message, data);
312
514
  }
313
- async signMessage(params) {
314
- if (!this.client || !this.walletId) {
315
- throw new Error("Not connected");
316
- }
317
- const parsedMessage = (0, import_parsers.parseMessage)(params.message);
318
- return await this.client.signMessage({
319
- walletId: this.walletId,
320
- message: parsedMessage.base64url,
321
- networkId: params.networkId
322
- });
515
+ warn(category, message, data) {
516
+ debug.warn(category, message, data);
323
517
  }
324
- async signAndSendTransaction(params) {
325
- if (!this.client || !this.walletId) {
326
- throw new Error("Not connected");
518
+ error(category, message, data) {
519
+ debug.error(category, message, data);
520
+ }
521
+ log(category, message, data) {
522
+ debug.log(category, message, data);
523
+ }
524
+ };
525
+
526
+ // src/utils/browser-detection.ts
527
+ function parseBrowserFromUserAgent(userAgent, hasBraveAPI) {
528
+ let name = "unknown";
529
+ let version = "unknown";
530
+ if (!userAgent || typeof userAgent !== "string") {
531
+ return { name, version };
532
+ }
533
+ try {
534
+ if (userAgent.includes("Edg/")) {
535
+ name = "edge";
536
+ const match = userAgent.match(/Edg\/([0-9]+(?:\.[0-9]+)*)/);
537
+ if (match)
538
+ version = match[1].split(".")[0];
539
+ } else if (userAgent.includes("OPR/") || userAgent.includes("Opera/")) {
540
+ name = "opera";
541
+ const match = userAgent.match(/(?:OPR|Opera)\/([0-9]+(?:\.[0-9]+)*)/);
542
+ if (match)
543
+ version = match[1].split(".")[0];
544
+ } else if (userAgent.includes("SamsungBrowser/")) {
545
+ name = "samsung";
546
+ const match = userAgent.match(/SamsungBrowser\/([0-9]+(?:\.[0-9]+)*)/);
547
+ if (match)
548
+ version = match[1].split(".")[0];
549
+ } else if (userAgent.includes("DuckDuckGo/")) {
550
+ name = "duckduckgo";
551
+ const match = userAgent.match(/DuckDuckGo\/([0-9]+(?:\.[0-9]+)*)/);
552
+ if (match)
553
+ version = match[1].split(".")[0];
554
+ } else if (userAgent.includes("Chrome/") && hasBraveAPI) {
555
+ name = "brave";
556
+ const match = userAgent.match(/Chrome\/([0-9]+(?:\.[0-9]+)*)/);
557
+ if (match)
558
+ version = match[1].split(".")[0];
559
+ } else if (userAgent.includes("Mobile/") || userAgent.includes("Android")) {
560
+ if (userAgent.includes("Chrome/")) {
561
+ name = "chrome-mobile";
562
+ const match = userAgent.match(/Chrome\/([0-9]+(?:\.[0-9]+)*)/);
563
+ if (match)
564
+ version = match[1].split(".")[0];
565
+ } else if (userAgent.includes("Firefox/")) {
566
+ name = "firefox-mobile";
567
+ const match = userAgent.match(/Firefox\/([0-9]+(?:\.[0-9]+)*)/);
568
+ if (match)
569
+ version = match[1].split(".")[0];
570
+ } else if (userAgent.includes("Safari/") && userAgent.includes("Mobile/")) {
571
+ name = "safari-mobile";
572
+ const match = userAgent.match(/Version\/([0-9]+(?:\.[0-9]+)*)/);
573
+ if (match)
574
+ version = match[1].split(".")[0];
575
+ } else {
576
+ name = "mobile";
577
+ }
578
+ } else if (userAgent.includes("Chrome/")) {
579
+ name = "chrome";
580
+ const match = userAgent.match(/Chrome\/([0-9]+(?:\.[0-9]+)*)/);
581
+ if (match)
582
+ version = match[1].split(".")[0];
583
+ } else if (userAgent.includes("Firefox/")) {
584
+ name = "firefox";
585
+ const match = userAgent.match(/Firefox\/([0-9]+(?:\.[0-9]+)*)/);
586
+ if (match)
587
+ version = match[1].split(".")[0];
588
+ } else if (userAgent.includes("Safari/") && !userAgent.includes("Chrome/")) {
589
+ name = "safari";
590
+ const match = userAgent.match(/Version\/([0-9]+(?:\.[0-9]+)*)/);
591
+ if (match)
592
+ version = match[1].split(".")[0];
327
593
  }
328
- const parsedTransaction = await (0, import_parsers.parseTransaction)(params.transaction, params.networkId);
329
- return await this.client.signAndSendTransaction({
330
- walletId: this.walletId,
331
- transaction: parsedTransaction.base64url,
332
- networkId: params.networkId
333
- });
594
+ if (name === "unknown") {
595
+ const patterns = [
596
+ { regex: /Chrome\/([0-9]+)/, name: "chrome" },
597
+ { regex: /Firefox\/([0-9]+)/, name: "firefox" },
598
+ { regex: /Safari\/([0-9]+)/, name: "safari" },
599
+ { regex: /Edge\/([0-9]+)/, name: "edge" },
600
+ { regex: /Opera\/([0-9]+)/, name: "opera" }
601
+ ];
602
+ for (const pattern of patterns) {
603
+ const match = userAgent.match(pattern.regex);
604
+ if (match) {
605
+ name = pattern.name;
606
+ version = match[1];
607
+ break;
608
+ }
609
+ }
610
+ }
611
+ } catch (error) {
334
612
  }
335
- getAddresses() {
336
- return this.addresses;
613
+ return { name, version };
614
+ }
615
+ function detectBrowser() {
616
+ if (typeof window === "undefined" || !window.navigator?.userAgent) {
617
+ return { name: "unknown", version: "unknown" };
337
618
  }
338
- isConnected() {
339
- return this.client !== null && this.walletId !== null;
619
+ const userAgent = window.navigator.userAgent;
620
+ const hasBraveAPI = !!navigator.brave;
621
+ return parseBrowserFromUserAgent(userAgent, hasBraveAPI);
622
+ }
623
+ function getPlatformName() {
624
+ const { name, version } = detectBrowser();
625
+ return version !== "unknown" ? `${name}-v${version}` : name;
626
+ }
627
+ function getBrowserDisplayName() {
628
+ const { name, version } = detectBrowser();
629
+ const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
630
+ return version !== "unknown" ? `${capitalizedName} ${version}` : capitalizedName;
631
+ }
632
+
633
+ // src/providers/embedded/index.ts
634
+ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvider {
635
+ constructor(config) {
636
+ debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
637
+ const urlParamsAccessor = new BrowserURLParamsAccessor();
638
+ const stamper = new import_indexed_db_stamper.IndexedDbStamper({
639
+ dbName: `phantom-embedded-sdk-${config.organizationId}`,
640
+ storeName: "crypto-keys",
641
+ keyName: "signing-key"
642
+ });
643
+ const platformName = getPlatformName();
644
+ const platform = {
645
+ storage: new BrowserStorage(),
646
+ authProvider: new BrowserAuthProvider(urlParamsAccessor),
647
+ urlParamsAccessor,
648
+ stamper,
649
+ name: platformName
650
+ // Use detected browser name and version for identification
651
+ };
652
+ debug.log(DebugCategory.EMBEDDED_PROVIDER, "Detected platform", { platformName });
653
+ const logger = new BrowserLogger();
654
+ super(config, platform, logger);
655
+ debug.info(DebugCategory.EMBEDDED_PROVIDER, "Browser EmbeddedProvider initialized");
340
656
  }
341
657
  };
342
658
 
@@ -347,8 +663,13 @@ var ProviderManager = class {
347
663
  this.currentProvider = null;
348
664
  this.currentProviderKey = null;
349
665
  this.walletId = null;
666
+ debug.log(DebugCategory.PROVIDER_MANAGER, "Initializing ProviderManager", { config });
350
667
  this.config = config;
668
+ debug.log(DebugCategory.PROVIDER_MANAGER, "Setting default provider");
351
669
  this.setDefaultProvider();
670
+ debug.info(DebugCategory.PROVIDER_MANAGER, "ProviderManager initialized", {
671
+ currentProviderKey: this.currentProviderKey
672
+ });
352
673
  }
353
674
  /**
354
675
  * Switch to a different provider type
@@ -389,13 +710,27 @@ var ProviderManager = class {
389
710
  /**
390
711
  * Connect using the current provider
391
712
  */
392
- async connect() {
713
+ async connect(authOptions) {
714
+ debug.info(DebugCategory.PROVIDER_MANAGER, "Starting connection", {
715
+ currentProviderKey: this.currentProviderKey,
716
+ authOptions: authOptions ? { provider: authOptions.provider, hasJwtToken: !!authOptions.jwtToken } : void 0
717
+ });
393
718
  if (!this.currentProvider) {
719
+ debug.error(DebugCategory.PROVIDER_MANAGER, "No provider selected");
394
720
  throw new Error("No provider selected");
395
721
  }
396
- const result = await this.currentProvider.connect();
722
+ debug.log(DebugCategory.PROVIDER_MANAGER, "Delegating to provider connect method");
723
+ const result = await this.currentProvider.connect(authOptions);
397
724
  this.walletId = result.walletId || null;
725
+ debug.log(DebugCategory.PROVIDER_MANAGER, "Connection successful, saving preferences", {
726
+ walletId: this.walletId,
727
+ addressCount: result.addresses?.length || 0
728
+ });
398
729
  this.saveProviderPreference();
730
+ debug.info(DebugCategory.PROVIDER_MANAGER, "Connect completed", {
731
+ walletId: this.walletId,
732
+ addresses: result.addresses
733
+ });
399
734
  return result;
400
735
  }
401
736
  /**
@@ -475,7 +810,7 @@ var ProviderManager = class {
475
810
  provider = new EmbeddedProvider({
476
811
  apiBaseUrl: this.config.apiBaseUrl,
477
812
  organizationId: this.config.organizationId,
478
- authUrl: this.config.authUrl,
813
+ authOptions: this.config.authOptions,
479
814
  embeddedWalletType: embeddedWalletType || "app-wallet",
480
815
  addressTypes: this.config.addressTypes || [],
481
816
  solanaProvider: this.config.solanaProvider || "web3js"
@@ -529,37 +864,78 @@ var ProviderManager = class {
529
864
  var import_browser_injected_sdk2 = require("@phantom/browser-injected-sdk");
530
865
  var BrowserSDK = class {
531
866
  constructor(config) {
867
+ if (config.debug?.enabled) {
868
+ debug.enable();
869
+ if (config.debug.level !== void 0) {
870
+ debug.setLevel(config.debug.level);
871
+ }
872
+ if (config.debug.callback) {
873
+ debug.setCallback(config.debug.callback);
874
+ }
875
+ }
876
+ debug.info(DebugCategory.BROWSER_SDK, "Initializing BrowserSDK", {
877
+ providerType: config.providerType,
878
+ embeddedWalletType: config.embeddedWalletType,
879
+ addressTypes: config.addressTypes,
880
+ debugEnabled: config.debug?.enabled
881
+ });
532
882
  if (!["injected", "embedded"].includes(config.providerType)) {
883
+ debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType", { providerType: config.providerType });
533
884
  throw new Error(`Invalid providerType: ${config.providerType}. Must be "injected" or "embedded".`);
534
885
  }
535
886
  const embeddedWalletType = config.embeddedWalletType || "app-wallet";
536
887
  if (config.providerType === "embedded" && !["app-wallet", "user-wallet"].includes(embeddedWalletType)) {
888
+ debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType", {
889
+ embeddedWalletType: config.embeddedWalletType
890
+ });
537
891
  throw new Error(
538
892
  `Invalid embeddedWalletType: ${config.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
539
893
  );
540
894
  }
541
895
  config.embeddedWalletType = embeddedWalletType;
542
896
  this.config = config;
897
+ debug.log(DebugCategory.BROWSER_SDK, "Creating ProviderManager", { config });
543
898
  this.providerManager = new ProviderManager(config);
899
+ debug.info(DebugCategory.BROWSER_SDK, "BrowserSDK initialized successfully");
544
900
  }
545
901
  /**
546
902
  * Connect to the wallet with optional provider switching
547
903
  */
548
904
  async connect(options) {
905
+ debug.info(DebugCategory.BROWSER_SDK, "Starting connect process", { options });
549
906
  if (options?.providerType) {
907
+ debug.log(DebugCategory.BROWSER_SDK, "Provider switch requested", {
908
+ providerType: options.providerType,
909
+ embeddedWalletType: options.embeddedWalletType
910
+ });
550
911
  if (!["injected", "embedded"].includes(options.providerType)) {
912
+ debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType in connect options", {
913
+ providerType: options.providerType
914
+ });
551
915
  throw new Error(`Invalid providerType: ${options.providerType}. Must be "injected" or "embedded".`);
552
916
  }
553
917
  if (options.embeddedWalletType && !["app-wallet", "user-wallet"].includes(options.embeddedWalletType)) {
918
+ debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType in connect options", {
919
+ embeddedWalletType: options.embeddedWalletType
920
+ });
554
921
  throw new Error(
555
922
  `Invalid embeddedWalletType: ${options.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
556
923
  );
557
924
  }
925
+ debug.log(DebugCategory.BROWSER_SDK, "Switching provider", {
926
+ providerType: options.providerType,
927
+ embeddedWalletType: options.embeddedWalletType
928
+ });
558
929
  await this.providerManager.switchProvider(options.providerType, {
559
930
  embeddedWalletType: options.embeddedWalletType
560
931
  });
561
932
  }
562
- return this.providerManager.connect();
933
+ debug.log(DebugCategory.BROWSER_SDK, "Delegating to ProviderManager.connect", {
934
+ authOptions: options?.authOptions
935
+ });
936
+ const result = await this.providerManager.connect(options?.authOptions);
937
+ debug.info(DebugCategory.BROWSER_SDK, "Connect completed successfully", result);
938
+ return result;
563
939
  }
564
940
  /**
565
941
  * Switch to a different provider type
@@ -610,7 +986,17 @@ var BrowserSDK = class {
610
986
  * @returns Signature string
611
987
  */
612
988
  async signMessage(params) {
613
- return this.providerManager.signMessage(params);
989
+ debug.info(DebugCategory.BROWSER_SDK, "Signing message", {
990
+ message: params.message,
991
+ networkId: params.networkId
992
+ });
993
+ const result = await this.providerManager.signMessage(params);
994
+ debug.info(DebugCategory.BROWSER_SDK, "Message signed successfully", {
995
+ message: params.message,
996
+ networkId: params.networkId,
997
+ result
998
+ });
999
+ return result;
614
1000
  }
615
1001
  /**
616
1002
  * Sign and send a transaction
@@ -618,7 +1004,15 @@ var BrowserSDK = class {
618
1004
  * @returns Transaction result
619
1005
  */
620
1006
  async signAndSendTransaction(params) {
621
- return this.providerManager.signAndSendTransaction(params);
1007
+ debug.info(DebugCategory.BROWSER_SDK, "Signing and sending transaction", {
1008
+ networkId: params.networkId
1009
+ });
1010
+ const result = await this.providerManager.signAndSendTransaction(params);
1011
+ debug.info(DebugCategory.BROWSER_SDK, "Transaction signed and sent successfully", {
1012
+ networkId: params.networkId,
1013
+ result
1014
+ });
1015
+ return result;
622
1016
  }
623
1017
  /**
624
1018
  * Get wallet addresses
@@ -667,4 +1061,5 @@ var BrowserSDK = class {
667
1061
  };
668
1062
 
669
1063
  // src/index.ts
670
- var import_client3 = require("@phantom/client");
1064
+ var import_constants3 = require("@phantom/constants");
1065
+ var import_client2 = require("@phantom/client");