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

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
@@ -319,8 +319,9 @@ var InjectedEthereumChain = class {
319
319
  return await this.phantom.ethereum.sendTransaction(transaction);
320
320
  }
321
321
  async switchChain(chainId) {
322
- await this.phantom.ethereum.switchChain(`0x${chainId.toString(16)}`);
323
- this._chainId = `0x${chainId.toString(16)}`;
322
+ const hexChainId = typeof chainId === "string" ? chainId.toLowerCase().startsWith("0x") ? chainId : `0x${parseInt(chainId, 10).toString(16)}` : `0x${chainId.toString(16)}`;
323
+ await this.phantom.ethereum.switchChain(hexChainId);
324
+ this._chainId = hexChainId;
324
325
  this.eventEmitter.emit("chainChanged", this._chainId);
325
326
  }
326
327
  async getChainId() {
@@ -384,8 +385,8 @@ var InjectedEthereumChain = class {
384
385
  };
385
386
 
386
387
  // src/providers/injected/index.ts
387
- var MANUAL_DISCONNECT_KEY = "phantom-injected-manual-disconnect";
388
- var MANUAL_DISCONNECT_VALUE = "true";
388
+ var WAS_CONNECTED_KEY = "phantom-injected-was-connected";
389
+ var WAS_CONNECTED_VALUE = "true";
389
390
  var InjectedProvider = class {
390
391
  constructor(config) {
391
392
  this.connected = false;
@@ -421,9 +422,6 @@ var InjectedProvider = class {
421
422
  }
422
423
  debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
423
424
  }
424
- /**
425
- * Access to Solana chain operations
426
- */
427
425
  get solana() {
428
426
  if (!this.addressTypes.includes(import_client4.AddressType.solana)) {
429
427
  throw new Error("Solana not enabled for this provider");
@@ -522,10 +520,10 @@ var InjectedProvider = class {
522
520
  this.connected = true;
523
521
  const authUserId = await this.getAuthUserId("manual-connect");
524
522
  try {
525
- localStorage.removeItem(MANUAL_DISCONNECT_KEY);
526
- debug.log(DebugCategory.INJECTED_PROVIDER, "Cleared manual disconnect flag - auto-reconnect enabled");
523
+ localStorage.setItem(WAS_CONNECTED_KEY, WAS_CONNECTED_VALUE);
524
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Set was-connected flag - auto-reconnect enabled");
527
525
  } catch (error) {
528
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to clear manual disconnect flag", { error });
526
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to set was-connected flag", { error });
529
527
  }
530
528
  const result = {
531
529
  addresses: this.addresses,
@@ -558,18 +556,15 @@ var InjectedProvider = class {
558
556
  debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
559
557
  }
560
558
  }
561
- if (this.addressTypes.includes(import_client4.AddressType.ethereum)) {
562
- debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected (no-op)");
563
- }
564
559
  this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
565
560
  this.browserInjectedCleanupFunctions = [];
566
561
  this.connected = false;
567
562
  this.addresses = [];
568
563
  try {
569
- localStorage.setItem(MANUAL_DISCONNECT_KEY, MANUAL_DISCONNECT_VALUE);
570
- debug.log(DebugCategory.INJECTED_PROVIDER, "Set manual disconnect flag to prevent auto-reconnect");
564
+ localStorage.removeItem(WAS_CONNECTED_KEY);
565
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Cleared was connected flag to prevent auto-reconnect");
571
566
  } catch (error) {
572
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to set manual disconnect flag", { error });
567
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to clear was-connected flag", { error });
573
568
  }
574
569
  this.emit("disconnect", {
575
570
  source: "manual-disconnect"
@@ -577,20 +572,22 @@ var InjectedProvider = class {
577
572
  debug.info(DebugCategory.INJECTED_PROVIDER, "Injected provider disconnected successfully");
578
573
  }
579
574
  /**
580
- * Attempt auto-connection using onlyIfTrusted parameter
581
- * This will only connect if the dApp is already trusted by the user
575
+ * Attempt auto-connection if user was previously connected
576
+ * Only reconnects if the user connected before and didn't explicitly disconnect
582
577
  * Should be called after setting up event listeners
583
578
  */
584
579
  async autoConnect() {
585
- debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting auto-connect with onlyIfTrusted=true");
580
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting auto-connect");
586
581
  try {
587
- const manualDisconnect = localStorage.getItem(MANUAL_DISCONNECT_KEY);
588
- if (manualDisconnect === MANUAL_DISCONNECT_VALUE) {
589
- debug.log(DebugCategory.INJECTED_PROVIDER, "Skipping auto-connect: user previously disconnected manually");
582
+ const wasConnected = localStorage.getItem(WAS_CONNECTED_KEY);
583
+ if (wasConnected !== WAS_CONNECTED_VALUE) {
584
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Skipping auto-connect: user was not previously connected");
590
585
  return;
591
586
  }
587
+ debug.log(DebugCategory.INJECTED_PROVIDER, "User was previously connected, attempting auto-connect");
592
588
  } catch (error) {
593
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to check manual disconnect flag", { error });
589
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to check was-connected flag", { error });
590
+ return;
594
591
  }
595
592
  this.emit("connect_start", {
596
593
  source: "auto-connect",
@@ -618,7 +615,10 @@ var InjectedProvider = class {
618
615
  debug.info(DebugCategory.INJECTED_PROVIDER, "Solana auto-connected successfully", { address: publicKey });
619
616
  }
620
617
  } catch (err) {
621
- debug.log(DebugCategory.INJECTED_PROVIDER, "Solana auto-connect failed (expected if not trusted)", { error: err });
618
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Solana auto-connect failed (expected if not trusted)", {
619
+ error: err
620
+ });
621
+ throw err;
622
622
  }
623
623
  }
624
624
  if (this.addressTypes.includes(import_client4.AddressType.ethereum)) {
@@ -632,10 +632,14 @@ var InjectedProvider = class {
632
632
  address
633
633
  }))
634
634
  );
635
- debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connected successfully", { addresses: accounts });
635
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connected successfully", {
636
+ addresses: accounts
637
+ });
636
638
  }
637
639
  } catch (err) {
638
- debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connect failed (expected if not trusted)", { error: err });
640
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum auto-connect failed (expected if not trusted)", {
641
+ error: err
642
+ });
639
643
  }
640
644
  }
641
645
  if (connectedAddresses.length === 0) {
@@ -656,7 +660,10 @@ var InjectedProvider = class {
656
660
  });
657
661
  debug.info(DebugCategory.INJECTED_PROVIDER, "Auto-connect successful", {
658
662
  addressCount: connectedAddresses.length,
659
- addresses: connectedAddresses.map((addr) => ({ type: addr.addressType, address: addr.address.substring(0, 8) + "..." })),
663
+ addresses: connectedAddresses.map((addr) => ({
664
+ type: addr.addressType,
665
+ address: addr.address.substring(0, 8) + "..."
666
+ })),
660
667
  authUserId
661
668
  });
662
669
  } catch (error) {
@@ -702,14 +709,22 @@ var InjectedProvider = class {
702
709
  const userInfo = await window.phantom.app.getUser();
703
710
  const authUserId = userInfo?.authUserId;
704
711
  if (authUserId) {
705
- debug.log(DebugCategory.INJECTED_PROVIDER, `Retrieved authUserId from window.phantom.app.getUser() during ${context}`, {
706
- authUserId
707
- });
712
+ debug.log(
713
+ DebugCategory.INJECTED_PROVIDER,
714
+ `Retrieved authUserId from window.phantom.app.getUser() during ${context}`,
715
+ {
716
+ authUserId
717
+ }
718
+ );
708
719
  }
709
720
  return authUserId;
710
721
  }
711
722
  } catch (error) {
712
- debug.log(DebugCategory.INJECTED_PROVIDER, `Failed to get user info during ${context} (method may not be supported)`, { error });
723
+ debug.log(
724
+ DebugCategory.INJECTED_PROVIDER,
725
+ `Failed to get user info during ${context} (method may not be supported)`,
726
+ { error }
727
+ );
713
728
  }
714
729
  return void 0;
715
730
  }
@@ -1200,7 +1215,7 @@ var BrowserAuthProvider = class {
1200
1215
  // OAuth session management - defaults to allow refresh unless explicitly clearing after logout
1201
1216
  clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
1202
1217
  allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
1203
- sdk_version: "1.0.0-beta.20",
1218
+ sdk_version: "1.0.0-beta.22",
1204
1219
  sdk_type: "browser",
1205
1220
  platform: detectBrowser().name
1206
1221
  });
@@ -1230,7 +1245,7 @@ var BrowserAuthProvider = class {
1230
1245
  resolve();
1231
1246
  });
1232
1247
  }
1233
- resumeAuthFromRedirect() {
1248
+ resumeAuthFromRedirect(provider) {
1234
1249
  try {
1235
1250
  const walletId = this.urlParamsAccessor.getParam("wallet_id");
1236
1251
  const sessionId = this.urlParamsAccessor.getParam("session_id");
@@ -1297,16 +1312,21 @@ var BrowserAuthProvider = class {
1297
1312
  throw new Error("Missing organization_id in auth response");
1298
1313
  }
1299
1314
  if (organizationId.startsWith("temp-")) {
1300
- debug.warn(DebugCategory.PHANTOM_CONNECT_AUTH, "Received temporary organization_id, server may not be configured properly", {
1301
- organizationId
1302
- });
1315
+ debug.warn(
1316
+ DebugCategory.PHANTOM_CONNECT_AUTH,
1317
+ "Received temporary organization_id, server may not be configured properly",
1318
+ {
1319
+ organizationId
1320
+ }
1321
+ );
1303
1322
  }
1304
1323
  return {
1305
1324
  walletId,
1306
1325
  organizationId,
1307
1326
  accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : 0,
1308
1327
  expiresInMs: expiresInMs ? parseInt(expiresInMs) : 0,
1309
- authUserId: authUserId || void 0
1328
+ authUserId: authUserId || void 0,
1329
+ provider
1310
1330
  };
1311
1331
  } catch (error) {
1312
1332
  sessionStorage.removeItem("phantom-auth-context");
@@ -1459,7 +1479,7 @@ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvi
1459
1479
  // Full user agent for more detailed info
1460
1480
  [import_constants2.ANALYTICS_HEADERS.APP_ID]: config.appId,
1461
1481
  [import_constants2.ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
1462
- [import_constants2.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.20"
1482
+ [import_constants2.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.0-beta.22"
1463
1483
  // Replaced at build time
1464
1484
  }
1465
1485
  };
@@ -1471,6 +1491,7 @@ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvi
1471
1491
  };
1472
1492
 
1473
1493
  // src/ProviderManager.ts
1494
+ var import_embedded_provider_core2 = require("@phantom/embedded-provider-core");
1474
1495
  var import_constants3 = require("@phantom/constants");
1475
1496
 
1476
1497
  // src/utils/auth-callback.ts
@@ -1554,6 +1575,12 @@ var ProviderManager = class {
1554
1575
  embeddedWalletType
1555
1576
  };
1556
1577
  }
1578
+ /**
1579
+ * Check if a provider is allowed by the config
1580
+ */
1581
+ isProviderAllowed(provider) {
1582
+ return this.config.providers.includes(provider);
1583
+ }
1557
1584
  /**
1558
1585
  * Connect using the current provider
1559
1586
  * Automatically switches provider based on authOptions.provider
@@ -1561,13 +1588,18 @@ var ProviderManager = class {
1561
1588
  async connect(authOptions) {
1562
1589
  debug.info(DebugCategory.PROVIDER_MANAGER, "Starting connection", {
1563
1590
  currentProviderKey: this.currentProviderKey,
1564
- authOptions: { provider: authOptions.provider, hasJwtToken: !!authOptions.jwtToken }
1591
+ authOptions: { provider: authOptions.provider }
1565
1592
  });
1593
+ if (!this.isProviderAllowed(authOptions.provider)) {
1594
+ const error = `Provider "${authOptions.provider}" is not in the allowed providers list: ${JSON.stringify(this.config.providers)}`;
1595
+ debug.error(DebugCategory.PROVIDER_MANAGER, error);
1596
+ throw new Error(error);
1597
+ }
1566
1598
  const requestedProvider = authOptions.provider;
1567
1599
  let targetProviderType = null;
1568
1600
  if (requestedProvider === "injected") {
1569
1601
  targetProviderType = "injected";
1570
- } else if (["google", "apple", "jwt", "phantom"].includes(requestedProvider)) {
1602
+ } else if (import_embedded_provider_core2.EMBEDDED_PROVIDER_AUTH_TYPES.includes(requestedProvider)) {
1571
1603
  targetProviderType = "embedded";
1572
1604
  }
1573
1605
  if (targetProviderType) {
@@ -1591,16 +1623,14 @@ var ProviderManager = class {
1591
1623
  }
1592
1624
  debug.log(DebugCategory.PROVIDER_MANAGER, "Delegating to provider connect method");
1593
1625
  const result = await this.currentProvider.connect(authOptions);
1594
- const providerInfo = this.getCurrentProviderInfo();
1595
- result.providerType = providerInfo?.type;
1596
1626
  debug.log(DebugCategory.PROVIDER_MANAGER, "Connection successful, saving preferences", {
1597
1627
  addressCount: result.addresses?.length || 0,
1598
- providerType: result.providerType
1628
+ provider: authOptions.provider
1599
1629
  });
1600
1630
  this.saveProviderPreference();
1601
1631
  debug.info(DebugCategory.PROVIDER_MANAGER, "Connect completed", {
1602
1632
  addresses: result.addresses,
1603
- providerType: result.providerType
1633
+ provider: authOptions.provider
1604
1634
  });
1605
1635
  return result;
1606
1636
  }
@@ -1629,7 +1659,7 @@ var ProviderManager = class {
1629
1659
  }
1630
1660
  /**
1631
1661
  * Attempt auto-connect with fallback strategy
1632
- * Tries embedded provider first if it exists, then injected provider
1662
+ * Tries embedded provider first if it exists and is allowed, then injected provider if allowed
1633
1663
  * Returns true if any provider successfully connected
1634
1664
  */
1635
1665
  async autoConnect() {
@@ -1640,7 +1670,8 @@ var ProviderManager = class {
1640
1670
  }
1641
1671
  const embeddedWalletType = this.config.embeddedWalletType || "user-wallet";
1642
1672
  const embeddedKey = this.getProviderKey("embedded", embeddedWalletType);
1643
- if (this.providers.has(embeddedKey)) {
1673
+ const embeddedAllowed = this.config.providers.some((p) => p !== "injected");
1674
+ if (embeddedAllowed && this.providers.has(embeddedKey)) {
1644
1675
  debug.log(DebugCategory.PROVIDER_MANAGER, "Trying auto-connect with existing embedded provider");
1645
1676
  const embeddedProvider = this.providers.get(embeddedKey);
1646
1677
  try {
@@ -1669,8 +1700,9 @@ var ProviderManager = class {
1669
1700
  }
1670
1701
  }
1671
1702
  }
1703
+ const injectedAllowed = this.config.providers.includes("injected");
1672
1704
  const injectedKey = this.getProviderKey("injected");
1673
- if (this.providers.has(injectedKey)) {
1705
+ if (injectedAllowed && this.providers.has(injectedKey)) {
1674
1706
  debug.log(DebugCategory.PROVIDER_MANAGER, "Trying auto-connect with existing injected provider");
1675
1707
  const injectedProvider = this.providers.get(injectedKey);
1676
1708
  try {
@@ -1689,7 +1721,7 @@ var ProviderManager = class {
1689
1721
  });
1690
1722
  }
1691
1723
  }
1692
- debug.log(DebugCategory.PROVIDER_MANAGER, "Auto-connect failed for all existing providers");
1724
+ debug.log(DebugCategory.PROVIDER_MANAGER, "Auto-connect failed for all allowed providers");
1693
1725
  return false;
1694
1726
  }
1695
1727
  /**
@@ -1773,17 +1805,28 @@ var ProviderManager = class {
1773
1805
  }
1774
1806
  /**
1775
1807
  * Set default provider based on initial config
1776
- * Creates both embedded and injected providers for autoConnect fallback
1808
+ * Creates providers based on the allowed providers array
1777
1809
  */
1778
1810
  setDefaultProvider() {
1779
- const defaultType = this.config.providerType || "embedded";
1780
1811
  const defaultEmbeddedType = this.config.embeddedWalletType || "user-wallet";
1781
- if (this.config.appId) {
1782
- debug.log(DebugCategory.PROVIDER_MANAGER, "Creating embedded provider");
1812
+ const hasInjected = this.config.providers.includes("injected");
1813
+ const hasEmbedded = this.config.providers.some((p) => p !== "injected");
1814
+ if (hasInjected) {
1815
+ debug.log(DebugCategory.PROVIDER_MANAGER, "Creating injected provider (allowed by providers array)");
1816
+ this.createProvider("injected");
1817
+ }
1818
+ if (hasEmbedded) {
1819
+ debug.log(DebugCategory.PROVIDER_MANAGER, "Creating embedded provider (allowed by providers array)");
1783
1820
  this.createProvider("embedded", defaultEmbeddedType);
1784
1821
  }
1785
- debug.log(DebugCategory.PROVIDER_MANAGER, "Creating injected provider");
1786
- this.createProvider("injected");
1822
+ let defaultType;
1823
+ if (hasEmbedded && this.providers.has(`embedded-${defaultEmbeddedType}`)) {
1824
+ defaultType = "embedded";
1825
+ } else if (hasInjected && this.providers.has("injected")) {
1826
+ defaultType = "injected";
1827
+ } else {
1828
+ throw new Error("No valid providers could be created from the providers array");
1829
+ }
1787
1830
  const switchOptions = {};
1788
1831
  if (defaultType === "embedded") {
1789
1832
  switchOptions.embeddedWalletType = defaultEmbeddedType;
@@ -1876,20 +1919,39 @@ async function waitForPhantomExtension(timeoutMs = 3e3) {
1876
1919
  }
1877
1920
 
1878
1921
  // src/BrowserSDK.ts
1922
+ var import_embedded_provider_core3 = require("@phantom/embedded-provider-core");
1879
1923
  var import_constants4 = require("@phantom/constants");
1924
+ var BROWSER_SDK_PROVIDER_TYPES = [...import_embedded_provider_core3.EMBEDDED_PROVIDER_AUTH_TYPES, "injected"];
1880
1925
  var BrowserSDK = class {
1881
1926
  constructor(config) {
1882
1927
  debug.info(DebugCategory.BROWSER_SDK, "Initializing BrowserSDK", {
1883
- providerType: config.providerType,
1928
+ providers: config.providers,
1884
1929
  embeddedWalletType: config.embeddedWalletType,
1885
1930
  addressTypes: config.addressTypes
1886
1931
  });
1887
- if (!["injected", "embedded"].includes(config.providerType)) {
1888
- debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType", { providerType: config.providerType });
1889
- throw new Error(`Invalid providerType: ${config.providerType}. Must be "injected" or "embedded".`);
1932
+ if (!Array.isArray(config.providers) || config.providers.length === 0) {
1933
+ debug.error(DebugCategory.BROWSER_SDK, "Invalid providers array", { providers: config.providers });
1934
+ throw new Error("providers must be a non-empty array of AuthProviderType");
1935
+ }
1936
+ const invalidProviders = config.providers.filter((p) => !BROWSER_SDK_PROVIDER_TYPES.includes(p));
1937
+ if (invalidProviders.length > 0) {
1938
+ debug.error(DebugCategory.BROWSER_SDK, "Invalid provider types", {
1939
+ invalidProviders,
1940
+ validProviders: BROWSER_SDK_PROVIDER_TYPES
1941
+ });
1942
+ throw new Error(
1943
+ `Invalid provider type(s): ${invalidProviders.join(", ")}. Valid providers are: ${BROWSER_SDK_PROVIDER_TYPES.join(", ")}`
1944
+ );
1945
+ }
1946
+ const hasEmbeddedProviders = config.providers.some((p) => p !== "injected");
1947
+ if (hasEmbeddedProviders && !config.appId) {
1948
+ debug.error(DebugCategory.BROWSER_SDK, "appId required for embedded providers", {
1949
+ providers: config.providers
1950
+ });
1951
+ throw new Error("appId is required when using embedded providers (google, apple, phantom, etc.)");
1890
1952
  }
1891
1953
  const embeddedWalletType = config.embeddedWalletType || import_constants4.DEFAULT_EMBEDDED_WALLET_TYPE;
1892
- if (config.providerType === "embedded" && !["app-wallet", "user-wallet"].includes(embeddedWalletType)) {
1954
+ if (!["app-wallet", "user-wallet"].includes(embeddedWalletType)) {
1893
1955
  debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType", {
1894
1956
  embeddedWalletType: config.embeddedWalletType
1895
1957
  });