@bounded-sh/client 0.0.2 → 0.0.4

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.
Files changed (57) hide show
  1. package/dist/hooks/useQuery.d.ts +58 -0
  2. package/dist/{index-BL-0ZKBl.js → index-BBLnBZjY.js} +234 -46
  3. package/dist/index-BBLnBZjY.js.map +1 -0
  4. package/dist/{index-CqoP9udN.js → index-BMrN-6oK.js} +1202 -450
  5. package/dist/index-BMrN-6oK.js.map +1 -0
  6. package/dist/{index-B2ytfYTB.esm.js → index-D5Ut2JU7.esm.js} +1202 -450
  7. package/dist/index-D5Ut2JU7.esm.js.map +1 -0
  8. package/dist/{index-BFOmV3Pb.esm.js → index-DkWfblRJ.esm.js} +1202 -450
  9. package/dist/index-DkWfblRJ.esm.js.map +1 -0
  10. package/dist/{index-BgAygrhE.js → index-FYyc3l_y.js} +1202 -450
  11. package/dist/index-FYyc3l_y.js.map +1 -0
  12. package/dist/{index-D986s6w7.esm.js → index-n4fG6EZJ.esm.js} +229 -46
  13. package/dist/index-n4fG6EZJ.esm.js.map +1 -0
  14. package/dist/{index.browser-D2xm-q6N.esm.js → index.browser-CCWEiCH-.esm.js} +766 -773
  15. package/dist/index.browser-CCWEiCH-.esm.js.map +1 -0
  16. package/dist/{index.browser-Bd0GwRur.esm.js → index.browser-C_TToxuO.esm.js} +230 -242
  17. package/dist/index.browser-C_TToxuO.esm.js.map +1 -0
  18. package/dist/{index.browser-D8u31irV.js → index.browser-D5evrolK.js} +766 -773
  19. package/dist/index.browser-D5evrolK.js.map +1 -0
  20. package/dist/{index.browser-BeM1bzpe.js → index.browser-DcHalmEf.js} +230 -242
  21. package/dist/index.browser-DcHalmEf.js.map +1 -0
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.esm.js +1 -1
  24. package/dist/index.js +6 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/{index.native-B-cLm_BI.esm.js → index.native-D5q2RUeV.esm.js} +162 -39
  27. package/dist/index.native-D5q2RUeV.esm.js.map +1 -0
  28. package/dist/{index.native-NgHStPq0.js → index.native-D82ofFXB.js} +166 -39
  29. package/dist/index.native-D82ofFXB.js.map +1 -0
  30. package/dist/index.native.esm.js +1 -1
  31. package/dist/index.native.js +5 -1
  32. package/dist/index.native.js.map +1 -1
  33. package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js → phantom-wallet-provider-C8DNu92D.esm.js} +3 -3
  34. package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js.map → phantom-wallet-provider-C8DNu92D.esm.js.map} +1 -1
  35. package/dist/{phantom-wallet-provider-Dy48LSdU.js → phantom-wallet-provider-CoL7g8Sr.js} +3 -3
  36. package/dist/{phantom-wallet-provider-Dy48LSdU.js.map → phantom-wallet-provider-CoL7g8Sr.js.map} +1 -1
  37. package/dist/{privy-wallet-provider-CiKtBJ5M.js → privy-wallet-provider-CV1mU4KR.js} +4 -4
  38. package/dist/{privy-wallet-provider-CiKtBJ5M.js.map → privy-wallet-provider-CV1mU4KR.js.map} +1 -1
  39. package/dist/{privy-wallet-provider-BDsrUpk4.esm.js → privy-wallet-provider-De3mfJYo.esm.js} +4 -4
  40. package/dist/{privy-wallet-provider-BDsrUpk4.esm.js.map → privy-wallet-provider-De3mfJYo.esm.js.map} +1 -1
  41. package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js → solana-mobile-wallet-provider-CLCvi-08.esm.js} +5 -5
  42. package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js.map → solana-mobile-wallet-provider-CLCvi-08.esm.js.map} +1 -1
  43. package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js → solana-mobile-wallet-provider-D9dPbk__.js} +5 -5
  44. package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js.map → solana-mobile-wallet-provider-D9dPbk__.js.map} +1 -1
  45. package/package.json +2 -2
  46. package/dist/index-B2ytfYTB.esm.js.map +0 -1
  47. package/dist/index-BFOmV3Pb.esm.js.map +0 -1
  48. package/dist/index-BL-0ZKBl.js.map +0 -1
  49. package/dist/index-BgAygrhE.js.map +0 -1
  50. package/dist/index-CqoP9udN.js.map +0 -1
  51. package/dist/index-D986s6w7.esm.js.map +0 -1
  52. package/dist/index.browser-Bd0GwRur.esm.js.map +0 -1
  53. package/dist/index.browser-BeM1bzpe.js.map +0 -1
  54. package/dist/index.browser-D2xm-q6N.esm.js.map +0 -1
  55. package/dist/index.browser-D8u31irV.js.map +0 -1
  56. package/dist/index.native-B-cLm_BI.esm.js.map +0 -1
  57. package/dist/index.native-NgHStPq0.js.map +0 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  var React = require('react');
4
4
  var axios = require('axios');
5
- var index_native = require('./index.native-NgHStPq0.js');
5
+ var index_native = require('./index.native-D82ofFXB.js');
6
6
  var web3_js = require('@solana/web3.js');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  require('@coral-xyz/anchor');
@@ -509,6 +509,50 @@ var GetAccountsMethodEnum;
509
509
  GetAccountsMethodEnum["getAccounts"] = "getAccounts";
510
510
  })(GetAccountsMethodEnum || (GetAccountsMethodEnum = {}));
511
511
 
512
+ /* tslint:disable */
513
+ /* eslint-disable */
514
+ /**
515
+ * kms-api
516
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
517
+ *
518
+ * The version of the OpenAPI document: 0.1.0
519
+ *
520
+ *
521
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
522
+ * https://openapi-generator.tech
523
+ * Do not edit the class manually.
524
+ */
525
+ /**
526
+ * @export
527
+ * @enum {string}
528
+ */
529
+ var GetOrCreatePhantomOrganizationMethodEnum;
530
+ (function (GetOrCreatePhantomOrganizationMethodEnum) {
531
+ GetOrCreatePhantomOrganizationMethodEnum["getOrCreatePhantomOrganization"] = "getOrCreatePhantomOrganization";
532
+ })(GetOrCreatePhantomOrganizationMethodEnum || (GetOrCreatePhantomOrganizationMethodEnum = {}));
533
+
534
+ /* tslint:disable */
535
+ /* eslint-disable */
536
+ /**
537
+ * kms-api
538
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
539
+ *
540
+ * The version of the OpenAPI document: 0.1.0
541
+ *
542
+ *
543
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
544
+ * https://openapi-generator.tech
545
+ * Do not edit the class manually.
546
+ */
547
+ /**
548
+ * @export
549
+ * @enum {string}
550
+ */
551
+ var GetOrganizationWalletsMethodEnum;
552
+ (function (GetOrganizationWalletsMethodEnum) {
553
+ GetOrganizationWalletsMethodEnum["getOrganizationWallets"] = "getOrganizationWallets";
554
+ })(GetOrganizationWalletsMethodEnum || (GetOrganizationWalletsMethodEnum = {}));
555
+
512
556
  /* tslint:disable */
513
557
  /* eslint-disable */
514
558
  /**
@@ -597,6 +641,13 @@ var UserPolicyOneOfTypeEnum;
597
641
  UserPolicyOneOfTypeEnum["root"] = "ROOT";
598
642
  })(UserPolicyOneOfTypeEnum || (UserPolicyOneOfTypeEnum = {}));
599
643
 
644
+ // src/auth2.ts
645
+ var TOKEN_REFRESH_BUFFER_MS = 15 * 60 * 1e3;
646
+ var DEFAULT_AUTHENTICATOR_ALGORITHM = Algorithm.ed25519;
647
+
648
+ // src/icons.ts
649
+ var PHANTOM_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTA4IiBoZWlnaHQ9IjEwOCIgdmlld0JveD0iMCAwIDEwOCAxMDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMDgiIGhlaWdodD0iMTA4IiByeD0iMjYiIGZpbGw9IiNBQjlGRjIiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00Ni41MjY3IDY5LjkyMjlDNDIuMDA1NCA3Ni44NTA5IDM0LjQyOTIgODUuNjE4MiAyNC4zNDggODUuNjE4MkMxOS41ODI0IDg1LjYxODIgMTUgODMuNjU2MyAxNSA3NS4xMzQyQzE1IDUzLjQzMDUgNDQuNjMyNiAxOS44MzI3IDcyLjEyNjggMTkuODMyN0M4Ny43NjggMTkuODMyNyA5NCAzMC42ODQ2IDk0IDQzLjAwNzlDOTQgNTguODI1OCA4My43MzU1IDc2LjkxMjIgNzMuNTMyMSA3Ni45MTIyQzcwLjI5MzkgNzYuOTEyMiA2OC43MDUzIDc1LjEzNDIgNjguNzA1MyA3Mi4zMTRDNjguNzA1MyA3MS41NzgzIDY4LjgyNzUgNzAuNzgxMiA2OS4wNzE5IDY5LjkyMjlDNjUuNTg5MyA3NS44Njk5IDU4Ljg2ODUgODEuMzg3OCA1Mi41NzU0IDgxLjM4NzhDNDcuOTkzIDgxLjM4NzggNDUuNjcxMyA3OC41MDYzIDQ1LjY3MTMgNzQuNDU5OEM0NS42NzEzIDcyLjk4ODQgNDUuOTc2OCA3MS40NTU2IDQ2LjUyNjcgNjkuOTIyOVpNODMuNjc2MSA0Mi41Nzk0QzgzLjY3NjEgNDYuMTcwNCA4MS41NTc1IDQ3Ljk2NTggNzkuMTg3NSA0Ny45NjU4Qzc2Ljc4MTYgNDcuOTY1OCA3NC42OTg5IDQ2LjE3MDQgNzQuNjk4OSA0Mi41Nzk0Qzc0LjY5ODkgMzguOTg4NSA3Ni43ODE2IDM3LjE5MzEgNzkuMTg3NSAzNy4xOTMxQzgxLjU1NzUgMzcuMTkzMSA4My42NzYxIDM4Ljk4ODUgODMuNjc2MSA0Mi41Nzk0Wk03MC4yMTAzIDQyLjU3OTVDNzAuMjEwMyA0Ni4xNzA0IDY4LjA5MTYgNDcuOTY1OCA2NS43MjE2IDQ3Ljk2NThDNjMuMzE1NyA0Ny45NjU4IDYxLjIzMyA0Ni4xNzA0IDYxLjIzMyA0Mi41Nzk1QzYxLjIzMyAzOC45ODg1IDYzLjMxNTcgMzcuMTkzMSA2NS43MjE2IDM3LjE5MzFDNjguMDkxNiAzNy4xOTMxIDcwLjIxMDMgMzguOTg4NSA3MC4yMTAzIDQyLjU3OTVaIiBmaWxsPSIjRkZGREY4Ii8+Cjwvc3ZnPgo=";
650
+
600
651
  // src/network-ids.ts
601
652
  var NetworkId = /* @__PURE__ */ ((NetworkId2) => {
602
653
  NetworkId2["SOLANA_MAINNET"] = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
@@ -900,13 +951,15 @@ var ANALYTICS_HEADERS = {
900
951
  SDK_VERSION: "x-phantom-sdk-version",
901
952
  // SDK version, e.g. 1.0.0
902
953
  PLATFORM: "x-phantom-platform",
903
- // firefox, chrome, safari, ios, android, etc.
954
+ // ext-sdk for all SDK requests
904
955
  WALLET_TYPE: "x-phantom-wallet-type",
905
956
  // app-wallet, user-wallet
906
957
  APP_ID: "x-app-id",
907
958
  // Your application ID for identifying your app in analytics
908
- PLATFORM_VERSION: "x-phantom-platform-version"
959
+ PLATFORM_VERSION: "x-phantom-platform-version",
909
960
  // OS version, device model, etc.
961
+ CLIENT: "x-phantom-client"
962
+ // mcp, chrome, firefox, safari, node, ios, android, etc.
910
963
  };
911
964
 
912
965
  // src/environments.ts
@@ -1018,6 +1071,12 @@ function isSolanaChain(networkId) {
1018
1071
  return network === "solana";
1019
1072
  }
1020
1073
 
1074
+ // src/index.ts
1075
+ async function sha256$2(input) {
1076
+ const digest = await crypto.subtle.digest("SHA-256", input);
1077
+ return new Uint8Array(digest);
1078
+ }
1079
+
1021
1080
  // src/PhantomClient.ts
1022
1081
  var CAIP2_NETWORK_MAPPINGS = {
1023
1082
  // Solana networks
@@ -1197,6 +1256,12 @@ function getErrorMessage(error, fallbackMessage = "An error occurred") {
1197
1256
  }
1198
1257
  return fallbackMessage;
1199
1258
  }
1259
+ function isAuthenticationError(error) {
1260
+ if (axios.isAxiosError(error)) {
1261
+ return error.response?.status === 401 || error.response?.status === 403;
1262
+ }
1263
+ return false;
1264
+ }
1200
1265
  function parseWalletServiceError(data) {
1201
1266
  if (!data || !data.type) {
1202
1267
  return null;
@@ -1231,6 +1296,7 @@ var PhantomClient = class {
1231
1296
  ...config,
1232
1297
  walletType: config.walletType || "user-wallet"
1233
1298
  };
1299
+ this.logger = config.logger;
1234
1300
  this.axiosInstance = axios.create();
1235
1301
  const customHeaders = {};
1236
1302
  if (config.headers) {
@@ -1259,6 +1325,20 @@ var PhantomClient = class {
1259
1325
  }
1260
1326
  this.config.organizationId = organizationId;
1261
1327
  }
1328
+ /**
1329
+ * Gets the authenticator public key from the stamper if available.
1330
+ * Returns undefined if the stamper doesn't support key info retrieval.
1331
+ */
1332
+ getAuthenticatorPublicKey() {
1333
+ if (!this.stamper) {
1334
+ return void 0;
1335
+ }
1336
+ if ("getKeyInfo" in this.stamper && typeof this.stamper.getKeyInfo === "function") {
1337
+ const keyInfo = this.stamper.getKeyInfo();
1338
+ return keyInfo?.publicKey;
1339
+ }
1340
+ return void 0;
1341
+ }
1262
1342
  async createWallet(walletName) {
1263
1343
  try {
1264
1344
  if (!this.config.organizationId) {
@@ -1306,18 +1386,22 @@ var PhantomClient = class {
1306
1386
  }))
1307
1387
  };
1308
1388
  } catch (error) {
1309
- console.error("Failed to create wallet:", error.response?.data || error.message);
1389
+ this.logger?.error(`Failed to create wallet: ${JSON.stringify(error.response?.data) || error.message}`);
1310
1390
  throw new Error(`Failed to create wallet: ${error.response?.data?.message || error.message}`);
1311
1391
  }
1312
1392
  }
1313
- async prepare(transaction, organizationId, submissionConfig, account, methodName) {
1393
+ async prepare(transaction, organizationId, submissionConfig, account, authenticatorPublicKey, methodName) {
1314
1394
  try {
1315
1395
  const request = {
1316
1396
  transaction,
1317
1397
  organizationId,
1318
1398
  submissionConfig,
1319
- simulationConfig: { account }
1399
+ simulationConfig: { account },
1400
+ authenticatorPublicKey
1320
1401
  };
1402
+ this.logger?.debug(
1403
+ `prepare request: submissionConfig=${JSON.stringify(submissionConfig)} account=${account} methodName=${methodName} txLength=${transaction.length} request=${JSON.stringify(request)}`
1404
+ );
1321
1405
  const response = await this.axiosInstance.post(`${this.config.apiBaseUrl}/prepare`, request, {
1322
1406
  headers: {
1323
1407
  "Content-Type": "application/json",
@@ -1327,6 +1411,11 @@ var PhantomClient = class {
1327
1411
  return response.data;
1328
1412
  } catch (error) {
1329
1413
  const errorData = getAxiosErrorData(error);
1414
+ const axiosStatus = error.response?.status;
1415
+ const rawResponseData = error.response?.data;
1416
+ this.logger?.error(
1417
+ `[TX_DEBUG] prepare failed: status=${axiosStatus} methodName=${methodName} body=${JSON.stringify(rawResponseData)}`
1418
+ );
1330
1419
  const walletServiceError = parseWalletServiceError(errorData);
1331
1420
  if (walletServiceError) {
1332
1421
  throw walletServiceError;
@@ -1336,7 +1425,7 @@ var PhantomClient = class {
1336
1425
  }
1337
1426
  }
1338
1427
  async getTransactionForSigning(params) {
1339
- const { encodedTransaction, networkId, submissionConfig, account } = params;
1428
+ const { encodedTransaction, networkId, submissionConfig, account, authenticatorPublicKey } = params;
1340
1429
  const isEvmTransaction = isEthereumChain(networkId);
1341
1430
  const isSolanaTransaction = isSolanaChain(networkId);
1342
1431
  if (isEvmTransaction) {
@@ -1352,6 +1441,7 @@ var PhantomClient = class {
1352
1441
  this.config.organizationId,
1353
1442
  submissionConfig,
1354
1443
  account,
1444
+ authenticatorPublicKey,
1355
1445
  params.methodName
1356
1446
  );
1357
1447
  return prepareResponse.transaction;
@@ -1375,7 +1465,7 @@ var PhantomClient = class {
1375
1465
  /**
1376
1466
  * Private method for shared signing logic
1377
1467
  */
1378
- async performTransactionSigning(params, includeSubmissionConfig) {
1468
+ async performTransactionSigning(params, includeSubmissionConfig, presignTransaction) {
1379
1469
  const walletId = params.walletId;
1380
1470
  const encodedTransaction = params.transaction;
1381
1471
  const networkIdParam = params.networkId;
@@ -1398,13 +1488,25 @@ var PhantomClient = class {
1398
1488
  curve: networkConfig.curve,
1399
1489
  addressFormat: networkConfig.addressFormat
1400
1490
  };
1401
- const transactionForSigning = await this.getTransactionForSigning({
1491
+ const authenticatorPublicKey = this.getAuthenticatorPublicKey();
1492
+ let transactionForSigning = await this.getTransactionForSigning({
1402
1493
  encodedTransaction,
1403
1494
  networkId: networkIdParam,
1404
1495
  submissionConfig,
1496
+ authenticatorPublicKey,
1405
1497
  account: params.account,
1406
1498
  methodName
1407
1499
  });
1500
+ if (presignTransaction && typeof transactionForSigning === "string") {
1501
+ try {
1502
+ transactionForSigning = await presignTransaction(transactionForSigning, {
1503
+ networkId: networkIdParam,
1504
+ walletId
1505
+ });
1506
+ } catch (hookError) {
1507
+ throw new Error(`presignTransaction hook failed: ${getErrorMessage(hookError, "unknown error")}`);
1508
+ }
1509
+ }
1408
1510
  const signRequest = {
1409
1511
  organizationId: this.config.organizationId,
1410
1512
  walletId,
@@ -1424,6 +1526,10 @@ var PhantomClient = class {
1424
1526
  params: signRequest,
1425
1527
  timestampMs: await getSecureTimestamp()
1426
1528
  };
1529
+ this.logger?.debug(
1530
+ `[TX_DEBUG] KMS request: methodName=${methodName} networkId=${networkIdParam} walletId=${walletId} account=${params.account}`
1531
+ );
1532
+ this.logger?.debug(`[TX_DEBUG] transactionForSigning=${JSON.stringify(transactionForSigning)}`);
1427
1533
  const response = await this.kmsApi.postKmsRpc(request, {
1428
1534
  headers: {
1429
1535
  "X-Rpc-Method": methodName
@@ -1431,7 +1537,29 @@ var PhantomClient = class {
1431
1537
  });
1432
1538
  const result = response.data.result;
1433
1539
  const rpcSubmissionResult = response.data["rpc_submission_result"];
1434
- const hash = includeSubmissionConfig && rpcSubmissionResult ? rpcSubmissionResult.result : null;
1540
+ this.logger?.debug(
1541
+ `[TX_DEBUG] KMS response: methodName=${methodName} hasResult=${!!result} rpcSubmissionResult=${JSON.stringify(rpcSubmissionResult)} fullResponse=${JSON.stringify(response.data)}`
1542
+ );
1543
+ let hash = void 0;
1544
+ if (includeSubmissionConfig && rpcSubmissionResult) {
1545
+ if (rpcSubmissionResult.error) {
1546
+ const { error } = rpcSubmissionResult;
1547
+ throw new Error(
1548
+ `Transaction broadcast failed: ${error.data ?? error.message ?? JSON.stringify(rpcSubmissionResult)}`
1549
+ );
1550
+ }
1551
+ const envelope = rpcSubmissionResult.result;
1552
+ if (envelope != null) {
1553
+ if (typeof envelope === "string") {
1554
+ hash = envelope;
1555
+ } else if (typeof envelope.result === "string") {
1556
+ hash = envelope.result;
1557
+ } else if (envelope.error) {
1558
+ const { error } = envelope;
1559
+ throw new Error(`Transaction broadcast failed: ${error.data ?? error.message ?? JSON.stringify(envelope)}`);
1560
+ }
1561
+ }
1562
+ }
1435
1563
  return {
1436
1564
  signedTransaction: result.transaction,
1437
1565
  // Base64 encoded signed transaction
@@ -1442,6 +1570,11 @@ var PhantomClient = class {
1442
1570
  if (error instanceof WalletServiceError) {
1443
1571
  throw error;
1444
1572
  }
1573
+ const axiosStatus = error.response?.status;
1574
+ const axiosData = error.response?.data;
1575
+ this.logger?.error(
1576
+ `[TX_DEBUG] performTransactionSigning failed: methodName=${methodName} status=${axiosStatus} body=${JSON.stringify(axiosData)}`
1577
+ );
1445
1578
  throw new Error(getErrorMessage(error, `Failed to ${actionType} transaction`));
1446
1579
  }
1447
1580
  }
@@ -1449,7 +1582,7 @@ var PhantomClient = class {
1449
1582
  * Sign a transaction
1450
1583
  */
1451
1584
  async signTransaction(params) {
1452
- const result = await this.performTransactionSigning(params, false);
1585
+ const result = await this.performTransactionSigning(params, false, params.presignTransaction);
1453
1586
  return {
1454
1587
  rawTransaction: result.signedTransaction
1455
1588
  };
@@ -1458,7 +1591,7 @@ var PhantomClient = class {
1458
1591
  * Sign and send a transaction
1459
1592
  */
1460
1593
  async signAndSendTransaction(params) {
1461
- const result = await this.performTransactionSigning(params, true);
1594
+ const result = await this.performTransactionSigning(params, true, params.presignTransaction);
1462
1595
  return {
1463
1596
  rawTransaction: result.signedTransaction,
1464
1597
  hash: result.hash
@@ -1490,7 +1623,7 @@ var PhantomClient = class {
1490
1623
  }));
1491
1624
  return addresses;
1492
1625
  } catch (error) {
1493
- console.error("Failed to get wallet addresses:", error.response?.data || error.message);
1626
+ this.logger?.error(`Failed to get wallet addresses: ${JSON.stringify(error.response?.data) || error.message}`);
1494
1627
  throw new Error(`Failed to get wallet addresses: ${error.response?.data?.message || error.message}`);
1495
1628
  }
1496
1629
  }
@@ -1530,7 +1663,7 @@ var PhantomClient = class {
1530
1663
  const result = response.data.result;
1531
1664
  return result.signature;
1532
1665
  } catch (error) {
1533
- console.error("Failed to sign Ethereum message:", error.response?.data || error.message);
1666
+ this.logger?.error(`Failed to sign Ethereum message: ${JSON.stringify(error.response?.data) || error.message}`);
1534
1667
  throw new Error(`Failed to sign Ethereum message: ${error.response?.data?.message || error.message}`);
1535
1668
  }
1536
1669
  }
@@ -1571,7 +1704,7 @@ var PhantomClient = class {
1571
1704
  const result = response.data.result;
1572
1705
  return result.signature;
1573
1706
  } catch (error) {
1574
- console.error("Failed to sign raw payload:", error.response?.data || error.message);
1707
+ this.logger?.error(`Failed to sign raw payload: ${JSON.stringify(error.response?.data) || error.message}`);
1575
1708
  throw new Error(`Failed to sign raw payload: ${error.response?.data?.message || error.message}`);
1576
1709
  }
1577
1710
  }
@@ -1610,7 +1743,7 @@ var PhantomClient = class {
1610
1743
  const result = response.data.result;
1611
1744
  return result.signature;
1612
1745
  } catch (error) {
1613
- console.error("Failed to sign typed data:", error.response?.data || error.message);
1746
+ this.logger?.error(`Failed to sign typed data: ${JSON.stringify(error.response?.data) || error.message}`);
1614
1747
  throw new Error(`Failed to sign typed data: ${error.response?.data?.message || error.message}`);
1615
1748
  }
1616
1749
  }
@@ -1637,7 +1770,7 @@ var PhantomClient = class {
1637
1770
  offset: result.offset
1638
1771
  };
1639
1772
  } catch (error) {
1640
- console.error("Failed to get wallets:", error.response?.data || error.message);
1773
+ this.logger?.error(`Failed to get wallets: ${JSON.stringify(error.response?.data) || error.message}`);
1641
1774
  throw new Error(`Failed to get wallets: ${error.response?.data?.message || error.message}`);
1642
1775
  }
1643
1776
  }
@@ -1657,7 +1790,7 @@ var PhantomClient = class {
1657
1790
  const result = response.data.result;
1658
1791
  return result;
1659
1792
  } catch (error) {
1660
- console.error("Failed to get organization:", error.response?.data || error.message);
1793
+ this.logger?.error(`Failed to get organization: ${JSON.stringify(error.response?.data) || error.message}`);
1661
1794
  throw new Error(`Failed to get organization: ${error.response?.data?.message || error.message}`);
1662
1795
  }
1663
1796
  }
@@ -1711,7 +1844,7 @@ var PhantomClient = class {
1711
1844
  const result = response.data.result;
1712
1845
  return result;
1713
1846
  } catch (error) {
1714
- console.error("Failed to create organization:", error.response?.data || error.message);
1847
+ this.logger?.error(`Failed to create organization: ${JSON.stringify(error.response?.data) || error.message}`);
1715
1848
  throw new Error(`Failed to create organization: ${error.response?.data?.message || error.message}`);
1716
1849
  }
1717
1850
  }
@@ -1745,7 +1878,7 @@ var PhantomClient = class {
1745
1878
  const result = response.data.result;
1746
1879
  return result;
1747
1880
  } catch (error) {
1748
- console.error("Failed to create authenticator:", error.response?.data || error.message);
1881
+ this.logger?.error(`Failed to create authenticator: ${JSON.stringify(error.response?.data) || error.message}`);
1749
1882
  throw new Error(`Failed to create authenticator: ${error.response?.data?.message || error.message}`);
1750
1883
  }
1751
1884
  }
@@ -1768,7 +1901,7 @@ var PhantomClient = class {
1768
1901
  const result = response.data.result;
1769
1902
  return result;
1770
1903
  } catch (error) {
1771
- console.error("Failed to delete authenticator:", error.response?.data || error.message);
1904
+ this.logger?.error(`Failed to delete authenticator: ${JSON.stringify(error.response?.data) || error.message}`);
1772
1905
  throw new Error(`Failed to delete authenticator: ${error.response?.data?.message || error.message}`);
1773
1906
  }
1774
1907
  }
@@ -1783,7 +1916,9 @@ var PhantomClient = class {
1783
1916
  const result = response.data.result;
1784
1917
  return result;
1785
1918
  } catch (error) {
1786
- console.error("Failed to grant organization access:", error.response?.data || error.message);
1919
+ this.logger?.error(
1920
+ `Failed to grant organization access: ${JSON.stringify(error.response?.data) || error.message}`
1921
+ );
1787
1922
  throw new Error(`Failed to grant organization access: ${error.response?.data?.message || error.message}`);
1788
1923
  }
1789
1924
  }
@@ -1799,7 +1934,9 @@ var PhantomClient = class {
1799
1934
  };
1800
1935
  await this.kmsApi.postKmsRpc(request);
1801
1936
  } catch (error) {
1802
- console.error("Failed to add user to organization:", error.response?.data || error.message);
1937
+ this.logger?.error(
1938
+ `Failed to add user to organization: ${JSON.stringify(error.response?.data) || error.message}`
1939
+ );
1803
1940
  throw new Error(`Failed to add user to organization: ${error.response?.data?.message || error.message}`);
1804
1941
  }
1805
1942
  }
@@ -1821,7 +1958,7 @@ var PhantomClient = class {
1821
1958
  const result = response.data.result;
1822
1959
  return result;
1823
1960
  } catch (error) {
1824
- console.error("Failed to get wallet with tag:", error.response?.data || error.message);
1961
+ this.logger?.error(`Failed to get wallet with tag: ${JSON.stringify(error.response?.data) || error.message}`);
1825
1962
  throw new Error(`Failed to get wallet with tag: ${error.response?.data?.message || error.message}`);
1826
1963
  }
1827
1964
  }
@@ -1854,6 +1991,22 @@ var __privateMethod = (obj, member, method) => {
1854
1991
  return method;
1855
1992
  };
1856
1993
 
1994
+ // src/extension/isInstalled.ts
1995
+ function isInstalled() {
1996
+ try {
1997
+ const phantom = window?.phantom;
1998
+ return !!phantom;
1999
+ } catch (error) {
2000
+ return false;
2001
+ }
2002
+ }
2003
+
2004
+ // src/errors.ts
2005
+ var PHANTOM_NOT_DETECTED = "Phantom wallet not detected.";
2006
+ var ETHEREUM_PROVIDER_NOT_FOUND = "Ethereum provider not found on window.phantom.";
2007
+ var SOLANA_PROVIDER_NOT_FOUND = "Solana provider not found on window.phantom.";
2008
+ var APP_PROVIDER_NOT_FOUND = "App provider not found on window.phantom.";
2009
+
1857
2010
  // src/ethereum/siwe.ts
1858
2011
  var ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
1859
2012
  var DOMAIN_REGEX = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(:[0-9]{1,5})?$/;
@@ -1978,7 +2131,7 @@ function splitUri(value) {
1978
2131
  }
1979
2132
 
1980
2133
  // src/ethereum/strategies/injected.ts
1981
- var MAX_RETRIES$1 = 4;
2134
+ var MAX_RETRIES$1 = 6;
1982
2135
  var BASE_DELAY$1 = 100;
1983
2136
  var _getProvider$1, getProvider_fn$1;
1984
2137
  var InjectedEthereumStrategy = class {
@@ -1997,7 +2150,11 @@ var InjectedEthereumStrategy = class {
1997
2150
  }
1998
2151
  retryCount++;
1999
2152
  if (retryCount >= MAX_RETRIES$1) {
2000
- reject();
2153
+ if (!isInstalled()) {
2154
+ reject(new Error(PHANTOM_NOT_DETECTED));
2155
+ } else {
2156
+ reject(new Error(ETHEREUM_PROVIDER_NOT_FOUND));
2157
+ }
2001
2158
  } else {
2002
2159
  scheduleRetry(resolve, reject);
2003
2160
  }
@@ -2017,7 +2174,7 @@ var InjectedEthereumStrategy = class {
2017
2174
  async connect({ onlyIfTrusted }) {
2018
2175
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2019
2176
  if (!provider) {
2020
- throw new Error("Provider not found.");
2177
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2021
2178
  }
2022
2179
  if (provider.isConnected && provider.selectedAddress) {
2023
2180
  return this.getAccounts();
@@ -2049,7 +2206,7 @@ var InjectedEthereumStrategy = class {
2049
2206
  async signMessage(message, address) {
2050
2207
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2051
2208
  if (!provider) {
2052
- throw new Error("Provider not found.");
2209
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2053
2210
  }
2054
2211
  if (!provider.isConnected) {
2055
2212
  throw new Error("Provider is not connected.");
@@ -2063,7 +2220,7 @@ var InjectedEthereumStrategy = class {
2063
2220
  async signPersonalMessage(message, address) {
2064
2221
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2065
2222
  if (!provider) {
2066
- throw new Error("Provider not found.");
2223
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2067
2224
  }
2068
2225
  if (!provider.isConnected) {
2069
2226
  throw new Error("Provider is not connected.");
@@ -2077,7 +2234,7 @@ var InjectedEthereumStrategy = class {
2077
2234
  async signTypedData(typedData, address) {
2078
2235
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2079
2236
  if (!provider) {
2080
- throw new Error("Provider not found.");
2237
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2081
2238
  }
2082
2239
  if (!provider.isConnected) {
2083
2240
  throw new Error("Provider is not connected.");
@@ -2091,7 +2248,7 @@ var InjectedEthereumStrategy = class {
2091
2248
  async signIn(signInData) {
2092
2249
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2093
2250
  if (!provider) {
2094
- throw new Error("Provider not found.");
2251
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2095
2252
  }
2096
2253
  const message = createSiweMessage(signInData);
2097
2254
  const address = provider.selectedAddress;
@@ -2108,7 +2265,7 @@ var InjectedEthereumStrategy = class {
2108
2265
  async sendTransaction(transaction) {
2109
2266
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2110
2267
  if (!provider) {
2111
- throw new Error("Provider not found.");
2268
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2112
2269
  }
2113
2270
  if (!provider.isConnected) {
2114
2271
  throw new Error("Provider is not connected.");
@@ -2122,7 +2279,7 @@ var InjectedEthereumStrategy = class {
2122
2279
  async signTransaction(transaction) {
2123
2280
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2124
2281
  if (!provider) {
2125
- throw new Error("Provider not found.");
2282
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2126
2283
  }
2127
2284
  if (!provider.isConnected) {
2128
2285
  throw new Error("Provider is not connected.");
@@ -2136,7 +2293,7 @@ var InjectedEthereumStrategy = class {
2136
2293
  async getChainId() {
2137
2294
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2138
2295
  if (!provider) {
2139
- throw new Error("Provider not found.");
2296
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2140
2297
  }
2141
2298
  const chainId = await provider.request({ method: "eth_chainId" });
2142
2299
  return chainId;
@@ -2144,7 +2301,7 @@ var InjectedEthereumStrategy = class {
2144
2301
  async switchChain(chainId) {
2145
2302
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2146
2303
  if (!provider) {
2147
- throw new Error("Provider not found.");
2304
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2148
2305
  }
2149
2306
  await provider.request({
2150
2307
  method: "wallet_switchEthereumChain",
@@ -2154,29 +2311,25 @@ var InjectedEthereumStrategy = class {
2154
2311
  async request(args) {
2155
2312
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2156
2313
  if (!provider) {
2157
- throw new Error("Provider not found.");
2314
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2158
2315
  }
2159
2316
  return await provider.request(args);
2160
2317
  }
2161
2318
  };
2162
2319
  _getProvider$1 = new WeakSet();
2163
2320
  getProvider_fn$1 = function() {
2164
- if (typeof window === "undefined") {
2321
+ if (!isInstalled()) {
2165
2322
  return void 0;
2166
2323
  }
2167
- return window?.phantom?.ethereum;
2324
+ return window.phantom.ethereum;
2168
2325
  };
2169
2326
 
2170
2327
  // src/ethereum/getProvider.ts
2171
2328
  async function getProvider$2(strategy = "injected" /* INJECTED */) {
2172
2329
  if (strategy === "injected") {
2173
2330
  const provider = new InjectedEthereumStrategy();
2174
- try {
2175
- await provider.load();
2176
- return provider;
2177
- } catch (error) {
2178
- throw new Error("Provider not found.");
2179
- }
2331
+ await provider.load();
2332
+ return provider;
2180
2333
  } else {
2181
2334
  throw new Error("Invalid provider type.");
2182
2335
  }
@@ -2214,9 +2367,6 @@ function triggerEvent$1(event, data) {
2214
2367
  // src/ethereum/connect.ts
2215
2368
  async function connect$1({ onlyIfTrusted = false } = {}) {
2216
2369
  const provider = await getProvider$2();
2217
- if (!provider) {
2218
- throw new Error("Provider not found.");
2219
- }
2220
2370
  if (provider.isConnected) {
2221
2371
  const accounts = await provider.getAccounts();
2222
2372
  return accounts;
@@ -2246,9 +2396,6 @@ async function connect$1({ onlyIfTrusted = false } = {}) {
2246
2396
  // src/ethereum/disconnect.ts
2247
2397
  async function disconnect$1() {
2248
2398
  const provider = await getProvider$2();
2249
- if (!provider) {
2250
- throw new Error("Provider not found.");
2251
- }
2252
2399
  await provider.disconnect();
2253
2400
  triggerEvent$1("disconnect", []);
2254
2401
  }
@@ -2256,18 +2403,12 @@ async function disconnect$1() {
2256
2403
  // src/ethereum/getAccounts.ts
2257
2404
  async function getAccounts() {
2258
2405
  const provider = await getProvider$2();
2259
- if (!provider) {
2260
- throw new Error("Provider not found.");
2261
- }
2262
2406
  return provider.getAccounts();
2263
2407
  }
2264
2408
 
2265
2409
  // src/ethereum/signMessage.ts
2266
2410
  async function signPersonalMessage(message, address) {
2267
2411
  const provider = await getProvider$2();
2268
- if (!provider) {
2269
- throw new Error("Provider not found.");
2270
- }
2271
2412
  if (!provider.isConnected) {
2272
2413
  await provider.connect({ onlyIfTrusted: false });
2273
2414
  }
@@ -2275,9 +2416,6 @@ async function signPersonalMessage(message, address) {
2275
2416
  }
2276
2417
  async function signTypedData(typedData, address) {
2277
2418
  const provider = await getProvider$2();
2278
- if (!provider) {
2279
- throw new Error("Provider not found.");
2280
- }
2281
2419
  if (!provider.isConnected) {
2282
2420
  await provider.connect({ onlyIfTrusted: false });
2283
2421
  }
@@ -2287,9 +2425,6 @@ async function signTypedData(typedData, address) {
2287
2425
  // src/ethereum/sendTransaction.ts
2288
2426
  async function sendTransaction(transaction) {
2289
2427
  const provider = await getProvider$2();
2290
- if (!provider) {
2291
- throw new Error("Provider not found.");
2292
- }
2293
2428
  if (!provider.isConnected) {
2294
2429
  await provider.connect({ onlyIfTrusted: false });
2295
2430
  }
@@ -2297,9 +2432,6 @@ async function sendTransaction(transaction) {
2297
2432
  }
2298
2433
  async function signTransaction$1(transaction) {
2299
2434
  const provider = await getProvider$2();
2300
- if (!provider) {
2301
- throw new Error("Provider not found.");
2302
- }
2303
2435
  if (!provider.isConnected) {
2304
2436
  await provider.connect({ onlyIfTrusted: false });
2305
2437
  }
@@ -2309,16 +2441,10 @@ async function signTransaction$1(transaction) {
2309
2441
  // src/ethereum/chainUtils.ts
2310
2442
  async function getChainId() {
2311
2443
  const provider = await getProvider$2();
2312
- if (!provider) {
2313
- throw new Error("Provider not found.");
2314
- }
2315
2444
  return provider.getChainId();
2316
2445
  }
2317
2446
  async function switchChain(chainId) {
2318
2447
  const provider = await getProvider$2();
2319
- if (!provider) {
2320
- throw new Error("Provider not found.");
2321
- }
2322
2448
  return provider.switchChain(chainId);
2323
2449
  }
2324
2450
 
@@ -2329,9 +2455,6 @@ var Ethereum = class {
2329
2455
  this._accounts = [];
2330
2456
  this.bindProviderEvents();
2331
2457
  }
2332
- get connected() {
2333
- return this._accounts.length > 0;
2334
- }
2335
2458
  get chainId() {
2336
2459
  return this._chainId;
2337
2460
  }
@@ -2340,9 +2463,6 @@ var Ethereum = class {
2340
2463
  }
2341
2464
  async request(args) {
2342
2465
  const provider = await getProvider$2();
2343
- if (!provider) {
2344
- throw new Error("Provider not found.");
2345
- }
2346
2466
  const providerInstance = provider.getProvider();
2347
2467
  if (!providerInstance) {
2348
2468
  throw new Error("Provider instance not found.");
@@ -2443,16 +2563,6 @@ function createEthereumPlugin() {
2443
2563
  };
2444
2564
  }
2445
2565
 
2446
- // src/extension/isInstalled.ts
2447
- function isInstalled() {
2448
- try {
2449
- const phantom = window?.phantom;
2450
- return !!phantom;
2451
- } catch (error) {
2452
- return false;
2453
- }
2454
- }
2455
-
2456
2566
  // src/extension/plugin.ts
2457
2567
  var extension = {
2458
2568
  isInstalled
@@ -2474,7 +2584,7 @@ function createPhantom({ plugins = [] }) {
2474
2584
  }
2475
2585
 
2476
2586
  // src/solana/strategies/injected.ts
2477
- var MAX_RETRIES = 4;
2587
+ var MAX_RETRIES = 6;
2478
2588
  var BASE_DELAY = 100;
2479
2589
  var _getProvider, getProvider_fn;
2480
2590
  var InjectedSolanaStrategy = class {
@@ -2493,7 +2603,11 @@ var InjectedSolanaStrategy = class {
2493
2603
  }
2494
2604
  retryCount++;
2495
2605
  if (retryCount >= MAX_RETRIES) {
2496
- reject();
2606
+ if (!isInstalled()) {
2607
+ reject(new Error(PHANTOM_NOT_DETECTED));
2608
+ } else {
2609
+ reject(new Error(SOLANA_PROVIDER_NOT_FOUND));
2610
+ }
2497
2611
  } else {
2498
2612
  scheduleRetry(resolve, reject);
2499
2613
  }
@@ -2513,7 +2627,7 @@ var InjectedSolanaStrategy = class {
2513
2627
  async connect({ onlyIfTrusted }) {
2514
2628
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2515
2629
  if (!provider) {
2516
- throw new Error("Provider not found.");
2630
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2517
2631
  }
2518
2632
  if (provider.isConnected && provider.publicKey) {
2519
2633
  return this.getAccount() ?? void 0;
@@ -2528,7 +2642,7 @@ var InjectedSolanaStrategy = class {
2528
2642
  async disconnect() {
2529
2643
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2530
2644
  if (!provider) {
2531
- throw new Error("Provider not found.");
2645
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2532
2646
  }
2533
2647
  await provider.disconnect();
2534
2648
  }
@@ -2542,7 +2656,7 @@ var InjectedSolanaStrategy = class {
2542
2656
  async signMessage(message, display) {
2543
2657
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2544
2658
  if (!provider) {
2545
- throw new Error("Provider not found.");
2659
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2546
2660
  }
2547
2661
  if (!provider.isConnected) {
2548
2662
  throw new Error("Provider is not connected.");
@@ -2556,7 +2670,7 @@ var InjectedSolanaStrategy = class {
2556
2670
  async signIn(signInData) {
2557
2671
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2558
2672
  if (!provider) {
2559
- throw new Error("Provider not found.");
2673
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2560
2674
  }
2561
2675
  const result = await provider.signIn(signInData);
2562
2676
  return {
@@ -2568,7 +2682,7 @@ var InjectedSolanaStrategy = class {
2568
2682
  async signAndSendTransaction(transaction) {
2569
2683
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2570
2684
  if (!provider) {
2571
- throw new Error("Provider not found.");
2685
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2572
2686
  }
2573
2687
  if (!provider.isConnected) {
2574
2688
  throw new Error("Provider is not connected.");
@@ -2582,7 +2696,7 @@ var InjectedSolanaStrategy = class {
2582
2696
  async signAndSendAllTransactions(transactions) {
2583
2697
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2584
2698
  if (!provider) {
2585
- throw new Error("Provider not found.");
2699
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2586
2700
  }
2587
2701
  if (!provider.isConnected) {
2588
2702
  throw new Error("Provider is not connected.");
@@ -2599,7 +2713,7 @@ var InjectedSolanaStrategy = class {
2599
2713
  async signTransaction(transaction) {
2600
2714
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2601
2715
  if (!provider) {
2602
- throw new Error("Provider not found.");
2716
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2603
2717
  }
2604
2718
  if (!provider.isConnected) {
2605
2719
  throw new Error("Provider is not connected.");
@@ -2610,7 +2724,7 @@ var InjectedSolanaStrategy = class {
2610
2724
  async signAllTransactions(transactions) {
2611
2725
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2612
2726
  if (!provider) {
2613
- throw new Error("Provider not found.");
2727
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2614
2728
  }
2615
2729
  if (!provider.isConnected) {
2616
2730
  throw new Error("Provider is not connected.");
@@ -2621,22 +2735,18 @@ var InjectedSolanaStrategy = class {
2621
2735
  };
2622
2736
  _getProvider = new WeakSet();
2623
2737
  getProvider_fn = function() {
2624
- if (typeof window === "undefined") {
2738
+ if (!isInstalled()) {
2625
2739
  return void 0;
2626
2740
  }
2627
- return window?.phantom?.solana;
2741
+ return window.phantom.solana;
2628
2742
  };
2629
2743
 
2630
2744
  // src/solana/getProvider.ts
2631
2745
  async function getProvider$1(strategy = "injected" /* INJECTED */) {
2632
2746
  if (strategy === "injected") {
2633
2747
  const provider = new InjectedSolanaStrategy();
2634
- try {
2635
- await provider.load();
2636
- return provider;
2637
- } catch (error) {
2638
- throw new Error("Provider not found.");
2639
- }
2748
+ await provider.load();
2749
+ return provider;
2640
2750
  } else {
2641
2751
  throw new Error("Invalid provider type.");
2642
2752
  }
@@ -2676,9 +2786,6 @@ function triggerEvent(event, ...args) {
2676
2786
  // src/solana/connect.ts
2677
2787
  async function connect({ onlyIfTrusted = false } = {}) {
2678
2788
  const provider = await getProvider$1();
2679
- if (!provider) {
2680
- throw new Error("Provider not found.");
2681
- }
2682
2789
  if (provider.isConnected) {
2683
2790
  return provider.getAccount();
2684
2791
  }
@@ -2707,25 +2814,13 @@ async function connect({ onlyIfTrusted = false } = {}) {
2707
2814
  // src/solana/disconnect.ts
2708
2815
  async function disconnect() {
2709
2816
  const provider = await getProvider$1();
2710
- if (!provider) {
2711
- throw new Error("Provider not found.");
2712
- }
2713
2817
  await provider.disconnect();
2714
2818
  triggerEvent("disconnect");
2715
2819
  }
2716
2820
 
2717
- // src/solana/getAccount.ts
2718
- async function getAccount() {
2719
- const provider = await getProvider$1();
2720
- return provider.getAccount();
2721
- }
2722
-
2723
2821
  // src/solana/signAndSendTransaction.ts
2724
2822
  async function signAndSendTransaction(transaction) {
2725
2823
  const provider = await getProvider$1();
2726
- if (!provider) {
2727
- throw new Error("Provider not found.");
2728
- }
2729
2824
  if (!provider.isConnected) {
2730
2825
  await provider.connect({ onlyIfTrusted: false });
2731
2826
  }
@@ -2735,9 +2830,6 @@ async function signAndSendTransaction(transaction) {
2735
2830
  // src/solana/signAndSendAllTransactions.ts
2736
2831
  async function signAndSendAllTransactions(transactions) {
2737
2832
  const provider = await getProvider$1();
2738
- if (!provider) {
2739
- throw new Error("Provider not found.");
2740
- }
2741
2833
  if (!provider.isConnected) {
2742
2834
  await provider.connect({ onlyIfTrusted: false });
2743
2835
  }
@@ -2747,9 +2839,6 @@ async function signAndSendAllTransactions(transactions) {
2747
2839
  // src/solana/signTransaction.ts
2748
2840
  async function signTransaction(transaction) {
2749
2841
  const provider = await getProvider$1();
2750
- if (!provider) {
2751
- throw new Error("Provider not found.");
2752
- }
2753
2842
  if (!provider.isConnected) {
2754
2843
  await provider.connect({ onlyIfTrusted: false });
2755
2844
  }
@@ -2759,9 +2848,6 @@ async function signTransaction(transaction) {
2759
2848
  // src/solana/signAllTransactions.ts
2760
2849
  async function signAllTransactions(transactions) {
2761
2850
  const provider = await getProvider$1();
2762
- if (!provider) {
2763
- throw new Error("Provider not found.");
2764
- }
2765
2851
  if (!provider.isConnected) {
2766
2852
  await provider.connect({ onlyIfTrusted: false });
2767
2853
  }
@@ -2771,9 +2857,6 @@ async function signAllTransactions(transactions) {
2771
2857
  // src/solana/signMessage.ts
2772
2858
  async function signMessage(message, display) {
2773
2859
  const provider = await getProvider$1();
2774
- if (!provider) {
2775
- throw new Error("Provider not found.");
2776
- }
2777
2860
  if (!provider.isConnected) {
2778
2861
  await provider.connect({ onlyIfTrusted: false });
2779
2862
  }
@@ -2789,7 +2872,7 @@ var Solana = class {
2789
2872
  get publicKey() {
2790
2873
  return this._publicKey;
2791
2874
  }
2792
- get connected() {
2875
+ get isConnected() {
2793
2876
  return this._publicKey !== null;
2794
2877
  }
2795
2878
  async connect(options) {
@@ -2829,21 +2912,6 @@ var Solana = class {
2829
2912
  async switchNetwork(_network) {
2830
2913
  return Promise.resolve();
2831
2914
  }
2832
- async getPublicKey() {
2833
- if (this._publicKey) {
2834
- return this._publicKey;
2835
- }
2836
- try {
2837
- const account = await getAccount();
2838
- this._publicKey = account || null;
2839
- return this._publicKey;
2840
- } catch {
2841
- return null;
2842
- }
2843
- }
2844
- isConnected() {
2845
- return this._publicKey !== null;
2846
- }
2847
2915
  on(event, listener) {
2848
2916
  addEventListener(event, listener);
2849
2917
  }
@@ -2893,20 +2961,17 @@ function createSolanaPlugin() {
2893
2961
 
2894
2962
  // src/auto-confirm/getProvider.ts
2895
2963
  function getProvider() {
2896
- if (typeof window === "undefined") {
2897
- return null;
2964
+ if (!isInstalled()) {
2965
+ throw new Error(PHANTOM_NOT_DETECTED);
2898
2966
  }
2899
- const provider = window?.phantom?.app;
2967
+ const provider = window.phantom.app;
2900
2968
  if (!provider) {
2901
- return null;
2969
+ throw new Error(APP_PROVIDER_NOT_FOUND);
2902
2970
  }
2903
2971
  return provider;
2904
2972
  }
2905
2973
  async function autoConfirmEnable(params) {
2906
- const provider = await getProvider();
2907
- if (!provider) {
2908
- throw new Error("Provider not found.");
2909
- }
2974
+ const provider = getProvider();
2910
2975
  const transformedParams = params?.chains ? { chains: params.chains.map(networkIdToInternalCaip) } : {};
2911
2976
  const result = await provider.request({
2912
2977
  method: "phantom_auto_confirm_enable",
@@ -2918,10 +2983,7 @@ async function autoConfirmEnable(params) {
2918
2983
  };
2919
2984
  }
2920
2985
  async function autoConfirmDisable() {
2921
- const provider = await getProvider();
2922
- if (!provider) {
2923
- throw new Error("Provider not found.");
2924
- }
2986
+ const provider = getProvider();
2925
2987
  const result = await provider.request({
2926
2988
  method: "phantom_auto_confirm_disable",
2927
2989
  params: {}
@@ -2932,10 +2994,7 @@ async function autoConfirmDisable() {
2932
2994
  };
2933
2995
  }
2934
2996
  async function autoConfirmStatus() {
2935
- const provider = await getProvider();
2936
- if (!provider) {
2937
- throw new Error("Provider not found.");
2938
- }
2997
+ const provider = getProvider();
2939
2998
  const result = await provider.request({
2940
2999
  method: "phantom_auto_confirm_status",
2941
3000
  params: {}
@@ -2946,10 +3005,7 @@ async function autoConfirmStatus() {
2946
3005
  };
2947
3006
  }
2948
3007
  async function autoConfirmSupportedChains() {
2949
- const provider = await getProvider();
2950
- if (!provider) {
2951
- throw new Error("Provider not found.");
2952
- }
3008
+ const provider = getProvider();
2953
3009
  const result = await provider.request({
2954
3010
  method: "phantom_auto_confirm_supported_chains",
2955
3011
  params: {}
@@ -3370,7 +3426,7 @@ function stringToBase64url(str) {
3370
3426
  /**
3371
3427
  * The current version of Ethers.
3372
3428
  */
3373
- const version = "6.16.0";
3429
+ const version = "6.17.0";
3374
3430
 
3375
3431
  /**
3376
3432
  * Property helper functions.
@@ -8696,7 +8752,7 @@ function parseTransactionResponse(base64RawTransaction, networkId, hash) {
8696
8752
  function parseSolanaSignatureResponse(base64Response) {
8697
8753
  try {
8698
8754
  const signatureBytes = base64urlDecode(base64Response);
8699
- const signature = index_native.base58.encode(signatureBytes);
8755
+ const signature = index_native.bs582.encode(signatureBytes);
8700
8756
  return {
8701
8757
  signature,
8702
8758
  rawSignature: base64Response
@@ -8766,8 +8822,6 @@ function deserializeSolanaTransaction(transactionBytes) {
8766
8822
  throw legacyError;
8767
8823
  }
8768
8824
  }
8769
-
8770
- // src/index.ts
8771
8825
  async function parseToKmsTransaction(transaction, networkId) {
8772
8826
  const networkPrefix = networkId.split(":")[0].toLowerCase();
8773
8827
  switch (networkPrefix) {
@@ -9289,27 +9343,25 @@ var EventEmitter2 = /*@__PURE__*/index_native.getDefaultExportFromCjs(eventemitt
9289
9343
  // src/embedded-provider.ts
9290
9344
 
9291
9345
  // src/constants.ts
9292
- var AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1e3;
9346
+ var AUTHENTICATOR_EXPIRATION_TIME_MS = 31 * 24 * 60 * 60 * 1e3;
9293
9347
  var EMBEDDED_PROVIDER_AUTH_TYPES = ["google", "apple", "phantom"];
9294
9348
  var EmbeddedSolanaChain = class {
9295
9349
  constructor(provider) {
9296
9350
  this.provider = provider;
9297
9351
  this.currentNetworkId = NetworkId.SOLANA_MAINNET;
9298
- this._connected = false;
9299
9352
  this._publicKey = null;
9300
9353
  this.eventEmitter = new EventEmitter2();
9301
9354
  this.setupEventListeners();
9302
9355
  this.syncInitialState();
9303
9356
  }
9304
- // Wallet adapter compliant properties
9305
- get connected() {
9306
- return this._connected;
9307
- }
9308
9357
  get publicKey() {
9309
9358
  return this._publicKey;
9310
9359
  }
9360
+ get isConnected() {
9361
+ return this._publicKey !== null;
9362
+ }
9311
9363
  ensureConnected() {
9312
- if (!this.provider.isConnected()) {
9364
+ if (!this.isConnected) {
9313
9365
  throw new Error("Solana chain not available. Ensure SDK is connected.");
9314
9366
  }
9315
9367
  }
@@ -9321,7 +9373,7 @@ var EmbeddedSolanaChain = class {
9321
9373
  message: messageStr,
9322
9374
  networkId: this.currentNetworkId
9323
9375
  });
9324
- const signature = typeof result.signature === "string" ? new Uint8Array(index_native.base58.decode(result.signature)) : result.signature;
9376
+ const signature = typeof result.signature === "string" ? new Uint8Array(index_native.bs582.decode(result.signature)) : result.signature;
9325
9377
  return {
9326
9378
  signature,
9327
9379
  publicKey: this._publicKey || ""
@@ -9339,11 +9391,12 @@ var EmbeddedSolanaChain = class {
9339
9391
  }
9340
9392
  return signedTransaction;
9341
9393
  }
9342
- async signAndSendTransaction(transaction) {
9394
+ async signAndSendTransaction(transaction, options) {
9343
9395
  this.ensureConnected();
9344
9396
  const result = await this.provider.signAndSendTransaction({
9345
9397
  transaction,
9346
- networkId: this.currentNetworkId
9398
+ networkId: this.currentNetworkId,
9399
+ presignTransaction: options?.presignTransaction
9347
9400
  });
9348
9401
  if (!result.hash) {
9349
9402
  throw new Error("Transaction not submitted");
@@ -9367,7 +9420,7 @@ var EmbeddedSolanaChain = class {
9367
9420
  const solanaAddr = addresses.find((a) => a.addressType === "Solana");
9368
9421
  if (!solanaAddr)
9369
9422
  throw new Error("No Solana address found");
9370
- this.updateConnectionState(true, solanaAddr.address);
9423
+ this._publicKey = solanaAddr.address;
9371
9424
  return Promise.resolve({ publicKey: solanaAddr.address });
9372
9425
  }
9373
9426
  async disconnect() {
@@ -9377,41 +9430,25 @@ var EmbeddedSolanaChain = class {
9377
9430
  this.currentNetworkId = network === "mainnet" ? NetworkId.SOLANA_MAINNET : NetworkId.SOLANA_DEVNET;
9378
9431
  return Promise.resolve();
9379
9432
  }
9380
- getPublicKey() {
9381
- if (!this.provider.isConnected())
9382
- return Promise.resolve(null);
9383
- const addresses = this.provider.getAddresses();
9384
- const solanaAddr = addresses.find((a) => a.addressType === "Solana");
9385
- return Promise.resolve(solanaAddr?.address || null);
9386
- }
9387
- isConnected() {
9388
- return this._connected && this.provider.isConnected();
9389
- }
9390
9433
  setupEventListeners() {
9391
9434
  this.provider.on("connect", (data) => {
9392
9435
  const solanaAddress = data.addresses?.find((addr) => addr.addressType === "Solana");
9393
9436
  if (solanaAddress) {
9394
- this.updateConnectionState(true, solanaAddress.address);
9437
+ this._publicKey = solanaAddress.address;
9395
9438
  this.eventEmitter.emit("connect", solanaAddress.address);
9396
9439
  }
9397
9440
  });
9398
9441
  this.provider.on("disconnect", () => {
9399
- this.updateConnectionState(false, null);
9442
+ this._publicKey = null;
9400
9443
  this.eventEmitter.emit("disconnect");
9401
9444
  });
9402
9445
  }
9403
9446
  syncInitialState() {
9404
- if (this.provider.isConnected()) {
9405
- const addresses = this.provider.getAddresses();
9406
- const solanaAddress = addresses.find((a) => a.addressType === "Solana");
9407
- if (solanaAddress) {
9408
- this.updateConnectionState(true, solanaAddress.address);
9409
- }
9410
- }
9411
- }
9412
- updateConnectionState(connected, publicKey) {
9413
- this._connected = connected;
9414
- this._publicKey = publicKey;
9447
+ if (!this.provider.isConnected())
9448
+ return;
9449
+ const addresses = this.provider.getAddresses();
9450
+ const solanaAddr = addresses.find((a) => a.addressType === "Solana");
9451
+ this._publicKey = solanaAddr?.address || null;
9415
9452
  }
9416
9453
  // Event methods for interface compliance
9417
9454
  on(event, listener) {
@@ -9425,16 +9462,11 @@ var EmbeddedEthereumChain = class {
9425
9462
  constructor(provider) {
9426
9463
  this.provider = provider;
9427
9464
  this.currentNetworkId = NetworkId.ETHEREUM_MAINNET;
9428
- this._connected = false;
9429
9465
  this._accounts = [];
9430
9466
  this.eventEmitter = new EventEmitter2();
9431
9467
  this.setupEventListeners();
9432
9468
  this.syncInitialState();
9433
9469
  }
9434
- // EIP-1193 compliant properties
9435
- get connected() {
9436
- return this._connected;
9437
- }
9438
9470
  get chainId() {
9439
9471
  const chainId = networkIdToChainId(this.currentNetworkId) || 1;
9440
9472
  return `0x${chainId.toString(16)}`;
@@ -9458,7 +9490,7 @@ var EmbeddedEthereumChain = class {
9458
9490
  }
9459
9491
  const addresses = this.provider.getAddresses();
9460
9492
  const ethAddresses = addresses.filter((a) => a.addressType === "Ethereum").map((a) => a.address);
9461
- this.updateConnectionState(true, ethAddresses);
9493
+ this.updateConnectionState(ethAddresses);
9462
9494
  return Promise.resolve(ethAddresses);
9463
9495
  }
9464
9496
  async disconnect() {
@@ -9524,19 +9556,19 @@ var EmbeddedEthereumChain = class {
9524
9556
  return this.request({ method: "eth_accounts" });
9525
9557
  }
9526
9558
  isConnected() {
9527
- return this._connected && this.provider.isConnected();
9559
+ return this.provider.isConnected() && this._accounts.length > 0;
9528
9560
  }
9529
9561
  setupEventListeners() {
9530
9562
  this.provider.on("connect", (data) => {
9531
9563
  const ethAddresses = data.addresses?.filter((addr) => addr.addressType === "Ethereum")?.map((addr) => addr.address) || [];
9532
9564
  if (ethAddresses.length > 0) {
9533
- this.updateConnectionState(true, ethAddresses);
9565
+ this.updateConnectionState(ethAddresses);
9534
9566
  this.eventEmitter.emit("connect", { chainId: this.chainId });
9535
9567
  this.eventEmitter.emit("accountsChanged", ethAddresses);
9536
9568
  }
9537
9569
  });
9538
9570
  this.provider.on("disconnect", () => {
9539
- this.updateConnectionState(false, []);
9571
+ this.updateConnectionState([]);
9540
9572
  this.eventEmitter.emit("disconnect", { code: 4900, message: "Provider disconnected" });
9541
9573
  this.eventEmitter.emit("accountsChanged", []);
9542
9574
  });
@@ -9546,12 +9578,11 @@ var EmbeddedEthereumChain = class {
9546
9578
  const addresses = this.provider.getAddresses();
9547
9579
  const ethAddresses = addresses.filter((a) => a.addressType === "Ethereum").map((a) => a.address);
9548
9580
  if (ethAddresses.length > 0) {
9549
- this.updateConnectionState(true, ethAddresses);
9581
+ this.updateConnectionState(ethAddresses);
9550
9582
  }
9551
9583
  }
9552
9584
  }
9553
- updateConnectionState(connected, accounts) {
9554
- this._connected = connected;
9585
+ updateConnectionState(accounts) {
9555
9586
  this._accounts = accounts;
9556
9587
  }
9557
9588
  async handleEmbeddedRequest(args) {
@@ -9627,7 +9658,7 @@ async function retryWithBackoff(operation, operationName, logger, maxRetries = 3
9627
9658
  let lastError;
9628
9659
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
9629
9660
  try {
9630
- logger.log("EMBEDDED_PROVIDER", `Attempting ${operationName}`, {
9661
+ logger.debug("EMBEDDED_PROVIDER", `Attempting ${operationName}`, {
9631
9662
  attempt,
9632
9663
  maxRetries
9633
9664
  });
@@ -9646,7 +9677,7 @@ async function retryWithBackoff(operation, operationName, logger, maxRetries = 3
9646
9677
  break;
9647
9678
  }
9648
9679
  const delay = baseDelay * Math.pow(2, attempt - 1);
9649
- logger.log("EMBEDDED_PROVIDER", `Retrying ${operationName} in ${delay}ms`, {
9680
+ logger.debug("EMBEDDED_PROVIDER", `Retrying ${operationName} in ${delay}ms`, {
9650
9681
  attempt: attempt + 1,
9651
9682
  delay
9652
9683
  });
@@ -9662,6 +9693,16 @@ function generateSessionId() {
9662
9693
  }
9663
9694
 
9664
9695
  // src/embedded-provider.ts
9696
+ var noopLogger = {
9697
+ info: () => {
9698
+ },
9699
+ warn: () => {
9700
+ },
9701
+ error: () => {
9702
+ },
9703
+ debug: () => {
9704
+ }
9705
+ };
9665
9706
  var EmbeddedProvider$1 = class EmbeddedProvider {
9666
9707
  constructor(config, platform, logger) {
9667
9708
  this.client = null;
@@ -9669,7 +9710,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9669
9710
  this.addresses = [];
9670
9711
  this.eventListeners = /* @__PURE__ */ new Map();
9671
9712
  this.logger = logger;
9672
- this.logger.log("EMBEDDED_PROVIDER", "Initializing EmbeddedProvider", { config });
9713
+ this.logger.debug("EMBEDDED_PROVIDER", "Initializing EmbeddedProvider", { config });
9673
9714
  if (config.embeddedWalletType === "app-wallet") {
9674
9715
  throw new Error("app-wallet type is not currently supported. Please use 'user-wallet' instead.");
9675
9716
  }
@@ -9692,19 +9733,19 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9692
9733
  this.eventListeners.set(event, /* @__PURE__ */ new Set());
9693
9734
  }
9694
9735
  this.eventListeners.get(event)?.add(callback);
9695
- this.logger.log("EMBEDDED_PROVIDER", "Event listener added", { event });
9736
+ this.logger.debug("EMBEDDED_PROVIDER", "Event listener added", { event });
9696
9737
  }
9697
9738
  off(event, callback) {
9698
9739
  const listeners = this.eventListeners.get(event);
9699
9740
  if (listeners) {
9700
9741
  listeners.delete(callback);
9701
- this.logger.log("EMBEDDED_PROVIDER", "Event listener removed", { event });
9742
+ this.logger.debug("EMBEDDED_PROVIDER", "Event listener removed", { event });
9702
9743
  }
9703
9744
  }
9704
9745
  emit(event, data) {
9705
9746
  const listeners = this.eventListeners.get(event);
9706
9747
  if (listeners && listeners.size > 0) {
9707
- this.logger.log("EMBEDDED_PROVIDER", "Emitting event", { event, listenerCount: listeners.size, data });
9748
+ this.logger.debug("EMBEDDED_PROVIDER", "Emitting event", { event, listenerCount: listeners.size, data });
9708
9749
  listeners.forEach((callback) => {
9709
9750
  try {
9710
9751
  callback(data);
@@ -9772,14 +9813,15 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9772
9813
  async validateAndCleanSession(session) {
9773
9814
  if (!session)
9774
9815
  return null;
9775
- this.logger.log("EMBEDDED_PROVIDER", "Found existing session, validating", {
9816
+ this.logger.debug("EMBEDDED_PROVIDER", "Found existing session, validating", {
9776
9817
  sessionId: session.sessionId,
9777
9818
  status: session.status,
9778
9819
  walletId: session.walletId
9779
9820
  });
9780
9821
  if (session.status !== "completed") {
9781
9822
  const urlSessionId = this.urlParamsAccessor.getParam("session_id");
9782
- if (session.status === "pending" && !urlSessionId) {
9823
+ const urlCode = this.urlParamsAccessor.getParam("code");
9824
+ if (session.status === "pending" && !urlSessionId && !urlCode) {
9783
9825
  this.logger.warn("EMBEDDED_PROVIDER", "Session mismatch detected - pending session without redirect context", {
9784
9826
  sessionId: session.sessionId,
9785
9827
  status: session.status
@@ -9817,11 +9859,11 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9817
9859
  * Returns ConnectResult if connection succeeds, null if should continue with new auth flow.
9818
9860
  */
9819
9861
  async tryExistingConnection(isAutoConnect) {
9820
- this.logger.log("EMBEDDED_PROVIDER", "Getting existing session");
9862
+ this.logger.debug("EMBEDDED_PROVIDER", "Getting existing session");
9821
9863
  let session = await this.storage.getSession();
9822
9864
  session = await this.validateAndCleanSession(session);
9823
9865
  if (!session) {
9824
- this.logger.log("EMBEDDED_PROVIDER", "No existing session found");
9866
+ this.logger.debug("EMBEDDED_PROVIDER", "No existing session found");
9825
9867
  return null;
9826
9868
  }
9827
9869
  if (session.status === "completed") {
@@ -9850,9 +9892,9 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9850
9892
  });
9851
9893
  return result;
9852
9894
  }
9853
- this.logger.log("EMBEDDED_PROVIDER", "No completed session found, checking for redirect resume");
9895
+ this.logger.debug("EMBEDDED_PROVIDER", "No completed session found, checking for redirect resume");
9854
9896
  if (this.authProvider.resumeAuthFromRedirect) {
9855
- const authResult = this.authProvider.resumeAuthFromRedirect(session.authProvider);
9897
+ const authResult = await this.authProvider.resumeAuthFromRedirect(session.authProvider);
9856
9898
  if (authResult) {
9857
9899
  this.logger.info("EMBEDDED_PROVIDER", "Resuming from redirect", {
9858
9900
  walletId: authResult.walletId,
@@ -9900,7 +9942,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9900
9942
  return false;
9901
9943
  }
9902
9944
  if (!session.walletId || !session.organizationId || !session.stamperInfo) {
9903
- this.logger.log("EMBEDDED_PROVIDER", "Session missing required fields", {
9945
+ this.logger.debug("EMBEDDED_PROVIDER", "Session missing required fields", {
9904
9946
  hasWalletId: !!session.walletId,
9905
9947
  hasOrganizationId: !!session.organizationId,
9906
9948
  hasStamperInfo: !!session.stamperInfo
@@ -9908,23 +9950,23 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9908
9950
  return false;
9909
9951
  }
9910
9952
  if (session.status !== "completed") {
9911
- this.logger.log("EMBEDDED_PROVIDER", "Session not completed", { status: session.status });
9953
+ this.logger.debug("EMBEDDED_PROVIDER", "Session not completed", { status: session.status });
9912
9954
  return false;
9913
9955
  }
9914
9956
  if (!session.authenticatorExpiresAt) {
9915
- this.logger.log("EMBEDDED_PROVIDER", "Session invalid - missing authenticator timing", {
9957
+ this.logger.debug("EMBEDDED_PROVIDER", "Session invalid - missing authenticator timing", {
9916
9958
  sessionId: session.sessionId
9917
9959
  });
9918
9960
  return false;
9919
9961
  }
9920
9962
  if (Date.now() >= session.authenticatorExpiresAt) {
9921
- this.logger.log("EMBEDDED_PROVIDER", "Authenticator expired, session invalid", {
9963
+ this.logger.debug("EMBEDDED_PROVIDER", "Authenticator expired, session invalid", {
9922
9964
  authenticatorExpiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
9923
9965
  now: (/* @__PURE__ */ new Date()).toISOString()
9924
9966
  });
9925
9967
  return false;
9926
9968
  }
9927
- this.logger.log("EMBEDDED_PROVIDER", "Session is valid", {
9969
+ this.logger.debug("EMBEDDED_PROVIDER", "Session is valid", {
9928
9970
  sessionId: session.sessionId,
9929
9971
  walletId: session.walletId,
9930
9972
  authenticatorExpires: new Date(session.authenticatorExpiresAt).toISOString()
@@ -9938,7 +9980,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9938
9980
  */
9939
9981
  async autoConnect() {
9940
9982
  try {
9941
- this.logger.log("EMBEDDED_PROVIDER", "Starting auto-connect attempt");
9983
+ this.logger.debug("EMBEDDED_PROVIDER", "Starting auto-connect attempt");
9942
9984
  this.emit("connect_start", { source: "auto-connect" });
9943
9985
  const result = await this.tryExistingConnection(true);
9944
9986
  if (result) {
@@ -9952,7 +9994,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9952
9994
  });
9953
9995
  return;
9954
9996
  }
9955
- this.logger.log("EMBEDDED_PROVIDER", "Auto-connect failed: no valid session found");
9997
+ this.logger.debug("EMBEDDED_PROVIDER", "Auto-connect failed: no valid session found");
9956
9998
  this.emit("connect_error", {
9957
9999
  error: "No valid session found",
9958
10000
  source: "auto-connect"
@@ -9973,11 +10015,11 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9973
10015
  * This is the first step when no existing session is found and we need to set up a new wallet.
9974
10016
  */
9975
10017
  async initializeStamper() {
9976
- this.logger.log("EMBEDDED_PROVIDER", "Initializing stamper");
10018
+ this.logger.debug("EMBEDDED_PROVIDER", "Initializing stamper");
9977
10019
  await this.stamper.init();
9978
- this.logger.log("EMBEDDED_PROVIDER", "Resetting keypair to avoid conflicts with existing keypairs");
10020
+ this.logger.debug("EMBEDDED_PROVIDER", "Resetting keypair to avoid conflicts with existing keypairs");
9979
10021
  const stamperInfo = await this.stamper.resetKeyPair();
9980
- this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized with fresh keypair", {
10022
+ this.logger.debug("EMBEDDED_PROVIDER", "Stamper initialized with fresh keypair", {
9981
10023
  publicKey: stamperInfo.publicKey,
9982
10024
  keyId: stamperInfo.keyId,
9983
10025
  algorithm: this.stamper.algorithm
@@ -9994,17 +10036,18 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9994
10036
  apiBaseUrl: this.config.apiBaseUrl,
9995
10037
  headers: {
9996
10038
  ...this.platform.analyticsHeaders || {}
9997
- }
10039
+ },
10040
+ logger: noopLogger
9998
10041
  });
9999
10042
  const platformName = this.platform.name || "unknown";
10000
10043
  const shortPubKey = stamperInfo.publicKey.slice(0, 8);
10001
10044
  const organizationName = `${this.config.appId.substring(0, 8)}-${platformName}-${shortPubKey}`;
10002
- this.logger.log("EMBEDDED_PROVIDER", "Creating organization for app-wallet", {
10045
+ this.logger.debug("EMBEDDED_PROVIDER", "Creating organization for app-wallet", {
10003
10046
  organizationName,
10004
10047
  publicKey: stamperInfo.publicKey,
10005
10048
  platform: platformName
10006
10049
  });
10007
- const base64urlPublicKey = base64urlEncode(index_native.base58.decode(stamperInfo.publicKey));
10050
+ const base64urlPublicKey = base64urlEncode(index_native.bs582.decode(stamperInfo.publicKey));
10008
10051
  const username = `user-${randomUUID()}`;
10009
10052
  const { organizationId } = await tempClient.createOrganization(organizationName, [
10010
10053
  {
@@ -10015,7 +10058,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10015
10058
  authenticatorName: `auth-${shortPubKey}`,
10016
10059
  authenticatorKind: "keypair",
10017
10060
  publicKey: base64urlPublicKey,
10018
- algorithm: "Ed25519",
10061
+ algorithm: this.stamper.algorithm,
10019
10062
  expiresInMs
10020
10063
  }
10021
10064
  ]
@@ -10119,7 +10162,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10119
10162
  async disconnect(shouldClearPreviousSession = true) {
10120
10163
  const wasConnected = this.client !== null;
10121
10164
  await this.storage.setShouldClearPreviousSession(shouldClearPreviousSession);
10122
- this.logger.log("EMBEDDED_PROVIDER", "Set flag to clear previous session on next login");
10165
+ this.logger.debug("EMBEDDED_PROVIDER", "Set flag to clear previous session on next login");
10123
10166
  await this.storage.clearSession();
10124
10167
  this.client = null;
10125
10168
  this.walletId = null;
@@ -10131,6 +10174,21 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10131
10174
  });
10132
10175
  }
10133
10176
  }
10177
+ /**
10178
+ * Handles errors from signing operations.
10179
+ * Disconnects the user if the server returns a 401/403 (revoked or expired authenticator).
10180
+ */
10181
+ async handleSigningError(error) {
10182
+ if (isAuthenticationError(error)) {
10183
+ this.logger.warn("EMBEDDED_PROVIDER", "Authenticator rejected by server (401/403), disconnecting", { error });
10184
+ await this.disconnect(false);
10185
+ throw new Error("Authenticator revoked");
10186
+ }
10187
+ if (error instanceof SpendingLimitError) {
10188
+ this.emit("spending_limit_reached", { error });
10189
+ }
10190
+ throw error;
10191
+ }
10134
10192
  async signMessage(params) {
10135
10193
  if (!this.client || !this.walletId) {
10136
10194
  throw new Error("Not connected");
@@ -10147,7 +10205,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10147
10205
  message: params.message,
10148
10206
  networkId: params.networkId,
10149
10207
  derivationIndex
10150
- });
10208
+ }).catch((error) => this.handleSigningError(error));
10151
10209
  this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
10152
10210
  walletId: this.walletId,
10153
10211
  message: params.message
@@ -10180,7 +10238,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10180
10238
  message: base64UrlMessage,
10181
10239
  networkId: params.networkId,
10182
10240
  derivationIndex
10183
- });
10241
+ }).catch((error) => this.handleSigningError(error));
10184
10242
  this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
10185
10243
  walletId: this.walletId,
10186
10244
  message: params.message
@@ -10203,7 +10261,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10203
10261
  typedData: params.typedData,
10204
10262
  networkId: params.networkId,
10205
10263
  derivationIndex
10206
- });
10264
+ }).catch((error) => this.handleSigningError(error));
10207
10265
  this.logger.info("EMBEDDED_PROVIDER", "Typed data signed successfully", {
10208
10266
  walletId: this.walletId
10209
10267
  });
@@ -10221,7 +10279,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10221
10279
  const parsedTransaction = await parseToKmsTransaction(params.transaction, params.networkId);
10222
10280
  const session = await this.storage.getSession();
10223
10281
  const derivationIndex = session?.accountDerivationIndex ?? 0;
10224
- this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10282
+ this.logger.debug("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10225
10283
  walletId: this.walletId,
10226
10284
  transaction: parsedTransaction,
10227
10285
  derivationIndex
@@ -10240,7 +10298,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10240
10298
  networkId: params.networkId,
10241
10299
  derivationIndex,
10242
10300
  account
10243
- });
10301
+ }).catch((error) => this.handleSigningError(error));
10244
10302
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed successfully", {
10245
10303
  walletId: this.walletId,
10246
10304
  networkId: params.networkId,
@@ -10260,7 +10318,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10260
10318
  const parsedTransaction = await parseToKmsTransaction(params.transaction, params.networkId);
10261
10319
  const session = await this.storage.getSession();
10262
10320
  const derivationIndex = session?.accountDerivationIndex ?? 0;
10263
- this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10321
+ this.logger.debug("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10264
10322
  walletId: this.walletId,
10265
10323
  transaction: parsedTransaction,
10266
10324
  derivationIndex
@@ -10273,21 +10331,14 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10273
10331
  if (!account) {
10274
10332
  throw new Error(`No address found for network ${params.networkId}`);
10275
10333
  }
10276
- let rawResponse;
10277
- try {
10278
- rawResponse = await this.client.signAndSendTransaction({
10279
- walletId: this.walletId,
10280
- transaction: transactionPayload,
10281
- networkId: params.networkId,
10282
- derivationIndex,
10283
- account
10284
- });
10285
- } catch (error) {
10286
- if (error instanceof SpendingLimitError) {
10287
- this.emit("spending_limit_reached", { error });
10288
- }
10289
- throw error;
10290
- }
10334
+ const rawResponse = await this.client.signAndSendTransaction({
10335
+ walletId: this.walletId,
10336
+ transaction: transactionPayload,
10337
+ networkId: params.networkId,
10338
+ derivationIndex,
10339
+ account,
10340
+ presignTransaction: params.presignTransaction
10341
+ }).catch((error) => this.handleSigningError(error));
10291
10342
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
10292
10343
  walletId: this.walletId,
10293
10344
  networkId: params.networkId,
@@ -10332,7 +10383,8 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10332
10383
  organizationId,
10333
10384
  headers: {
10334
10385
  ...this.platform.analyticsHeaders || {}
10335
- }
10386
+ },
10387
+ logger: noopLogger
10336
10388
  },
10337
10389
  this.stamper
10338
10390
  );
@@ -10411,7 +10463,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10411
10463
  lastRenewalAttempt: void 0,
10412
10464
  authUserId: authResult.authUserId
10413
10465
  };
10414
- this.logger.log("EMBEDDED_PROVIDER", "Saving Phantom session");
10466
+ this.logger.debug("EMBEDDED_PROVIDER", "Saving Phantom session");
10415
10467
  await this.storage.saveSession(session);
10416
10468
  return session;
10417
10469
  }
@@ -10446,7 +10498,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10446
10498
  authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,
10447
10499
  lastRenewalAttempt: void 0
10448
10500
  };
10449
- this.logger.log("EMBEDDED_PROVIDER", "Saving temporary session before redirect", {
10501
+ this.logger.debug("EMBEDDED_PROVIDER", "Saving temporary session before redirect", {
10450
10502
  sessionId: tempSession.sessionId,
10451
10503
  tempWalletId: tempSession.walletId
10452
10504
  });
@@ -10471,8 +10523,9 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10471
10523
  // OAuth session management - defaults to allowing refresh unless user explicitly logged out
10472
10524
  clearPreviousSession: shouldClearPreviousSession,
10473
10525
  // true only after logout
10474
- allowRefresh: !shouldClearPreviousSession
10526
+ allowRefresh: !shouldClearPreviousSession,
10475
10527
  // false only after logout
10528
+ algorithm: this.stamper.algorithm
10476
10529
  });
10477
10530
  if (authResult && "walletId" in authResult) {
10478
10531
  this.logger.info("EMBEDDED_PROVIDER", "Authentication completed after redirect", {
@@ -10485,20 +10538,21 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10485
10538
  tempSession.authProvider = authResult.provider || tempSession.authProvider;
10486
10539
  tempSession.accountDerivationIndex = authResult.accountDerivationIndex;
10487
10540
  tempSession.authUserId = authResult.authUserId;
10541
+ tempSession.bearerToken = authResult.bearerToken;
10488
10542
  tempSession.status = "completed";
10489
10543
  tempSession.lastUsed = Date.now();
10490
10544
  if (authResult.expiresInMs > 0) {
10491
10545
  const now2 = Date.now();
10492
10546
  tempSession.authenticatorCreatedAt = now2;
10493
10547
  tempSession.authenticatorExpiresAt = now2 + authResult.expiresInMs;
10494
- this.logger.log("EMBEDDED_PROVIDER", "Updated authenticator expiration from immediate auth response", {
10548
+ this.logger.debug("EMBEDDED_PROVIDER", "Updated authenticator expiration from immediate auth response", {
10495
10549
  expiresInMs: authResult.expiresInMs,
10496
10550
  expiresAt: new Date(tempSession.authenticatorExpiresAt).toISOString()
10497
10551
  });
10498
10552
  }
10499
10553
  await this.storage.saveSession(tempSession);
10500
10554
  await this.storage.setShouldClearPreviousSession(false);
10501
- this.logger.log("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10555
+ this.logger.debug("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10502
10556
  return tempSession;
10503
10557
  }
10504
10558
  this.logger.info("EMBEDDED_PROVIDER", "Redirect authentication initiated, waiting for redirect completion");
@@ -10514,20 +10568,21 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10514
10568
  session.organizationId = authResult.organizationId;
10515
10569
  session.accountDerivationIndex = authResult.accountDerivationIndex;
10516
10570
  session.authUserId = authResult.authUserId;
10571
+ session.bearerToken = authResult.bearerToken;
10517
10572
  session.status = "completed";
10518
10573
  session.lastUsed = Date.now();
10519
10574
  if (authResult.expiresInMs > 0) {
10520
10575
  const now = Date.now();
10521
10576
  session.authenticatorCreatedAt = now;
10522
10577
  session.authenticatorExpiresAt = now + authResult.expiresInMs;
10523
- this.logger.log("EMBEDDED_PROVIDER", "Updated authenticator expiration from auth response", {
10578
+ this.logger.debug("EMBEDDED_PROVIDER", "Updated authenticator expiration from auth response", {
10524
10579
  expiresInMs: authResult.expiresInMs,
10525
10580
  expiresAt: new Date(session.authenticatorExpiresAt).toISOString()
10526
10581
  });
10527
10582
  }
10528
10583
  await this.storage.saveSession(session);
10529
10584
  await this.storage.setShouldClearPreviousSession(false);
10530
- this.logger.log("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10585
+ this.logger.debug("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10531
10586
  await this.initializeClientFromSession(session);
10532
10587
  await this.ensureValidAuthenticator();
10533
10588
  return {
@@ -10554,7 +10609,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10554
10609
  throw new Error("Invalid session - missing authenticator timing");
10555
10610
  }
10556
10611
  const timeUntilExpiry = session.authenticatorExpiresAt - now;
10557
- this.logger.log("EMBEDDED_PROVIDER", "Checking authenticator expiration", {
10612
+ this.logger.debug("EMBEDDED_PROVIDER", "Checking authenticator expiration", {
10558
10613
  expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
10559
10614
  timeUntilExpiry
10560
10615
  });
@@ -10569,7 +10624,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10569
10624
  * This is the final step that sets up the provider's client state and retrieves available addresses.
10570
10625
  */
10571
10626
  async initializeClientFromSession(session) {
10572
- this.logger.log("EMBEDDED_PROVIDER", "Initializing PhantomClient from session", {
10627
+ this.logger.debug("EMBEDDED_PROVIDER", "Initializing PhantomClient from session", {
10573
10628
  organizationId: session.organizationId,
10574
10629
  walletId: session.walletId,
10575
10630
  appId: session.appId
@@ -10583,7 +10638,8 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10583
10638
  organizationId: session.organizationId,
10584
10639
  headers: {
10585
10640
  ...this.platform.analyticsHeaders || {},
10586
- ...session.authUserId ? { "x-auth-user-id": session.authUserId } : {}
10641
+ ...session.authUserId ? { "x-auth-user-id": session.authUserId } : {},
10642
+ ...session.bearerToken ? { Authorization: session.bearerToken } : {}
10587
10643
  }
10588
10644
  },
10589
10645
  this.stamper
@@ -10594,14 +10650,23 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10594
10650
  };
10595
10651
 
10596
10652
  // src/index.ts
10653
+ var WEB_CRYPTO_ALGORITHM_CONFIGS = {
10654
+ [DEFAULT_AUTHENTICATOR_ALGORITHM]: {
10655
+ generateParams: { name: "Ed25519" },
10656
+ signParams: { name: "Ed25519" }
10657
+ },
10658
+ [Algorithm.secp256r1]: {
10659
+ generateParams: { name: "ECDSA", namedCurve: "P-256" },
10660
+ signParams: { name: "ECDSA", hash: "SHA-256" }
10661
+ }
10662
+ };
10597
10663
  var IndexedDbStamper = class {
10598
10664
  // Optional for PKI, required for OIDC
10599
10665
  constructor(config = {}) {
10600
10666
  this.db = null;
10601
10667
  this.activeKeyPairRecord = null;
10602
10668
  this.pendingKeyPairRecord = null;
10603
- this.algorithm = Algorithm.ed25519;
10604
- // Use Ed25519 for maximum security and performance
10669
+ this.algorithm = DEFAULT_AUTHENTICATOR_ALGORITHM;
10605
10670
  // The type of stamper, can be changed at any time
10606
10671
  this.type = "PKI";
10607
10672
  if (typeof window === "undefined" || !window.indexedDB) {
@@ -10615,17 +10680,34 @@ var IndexedDbStamper = class {
10615
10680
  this.salt = config.salt;
10616
10681
  }
10617
10682
  /**
10618
- * Initialize the stamper by opening IndexedDB and retrieving or generating keys
10683
+ * Initialize the stamper by opening IndexedDB and retrieving or generating keys.
10684
+ * Automatically selects the best supported algorithm.
10619
10685
  */
10620
10686
  async init() {
10621
10687
  await this.openDB();
10622
10688
  this.activeKeyPairRecord = await this.loadActiveKeyPairRecord();
10623
- if (!this.activeKeyPairRecord) {
10689
+ if (this.activeKeyPairRecord) {
10690
+ this.algorithm = this.activeKeyPairRecord.keyPair.privateKey.algorithm.name === "Ed25519" ? Algorithm.ed25519 : Algorithm.secp256r1;
10691
+ } else {
10692
+ this.algorithm = await this.getSupportedAlgorithm();
10624
10693
  this.activeKeyPairRecord = await this.generateAndStoreNewKeyPair("active");
10625
10694
  }
10626
10695
  this.pendingKeyPairRecord = await this.loadPendingKeyPairRecord();
10627
10696
  return this.activeKeyPairRecord.keyInfo;
10628
10697
  }
10698
+ async getSupportedAlgorithm() {
10699
+ for (const [algorithm, params] of Object.entries(WEB_CRYPTO_ALGORITHM_CONFIGS)) {
10700
+ try {
10701
+ await crypto.subtle.generateKey(params.generateParams, false, ["sign", "verify"]);
10702
+ return algorithm;
10703
+ } catch {
10704
+ continue;
10705
+ }
10706
+ }
10707
+ throw new Error(
10708
+ "Your browser does not support the encryption needed for secure authentication. Please use a different browser or upgrade to a supported browser."
10709
+ );
10710
+ }
10629
10711
  /**
10630
10712
  * Get the public key information
10631
10713
  */
@@ -10653,10 +10735,7 @@ var IndexedDbStamper = class {
10653
10735
  }
10654
10736
  const dataBytes = new Uint8Array(data);
10655
10737
  const signature = await crypto.subtle.sign(
10656
- {
10657
- name: this.algorithm,
10658
- hash: "SHA-256"
10659
- },
10738
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].signParams,
10660
10739
  this.activeKeyPairRecord.keyPair.privateKey,
10661
10740
  dataBytes
10662
10741
  );
@@ -10666,14 +10745,14 @@ var IndexedDbStamper = class {
10666
10745
  const salt = params.type === "OIDC" ? params.salt : this.salt;
10667
10746
  const stampData = stampType === "PKI" ? {
10668
10747
  // Decode base58 public key to bytes, then encode as base64url (consistent with ApiKeyStamper)
10669
- publicKey: base64urlEncode(index_native.base58.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10748
+ publicKey: base64urlEncode(index_native.bs582.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10670
10749
  signature: signatureBase64url,
10671
10750
  kind: "PKI",
10672
10751
  algorithm: this.algorithm
10673
10752
  } : {
10674
10753
  kind: "OIDC",
10675
10754
  idToken,
10676
- publicKey: base64urlEncode(index_native.base58.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10755
+ publicKey: base64urlEncode(index_native.bs582.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10677
10756
  salt,
10678
10757
  algorithm: this.algorithm,
10679
10758
  signature: signatureBase64url
@@ -10768,15 +10847,13 @@ var IndexedDbStamper = class {
10768
10847
  }
10769
10848
  async generateAndStoreNewKeyPair(type) {
10770
10849
  const keyPair = await crypto.subtle.generateKey(
10771
- {
10772
- name: "Ed25519"
10773
- },
10850
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].generateParams,
10774
10851
  false,
10775
10852
  // non-extractable - private key can never be exported
10776
10853
  ["sign", "verify"]
10777
10854
  );
10778
10855
  const rawPublicKeyBuffer = await crypto.subtle.exportKey("raw", keyPair.publicKey);
10779
- const publicKeyBase58 = index_native.base58.encode(new Uint8Array(rawPublicKeyBuffer));
10856
+ const publicKeyBase58 = index_native.bs582.encode(new Uint8Array(rawPublicKeyBuffer));
10780
10857
  const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKeyBuffer);
10781
10858
  const keyId = base64urlEncode(new Uint8Array(keyIdBuffer)).substring(0, 16);
10782
10859
  const now = Date.now();
@@ -10846,15 +10923,301 @@ var IndexedDbStamper = class {
10846
10923
  }
10847
10924
  };
10848
10925
 
10849
- // src/types.ts
10850
-
10851
- // src/debug.ts
10852
- var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
10853
- DebugLevel2[DebugLevel2["ERROR"] = 0] = "ERROR";
10854
- DebugLevel2[DebugLevel2["WARN"] = 1] = "WARN";
10855
- DebugLevel2[DebugLevel2["INFO"] = 2] = "INFO";
10856
- DebugLevel2[DebugLevel2["DEBUG"] = 3] = "DEBUG";
10857
- return DebugLevel2;
10926
+ // src/index.ts
10927
+ var AUTH2_JAR_ALGORITHM = "ES256";
10928
+ var AUTH2_JAR_TYP = "oauth-authz-req+jwt";
10929
+ var textEncoder = new TextEncoder();
10930
+ async function createAuth2RequestJar(input) {
10931
+ const publicJwk = await globalThis.crypto.subtle.exportKey("jwk", input.keyPair.publicKey);
10932
+ if (!_isValidPublicJwk(publicJwk)) {
10933
+ throw new Error("Unable to export a valid P-256 public JWK for JAR header.");
10934
+ }
10935
+ const header = {
10936
+ alg: AUTH2_JAR_ALGORITHM,
10937
+ typ: AUTH2_JAR_TYP,
10938
+ jwk: {
10939
+ kty: "EC",
10940
+ crv: "P-256",
10941
+ x: publicJwk.x,
10942
+ y: publicJwk.y
10943
+ }
10944
+ };
10945
+ const encodedHeader = base64urlEncode(textEncoder.encode(JSON.stringify(header)));
10946
+ const encodedPayload = base64urlEncode(textEncoder.encode(JSON.stringify(input.payload)));
10947
+ const signingInput = `${encodedHeader}.${encodedPayload}`;
10948
+ const signature = await globalThis.crypto.subtle.sign(
10949
+ { name: "ECDSA", hash: "SHA-256" },
10950
+ input.keyPair.privateKey,
10951
+ textEncoder.encode(signingInput)
10952
+ );
10953
+ return `${signingInput}.${base64urlEncode(new Uint8Array(signature))}`;
10954
+ }
10955
+ function _isValidPublicJwk(jwk) {
10956
+ return jwk.kty === "EC" && jwk.crv === "P-256" && typeof jwk.x === "string" && typeof jwk.y === "string";
10957
+ }
10958
+ var DEFAULT_KMS_API_VERSION = "2025-11-24";
10959
+ var Auth2KmsRpcClient = class {
10960
+ constructor(stamper, options) {
10961
+ this.stamper = stamper;
10962
+ const axiosInstance = axios.create();
10963
+ axiosInstance.interceptors.request.use(async (config) => {
10964
+ config.headers = config.headers || {};
10965
+ config.headers["x-app-id"] = options.appId;
10966
+ config.headers["x-api-version"] = DEFAULT_KMS_API_VERSION;
10967
+ const tokens = await this.stamper.getTokens();
10968
+ if (tokens) {
10969
+ config.headers["authorization"] = tokens.bearerToken;
10970
+ }
10971
+ const requestBody = typeof config.data === "string" ? config.data : config.data === void 0 ? "" : JSON.stringify(config.data);
10972
+ const stamp = await this.stamper.stamp({ data: index_native.bufferExports.Buffer.from(requestBody, "utf-8") });
10973
+ config.headers["x-phantom-stamp"] = stamp;
10974
+ return config;
10975
+ });
10976
+ const configuration = new Configuration({ basePath: options.apiBaseUrl });
10977
+ this.kmsApi = new KMSRPCApi(configuration, options.apiBaseUrl, axiosInstance);
10978
+ }
10979
+ async postKmsRpc(request, bearerToken, authUserId) {
10980
+ const headers = { authorization: bearerToken };
10981
+ if (authUserId) {
10982
+ headers["x-auth-user-id"] = authUserId;
10983
+ }
10984
+ const response = await this.kmsApi.postKmsRpc(request, { headers });
10985
+ const rpcBody = response.data;
10986
+ if (rpcBody?.error) {
10987
+ throw new Error(`KMS RPC error: ${JSON.stringify(rpcBody.error)}`);
10988
+ }
10989
+ return response.data;
10990
+ }
10991
+ extractOrganizationId(body) {
10992
+ const result = body?.result;
10993
+ return extractStringFromPath(result, "organizationId", "organization_id");
10994
+ }
10995
+ async discoverOrganizationAndWalletId(bearerToken, authUserId) {
10996
+ const organizationId = await this.discoverOrganizationId(bearerToken, authUserId);
10997
+ if (!organizationId) {
10998
+ throw new Error("Unable to resolve organizationId. The Auth2 KMS did not return one.");
10999
+ }
11000
+ const walletId = await this.discoverWalletId(bearerToken, organizationId, authUserId);
11001
+ if (!walletId) {
11002
+ throw new Error("Unable to resolve walletId. The Auth2 KMS did not return or create one.");
11003
+ }
11004
+ return {
11005
+ organizationId,
11006
+ walletId
11007
+ };
11008
+ }
11009
+ async discoverOrganizationId(bearerToken, authUserId) {
11010
+ const keyInfo = this.stamper.getKeyInfo();
11011
+ if (!keyInfo) {
11012
+ throw new Error("Stamper not initialized");
11013
+ }
11014
+ const publicKey = base64urlEncode(index_native.bs582.decode(keyInfo.publicKey));
11015
+ const created = await this.postKmsRpc(
11016
+ {
11017
+ method: GetOrCreatePhantomOrganizationMethodEnum.getOrCreatePhantomOrganization,
11018
+ params: { publicKey },
11019
+ timestampMs: Date.now()
11020
+ },
11021
+ bearerToken,
11022
+ authUserId
11023
+ );
11024
+ return this.extractOrganizationId(created);
11025
+ }
11026
+ async discoverWalletId(bearerToken, organizationId, authUserId) {
11027
+ const listResponse = await this.postKmsRpc(
11028
+ {
11029
+ method: GetOrganizationWalletsMethodEnum.getOrganizationWallets,
11030
+ params: { organizationId, limit: 20, offset: 0 },
11031
+ timestampMs: Date.now()
11032
+ },
11033
+ bearerToken,
11034
+ authUserId
11035
+ );
11036
+ const result = listResponse?.result;
11037
+ const wallets = result?.wallets;
11038
+ if (Array.isArray(wallets) && wallets.length > 0) {
11039
+ return extractStringFromPath(wallets[0], "walletId", "wallet_id");
11040
+ }
11041
+ const createResponse = await this.postKmsRpc(
11042
+ {
11043
+ method: CreateWalletMethodEnum.createWallet,
11044
+ params: {
11045
+ walletName: `Auth2 SDK Wallet ${Date.now()}`,
11046
+ organizationId,
11047
+ accounts: [
11048
+ { curve: "Ed25519", derivationPath: "m/44'/501'/0'/0'", addressFormat: "Solana" },
11049
+ { curve: "Secp256k1", derivationPath: "m/44'/60'/0'/0/0", addressFormat: "Ethereum" },
11050
+ { curve: "Secp256k1", derivationPath: "m/84'/0'/0'/0", addressFormat: "BitcoinSegwit" },
11051
+ { curve: "Ed25519", derivationPath: "m/44'/784'/0'/0'/0'", addressFormat: "Sui" }
11052
+ ]
11053
+ },
11054
+ timestampMs: Date.now()
11055
+ },
11056
+ bearerToken,
11057
+ authUserId
11058
+ );
11059
+ const createResult = createResponse?.result;
11060
+ return extractStringFromPath(createResult, "walletId", "wallet_id");
11061
+ }
11062
+ };
11063
+ function extractStringFromPath(obj, ...keys) {
11064
+ if (!obj || typeof obj !== "object") {
11065
+ return null;
11066
+ }
11067
+ for (const key of keys) {
11068
+ const val = obj[key];
11069
+ if (typeof val === "string" && val.trim().length > 0) {
11070
+ return val.trim();
11071
+ }
11072
+ }
11073
+ return null;
11074
+ }
11075
+
11076
+ // src/index.ts
11077
+ var DEFAULT_SCOPE = "openid offline_access";
11078
+ function createCodeVerifier() {
11079
+ const bytes = new Uint8Array(64);
11080
+ crypto.getRandomValues(bytes);
11081
+ return base64urlEncode(bytes).slice(0, 96);
11082
+ }
11083
+ async function createConnectStartUrl({
11084
+ keyPair,
11085
+ connectLoginUrl,
11086
+ clientId,
11087
+ redirectUri,
11088
+ sessionId,
11089
+ provider,
11090
+ codeVerifier,
11091
+ salt
11092
+ }) {
11093
+ const nonce = await _deriveNonce(keyPair, salt);
11094
+ const codeChallenge = await _createCodeChallenge(codeVerifier);
11095
+ const nowSeconds = Math.floor(Date.now() / 1e3);
11096
+ const jarPayload = {
11097
+ aud: connectLoginUrl,
11098
+ iat: nowSeconds,
11099
+ exp: nowSeconds + 5 * 60,
11100
+ // 5 minutes
11101
+ client_id: clientId,
11102
+ redirect_uri: redirectUri,
11103
+ scope: DEFAULT_SCOPE,
11104
+ nonce,
11105
+ code_challenge: codeChallenge,
11106
+ code_challenge_method: "S256",
11107
+ ...provider && provider !== "phantom" && provider !== "device" && {
11108
+ login_hint: `${provider}:auth2`
11109
+ },
11110
+ // Use session_id as the OAuth state so it comes back in the callback URL
11111
+ // and can be validated without an extra sessionStorage entry.
11112
+ state: sessionId
11113
+ };
11114
+ const jar = await createAuth2RequestJar({
11115
+ payload: jarPayload,
11116
+ keyPair
11117
+ });
11118
+ const url = new URL(connectLoginUrl);
11119
+ url.hash = `jar=${jar}`;
11120
+ return url.toString();
11121
+ }
11122
+ async function _createCodeChallenge(codeVerifier) {
11123
+ return base64urlEncode(await sha256$2(new TextEncoder().encode(codeVerifier)));
11124
+ }
11125
+ async function _deriveNonce(keyPair, salt) {
11126
+ const publicKey = await crypto.subtle.exportKey("raw", keyPair.publicKey);
11127
+ const rawPublicKey = new Uint8Array(publicKey);
11128
+ const saltBytes = new TextEncoder().encode(salt);
11129
+ const combined = new Uint8Array(rawPublicKey.length + saltBytes.length);
11130
+ combined.set(rawPublicKey);
11131
+ combined.set(saltBytes, rawPublicKey.length);
11132
+ return base64urlEncode(await sha256$2(combined));
11133
+ }
11134
+ async function exchangeAuthCode(options) {
11135
+ return _postTokenRequest(
11136
+ options.authApiBaseUrl,
11137
+ new URLSearchParams({
11138
+ grant_type: "authorization_code",
11139
+ client_id: options.clientId,
11140
+ redirect_uri: options.redirectUri,
11141
+ code: options.code,
11142
+ code_verifier: options.codeVerifier
11143
+ })
11144
+ );
11145
+ }
11146
+ async function refreshToken(options) {
11147
+ const result = await _postTokenRequest(
11148
+ options.authApiBaseUrl,
11149
+ new URLSearchParams({
11150
+ grant_type: "refresh_token",
11151
+ client_id: options.clientId,
11152
+ redirect_uri: options.redirectUri,
11153
+ refresh_token: options.refreshToken
11154
+ })
11155
+ );
11156
+ if (!result.refreshToken) {
11157
+ throw new Error("Auth2 refresh token request did not return a refresh_token.");
11158
+ }
11159
+ return result;
11160
+ }
11161
+ async function _postTokenRequest(authApiBaseUrl, body) {
11162
+ const tokenEndpoint = new URL("/oauth2/token", authApiBaseUrl).toString();
11163
+ const tokenResponse = await fetch(tokenEndpoint, {
11164
+ method: "POST",
11165
+ headers: { "content-type": "application/x-www-form-urlencoded" },
11166
+ body: body.toString()
11167
+ });
11168
+ if (!tokenResponse.ok) {
11169
+ const text = await tokenResponse.text();
11170
+ throw new Error(`Auth2 token request failed (${tokenResponse.status} ${tokenResponse.statusText}): ${text}`);
11171
+ }
11172
+ const tokens = await tokenResponse.json();
11173
+ const accessToken = tokens.access_token;
11174
+ if (!accessToken) {
11175
+ throw new Error("Auth2 token request did not return an access_token.");
11176
+ }
11177
+ const idToken = tokens.id_token;
11178
+ if (!idToken) {
11179
+ throw new Error("Auth2 token request did not return an id_token.");
11180
+ }
11181
+ const bearerToken = `${tokens?.token_type ?? "Bearer"} ${accessToken}`;
11182
+ const authUserId = _parseJwtClaim(accessToken, ["sub"]) ?? void 0;
11183
+ const expiresInMs = tokens.expires_in != null ? tokens.expires_in * 1e3 : 0;
11184
+ return {
11185
+ idToken,
11186
+ bearerToken,
11187
+ authUserId,
11188
+ expiresInMs,
11189
+ refreshToken: tokens.refresh_token
11190
+ };
11191
+ }
11192
+ function _parseJwtClaim(token, keys) {
11193
+ try {
11194
+ const parts = token.split(".");
11195
+ if (parts.length < 2 || !parts[1]) {
11196
+ return null;
11197
+ }
11198
+ const padded = parts[1].replace(/-/g, "+").replace(/_/g, "/");
11199
+ const payload = JSON.parse(atob(padded));
11200
+ for (const key of keys) {
11201
+ const val = payload[key];
11202
+ if (typeof val === "string" && val.length > 0) {
11203
+ return val;
11204
+ }
11205
+ }
11206
+ return null;
11207
+ } catch {
11208
+ return null;
11209
+ }
11210
+ }
11211
+
11212
+ // src/types.ts
11213
+
11214
+ // src/debug.ts
11215
+ var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
11216
+ DebugLevel2[DebugLevel2["ERROR"] = 0] = "ERROR";
11217
+ DebugLevel2[DebugLevel2["WARN"] = 1] = "WARN";
11218
+ DebugLevel2[DebugLevel2["INFO"] = 2] = "INFO";
11219
+ DebugLevel2[DebugLevel2["DEBUG"] = 3] = "DEBUG";
11220
+ return DebugLevel2;
10858
11221
  })(DebugLevel || {});
10859
11222
  var Debug = class {
10860
11223
  constructor() {
@@ -10921,6 +11284,17 @@ var DebugCategory = {
10921
11284
  STORAGE: "Storage",
10922
11285
  SESSION: "Session"
10923
11286
  };
11287
+ var CUSTOM_WALLET_CONFIGS = [
11288
+ {
11289
+ id: "coinbase-wallet",
11290
+ name: "Coinbase Wallet",
11291
+ icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI4IDU2YzE1LjQ2NCAwIDI4LTEyLjUzNiAyOC0yOFM0My40NjQgMCAyOCAwIDAgMTIuNTM2IDAgMjhzMTIuNTM2IDI4IDI4IDI4WiIgZmlsbD0iIzFCNTNFNCIvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNyAyOGMwIDExLjU5OCA5LjQwMiAyMSAyMSAyMXMyMS05LjQwMiAyMS0yMVMzOS41OTggNyAyOCA3IDcgMTYuNDAyIDcgMjhabTE3LjIzNC02Ljc2NmEzIDMgMCAwIDAtMyAzdjcuNTMzYTMgMyAwIDAgMCAzIDNoNy41MzNhMyAzIDAgMCAwIDMtM3YtNy41MzNhMyAzIDAgMCAwLTMtM2gtNy41MzNaIiBmaWxsPSIjZmZmIi8+PC9zdmc+",
11292
+ windowProperty: "coinbaseSolana",
11293
+ addressTypes: [exports.AddressType.solana]
11294
+ }
11295
+ ];
11296
+
11297
+ // src/wallets/discovery.ts
10924
11298
  function generateWalletIdFromEIP6963(info) {
10925
11299
  if (info.rdns) {
10926
11300
  return info.rdns.split(".").reverse().join("-");
@@ -11184,6 +11558,51 @@ async function discoverSolanaWallets() {
11184
11558
  walletNames: wallets.map((w) => w.name)
11185
11559
  };
11186
11560
  debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard Solana discovery completed", finalLogData);
11561
+ const customWallets = discoverCustomSolanaWallets();
11562
+ wallets.push(...customWallets);
11563
+ return wallets;
11564
+ }
11565
+ function discoverCustomSolanaWallets() {
11566
+ const wallets = [];
11567
+ if (typeof window === "undefined") {
11568
+ debug.log(DebugCategory.BROWSER_SDK, "Custom wallet discovery skipped (not in browser environment)");
11569
+ return wallets;
11570
+ }
11571
+ debug.log(DebugCategory.BROWSER_SDK, "Starting custom Solana wallet discovery", {
11572
+ configCount: CUSTOM_WALLET_CONFIGS.length
11573
+ });
11574
+ for (const config of CUSTOM_WALLET_CONFIGS) {
11575
+ if (!config.addressTypes.includes(exports.AddressType.solana)) {
11576
+ continue;
11577
+ }
11578
+ const provider = window[config.windowProperty];
11579
+ if (!provider) {
11580
+ debug.log(DebugCategory.BROWSER_SDK, "Custom wallet not found", {
11581
+ walletId: config.id,
11582
+ windowProperty: config.windowProperty
11583
+ });
11584
+ continue;
11585
+ }
11586
+ debug.log(DebugCategory.BROWSER_SDK, "Discovered custom Solana wallet", {
11587
+ walletId: config.id,
11588
+ walletName: config.name,
11589
+ windowProperty: config.windowProperty
11590
+ });
11591
+ wallets.push({
11592
+ id: config.id,
11593
+ name: config.name,
11594
+ icon: config.icon,
11595
+ addressTypes: config.addressTypes,
11596
+ providers: {
11597
+ solana: provider
11598
+ },
11599
+ discovery: "custom"
11600
+ });
11601
+ }
11602
+ debug.log(DebugCategory.BROWSER_SDK, "Custom Solana wallet discovery completed", {
11603
+ discoveredCount: wallets.length,
11604
+ walletIds: wallets.map((w) => w.id)
11605
+ });
11187
11606
  return wallets;
11188
11607
  }
11189
11608
  function discoverPhantomWallet(addressTypes) {
@@ -11205,8 +11624,7 @@ function discoverPhantomWallet(addressTypes) {
11205
11624
  return {
11206
11625
  id: "phantom",
11207
11626
  name: "Phantom",
11208
- icon: void 0,
11209
- // Icon will be rendered from icons package in UI components
11627
+ icon: PHANTOM_ICON,
11210
11628
  addressTypes,
11211
11629
  providers: {
11212
11630
  solana: addressTypes.includes(exports.AddressType.solana) ? phantomInstance.solana : void 0,
@@ -11278,61 +11696,55 @@ var InjectedWalletSolanaChain = class {
11278
11696
  constructor(provider, walletId, walletName) {
11279
11697
  // Expose eventEmitter for testing - allows tests to trigger events directly
11280
11698
  this.eventEmitter = new EventEmitter3();
11281
- this._connected = false;
11282
11699
  this._publicKey = null;
11283
11700
  this.provider = provider;
11284
11701
  this.walletId = walletId;
11285
11702
  this.walletName = walletName;
11286
11703
  this.setupEventListeners();
11287
11704
  }
11288
- get connected() {
11289
- return this._connected;
11290
- }
11291
11705
  get publicKey() {
11292
11706
  return this._publicKey;
11293
11707
  }
11708
+ get isConnected() {
11709
+ return this.provider.isConnected || !!this._publicKey;
11710
+ }
11294
11711
  async connect(options) {
11295
- debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect", {
11296
- walletId: this.walletId,
11297
- walletName: this.walletName,
11298
- onlyIfTrusted: options?.onlyIfTrusted
11299
- });
11300
11712
  try {
11301
- const result = await this.provider.connect(options);
11302
- if (typeof result === "string") {
11303
- this._connected = true;
11304
- this._publicKey = result;
11305
- debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11713
+ await this.provider.connect(options);
11714
+ const isConnected = this.provider.isConnected;
11715
+ if (!isConnected || this.provider.publicKey === null) {
11716
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Provider not connected after connect() call", {
11306
11717
  walletId: this.walletId,
11307
11718
  walletName: this.walletName,
11308
- publicKey: result
11719
+ providerConnected: isConnected,
11720
+ providerPublicKey: this.provider.publicKey
11309
11721
  });
11310
- return { publicKey: result };
11722
+ throw new Error("Provider not connected after connect() call");
11311
11723
  }
11312
- if (typeof result === "object" && result !== null && "publicKey" in result) {
11313
- this._connected = true;
11314
- this._publicKey = result.publicKey;
11315
- debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11724
+ let publicKey;
11725
+ const providerPublicKey = this.provider.publicKey;
11726
+ if (typeof providerPublicKey === "string") {
11727
+ publicKey = providerPublicKey;
11728
+ } else if (providerPublicKey !== null && providerPublicKey !== void 0 && typeof providerPublicKey.toString === "function") {
11729
+ publicKey = providerPublicKey.toString();
11730
+ } else {
11731
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Invalid publicKey format in provider state", {
11316
11732
  walletId: this.walletId,
11317
11733
  walletName: this.walletName,
11318
- publicKey: result.publicKey
11734
+ publicKeyType: typeof providerPublicKey
11319
11735
  });
11320
- return result;
11736
+ throw new Error("Invalid publicKey format in provider state");
11321
11737
  }
11322
- if (Array.isArray(result) && result.length > 0) {
11323
- const firstAccount = result[0];
11324
- if (typeof firstAccount === "object" && firstAccount !== null && "address" in firstAccount) {
11325
- this._connected = true;
11326
- this._publicKey = firstAccount.address;
11327
- debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11328
- walletId: this.walletId,
11329
- walletName: this.walletName,
11330
- publicKey: firstAccount.address
11331
- });
11332
- return { publicKey: firstAccount.address };
11333
- }
11738
+ if (!publicKey || publicKey.length === 0) {
11739
+ throw new Error("Empty publicKey from provider");
11334
11740
  }
11335
- throw new Error("Unexpected connect result format");
11741
+ this._publicKey = publicKey;
11742
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11743
+ walletId: this.walletId,
11744
+ walletName: this.walletName,
11745
+ publicKey
11746
+ });
11747
+ return { publicKey };
11336
11748
  } catch (error) {
11337
11749
  debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect failed", {
11338
11750
  walletId: this.walletId,
@@ -11349,7 +11761,6 @@ var InjectedWalletSolanaChain = class {
11349
11761
  });
11350
11762
  try {
11351
11763
  await this.provider.disconnect();
11352
- this._connected = false;
11353
11764
  this._publicKey = null;
11354
11765
  debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana disconnected", {
11355
11766
  walletId: this.walletId,
@@ -11485,28 +11896,19 @@ var InjectedWalletSolanaChain = class {
11485
11896
  switchNetwork(_network) {
11486
11897
  return Promise.resolve();
11487
11898
  }
11488
- getPublicKey() {
11489
- return Promise.resolve(this._publicKey);
11490
- }
11491
- isConnected() {
11492
- return this._connected;
11493
- }
11494
11899
  setupEventListeners() {
11495
11900
  if (typeof this.provider.on === "function") {
11496
11901
  this.provider.on("connect", (publicKey) => {
11497
- this._connected = true;
11498
11902
  this._publicKey = publicKey;
11499
11903
  this.eventEmitter.emit("connect", publicKey);
11500
11904
  });
11501
11905
  this.provider.on("disconnect", () => {
11502
- this._connected = false;
11503
11906
  this._publicKey = null;
11504
11907
  this.eventEmitter.emit("disconnect");
11505
11908
  });
11506
11909
  this.provider.on("accountChanged", (publicKey) => {
11507
- this._publicKey = publicKey;
11508
- this._connected = publicKey != null && publicKey.length > 0;
11509
- this.eventEmitter.emit("accountChanged", publicKey);
11910
+ this._publicKey = publicKey ? publicKey : null;
11911
+ this.eventEmitter.emit("accountChanged", this._publicKey);
11510
11912
  });
11511
11913
  }
11512
11914
  }
@@ -11526,12 +11928,12 @@ var WalletStandardSolanaAdapter = class {
11526
11928
  this.walletName = walletName;
11527
11929
  this.setupEventListeners();
11528
11930
  }
11529
- get connected() {
11530
- return this._publicKey !== null;
11531
- }
11532
11931
  get publicKey() {
11533
11932
  return this._publicKey;
11534
11933
  }
11934
+ get isConnected() {
11935
+ return this._publicKey !== null;
11936
+ }
11535
11937
  async connect(_options) {
11536
11938
  try {
11537
11939
  const connectFeature = this.wallet.features["standard:connect"];
@@ -11695,7 +12097,7 @@ var WalletStandardSolanaAdapter = class {
11695
12097
  throw new Error("No signature found in signAndSendTransaction result");
11696
12098
  }
11697
12099
  const signatureBytes = this.parseUint8Array(signatureOutput.signature);
11698
- const signature = index_native.base58.encode(signatureBytes);
12100
+ const signature = index_native.bs582.encode(signatureBytes);
11699
12101
  return { signature };
11700
12102
  } catch (error) {
11701
12103
  debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signAndSendTransaction failed", {
@@ -11743,12 +12145,6 @@ var WalletStandardSolanaAdapter = class {
11743
12145
  async switchNetwork(_network) {
11744
12146
  return Promise.resolve();
11745
12147
  }
11746
- getPublicKey() {
11747
- return Promise.resolve(this._publicKey);
11748
- }
11749
- isConnected() {
11750
- return this._publicKey !== null;
11751
- }
11752
12148
  /**
11753
12149
  * Set up event listeners for Wallet Standard events
11754
12150
  * Maps Wallet Standard "change" events to "accountChanged" events
@@ -11880,9 +12276,6 @@ var InjectedWalletEthereumChain = class {
11880
12276
  this.walletName = walletName;
11881
12277
  this.setupEventListeners();
11882
12278
  }
11883
- get connected() {
11884
- return this._connected;
11885
- }
11886
12279
  get chainId() {
11887
12280
  return this._chainId;
11888
12281
  }
@@ -12012,7 +12405,8 @@ var InjectedWalletEthereumChain = class {
12012
12405
  address
12013
12406
  });
12014
12407
  try {
12015
- const providerConnected = this.provider.isConnected?.() || this.provider.connected || false;
12408
+ const providerAny = this.provider;
12409
+ const providerConnected = (typeof providerAny.isConnected === "function" ? providerAny.isConnected() : false) || (typeof providerAny.connected === "boolean" ? providerAny.connected : false);
12016
12410
  if (!this._connected || this._accounts.length === 0 || !providerConnected) {
12017
12411
  debug.log(DebugCategory.INJECTED_PROVIDER, "Not connected, attempting to connect before signing", {
12018
12412
  walletId: this.walletId,
@@ -12326,8 +12720,7 @@ var InjectedWalletRegistry = class {
12326
12720
  const phantomWallet = {
12327
12721
  id: "phantom",
12328
12722
  name: "Phantom",
12329
- icon: "",
12330
- // Icon will be rendered from icons package in UI components
12723
+ icon: PHANTOM_ICON,
12331
12724
  addressTypes,
12332
12725
  providers: wrappedProviders,
12333
12726
  isPhantom: true,
@@ -12541,16 +12934,11 @@ var InjectedProvider = class {
12541
12934
  walletName: walletInfo.name
12542
12935
  });
12543
12936
  } catch (err) {
12544
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana, stopping", {
12937
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana, continuing with other chains", {
12545
12938
  error: err,
12546
12939
  walletId: this.selectedWalletId,
12547
12940
  walletName: walletInfo.name
12548
12941
  });
12549
- this.emit("connect_error", {
12550
- error: err instanceof Error ? err.message : "Failed to connect",
12551
- source: options?.skipEventListeners ? "auto-connect" : "manual-connect"
12552
- });
12553
- throw err;
12554
12942
  }
12555
12943
  }
12556
12944
  if (this.addressTypes.includes(exports.AddressType.ethereum) && walletInfo.providers?.ethereum) {
@@ -12580,16 +12968,11 @@ var InjectedProvider = class {
12580
12968
  });
12581
12969
  }
12582
12970
  } catch (err) {
12583
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum, stopping", {
12971
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum, continuing with other chains", {
12584
12972
  error: err,
12585
12973
  walletId: this.selectedWalletId,
12586
12974
  walletName: walletInfo.name
12587
12975
  });
12588
- this.emit("connect_error", {
12589
- error: err instanceof Error ? err.message : "Failed to connect",
12590
- source: options?.skipEventListeners ? "auto-connect" : "manual-connect"
12591
- });
12592
- throw err;
12593
12976
  }
12594
12977
  }
12595
12978
  return connectedAddresses;
@@ -12649,7 +13032,8 @@ var InjectedProvider = class {
12649
13032
  this.emit("connect", {
12650
13033
  addresses: connectedAddresses,
12651
13034
  source: "manual-connect",
12652
- authUserId
13035
+ authUserId,
13036
+ walletId
12653
13037
  });
12654
13038
  return result;
12655
13039
  }
@@ -12661,12 +13045,13 @@ var InjectedProvider = class {
12661
13045
  if (authOptions.provider !== "injected") {
12662
13046
  throw new Error(`Invalid provider for injected connection: ${authOptions.provider}. Must be "injected"`);
12663
13047
  }
13048
+ const requestedWalletId = authOptions.walletId || "phantom";
12664
13049
  this.emit("connect_start", {
12665
13050
  source: "manual-connect",
12666
- providerType: "injected"
13051
+ providerType: "injected",
13052
+ walletId: requestedWalletId
12667
13053
  });
12668
13054
  try {
12669
- const requestedWalletId = authOptions.walletId || "phantom";
12670
13055
  const walletInfo = this.validateAndSelectWallet(requestedWalletId);
12671
13056
  const connectedAddresses = await this.connectToWallet(walletInfo);
12672
13057
  return await this.finalizeConnection(connectedAddresses, "injected", this.selectedWalletId || void 0);
@@ -12786,7 +13171,8 @@ var InjectedProvider = class {
12786
13171
  this.emit("connect", {
12787
13172
  addresses: connectedAddresses,
12788
13173
  source: "auto-connect",
12789
- authUserId
13174
+ authUserId,
13175
+ walletId: this.selectedWalletId
12790
13176
  });
12791
13177
  debug.info(DebugCategory.INJECTED_PROVIDER, "Auto-connect successful", {
12792
13178
  addressCount: connectedAddresses.length,
@@ -12852,7 +13238,8 @@ var InjectedProvider = class {
12852
13238
  this.emit("connect", {
12853
13239
  addresses: newAddresses,
12854
13240
  source,
12855
- authUserId
13241
+ authUserId,
13242
+ walletId: this.selectedWalletId
12856
13243
  });
12857
13244
  };
12858
13245
  }
@@ -12886,7 +13273,8 @@ var InjectedProvider = class {
12886
13273
  this.emit("connect", {
12887
13274
  addresses: newAddresses,
12888
13275
  source: this.getAccountChangeSource(source),
12889
- authUserId
13276
+ authUserId,
13277
+ walletId: this.selectedWalletId
12890
13278
  });
12891
13279
  } else {
12892
13280
  const state = this.getWalletState(walletId);
@@ -12927,7 +13315,8 @@ var InjectedProvider = class {
12927
13315
  this.emit("connect", {
12928
13316
  addresses: newAddresses,
12929
13317
  source,
12930
- authUserId
13318
+ authUserId,
13319
+ walletId: this.selectedWalletId
12931
13320
  });
12932
13321
  }
12933
13322
  };
@@ -12961,7 +13350,8 @@ var InjectedProvider = class {
12961
13350
  this.emit("connect", {
12962
13351
  addresses: newAddresses,
12963
13352
  source: this.getAccountChangeSource(source),
12964
- authUserId
13353
+ authUserId,
13354
+ walletId: this.selectedWalletId
12965
13355
  });
12966
13356
  } else {
12967
13357
  const state = this.getWalletState(walletId);
@@ -13159,7 +13549,9 @@ var InjectedProvider = class {
13159
13549
  this.eventListenerCleanups.set(walletId, [...existingCleanups, ...cleanups]);
13160
13550
  }
13161
13551
  /**
13162
- * Unified event listener setup for all wallet types (Phantom and external)
13552
+ * Unified event listener setup for all wallet types (Phantom and external).
13553
+ * Cleans up listeners for previously selected wallets to prevent stale events
13554
+ * from causing walletId flicker during connections.
13163
13555
  */
13164
13556
  setupEventListeners(walletInfo) {
13165
13557
  const walletId = this.selectedWalletId || "phantom";
@@ -13167,6 +13559,17 @@ var InjectedProvider = class {
13167
13559
  debug.log(DebugCategory.INJECTED_PROVIDER, "Event listeners already set up for wallet", { walletId });
13168
13560
  return;
13169
13561
  }
13562
+ for (const existingWalletId of this.eventListenersSetup) {
13563
+ if (existingWalletId === walletId) {
13564
+ continue;
13565
+ }
13566
+ const cleanups = this.eventListenerCleanups.get(existingWalletId);
13567
+ if (cleanups) {
13568
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Cleaning up event listeners for wallet", { existingWalletId });
13569
+ cleanups.forEach((cleanup) => cleanup());
13570
+ }
13571
+ this.eventListenersSetup.delete(existingWalletId);
13572
+ }
13170
13573
  debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up event listeners", { walletId });
13171
13574
  if (this.addressTypes.includes(exports.AddressType.solana) && walletInfo.providers?.solana) {
13172
13575
  this.setupSolanaEventListeners(walletInfo.providers.solana, walletId, "wallet");
@@ -13477,9 +13880,10 @@ var BrowserAuthProvider = class {
13477
13880
  // OAuth session management - defaults to allow refresh unless explicitly clearing after logout
13478
13881
  clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
13479
13882
  allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
13480
- sdk_version: "1.0.2",
13883
+ sdk_version: "1.0.7",
13481
13884
  sdk_type: "browser",
13482
- platform: detectBrowser().name
13885
+ platform: detectBrowser().name,
13886
+ algorithm: phantomOptions.algorithm || DEFAULT_AUTHENTICATOR_ALGORITHM
13483
13887
  });
13484
13888
  if (phantomOptions.provider) {
13485
13889
  debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
@@ -13507,7 +13911,7 @@ var BrowserAuthProvider = class {
13507
13911
  resolve();
13508
13912
  });
13509
13913
  }
13510
- resumeAuthFromRedirect(provider) {
13914
+ async resumeAuthFromRedirect(provider) {
13511
13915
  try {
13512
13916
  const walletId = this.urlParamsAccessor.getParam("wallet_id");
13513
13917
  const sessionId = this.urlParamsAccessor.getParam("session_id");
@@ -13582,40 +13986,361 @@ var BrowserAuthProvider = class {
13582
13986
  }
13583
13987
  );
13584
13988
  }
13585
- return {
13989
+ return Promise.resolve({
13586
13990
  walletId,
13587
13991
  organizationId,
13588
13992
  accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : 0,
13589
13993
  expiresInMs: expiresInMs ? parseInt(expiresInMs) : 0,
13590
13994
  authUserId: authUserId || void 0,
13591
13995
  provider
13592
- };
13996
+ });
13593
13997
  } catch (error) {
13594
13998
  sessionStorage.removeItem("phantom-auth-context");
13595
13999
  throw error;
13596
14000
  }
13597
14001
  }
13598
14002
  };
13599
- async function isPhantomLoginAvailable(timeoutMs = 3e3) {
13600
- const extensionInstalled = await waitForExtension(timeoutMs);
13601
- if (!extensionInstalled) {
13602
- return false;
14003
+ var Auth2AuthProvider = class {
14004
+ constructor(stamper, storage, urlParamsAccessor, auth2ProviderOptions, kmsClientOptions) {
14005
+ this.stamper = stamper;
14006
+ this.storage = storage;
14007
+ this.urlParamsAccessor = urlParamsAccessor;
14008
+ this.auth2ProviderOptions = auth2ProviderOptions;
14009
+ this.kms = new Auth2KmsRpcClient(stamper, kmsClientOptions);
13603
14010
  }
13604
- try {
13605
- if (!window.phantom?.app?.features || typeof window.phantom.app.features !== "function") {
13606
- return false;
14011
+ /** Redirect the browser. Extracted as a static method so tests can spy on it. */
14012
+ static navigate(url) {
14013
+ window.location.href = url;
14014
+ }
14015
+ /**
14016
+ * Builds the Auth2 /login/start URL and redirects the browser.
14017
+ *
14018
+ * Called by EmbeddedProvider.handleRedirectAuth() after the stamper has
14019
+ * already been initialized and a pending Session has been saved to storage.
14020
+ * We store the PKCE code_verifier into that session so it survives the page
14021
+ * redirect without ever touching sessionStorage.
14022
+ */
14023
+ async authenticate(options) {
14024
+ if (!this.stamper.getKeyInfo()) {
14025
+ await this.stamper.init();
13607
14026
  }
13608
- const response = await window.phantom.app.features();
13609
- if (!Array.isArray(response.features)) {
13610
- return false;
14027
+ const keyPair = this.stamper.getCryptoKeyPair();
14028
+ if (!keyPair) {
14029
+ throw new Error("Stamper key pair not found.");
13611
14030
  }
13612
- return response.features.includes("phantom_login");
13613
- } catch (error) {
13614
- console.error("Error checking Phantom extension features", error);
13615
- return false;
14031
+ const codeVerifier = createCodeVerifier();
14032
+ const session = await this.storage.getSession();
14033
+ if (!session) {
14034
+ throw new Error("Session not found.");
14035
+ }
14036
+ await this.storage.saveSession({ ...session, pkceCodeVerifier: codeVerifier });
14037
+ const url = await createConnectStartUrl({
14038
+ keyPair,
14039
+ connectLoginUrl: this.auth2ProviderOptions.connectLoginUrl,
14040
+ clientId: this.auth2ProviderOptions.clientId,
14041
+ redirectUri: this.auth2ProviderOptions.redirectUri,
14042
+ sessionId: options.sessionId,
14043
+ provider: options.provider,
14044
+ codeVerifier,
14045
+ // The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
14046
+ salt: ""
14047
+ });
14048
+ Auth2AuthProvider.navigate(url);
13616
14049
  }
13617
- }
13618
- async function waitForExtension(timeoutMs) {
14050
+ /**
14051
+ * Processes the Auth2 callback after the browser returns from /login/start.
14052
+ *
14053
+ * Exchanges the authorization code for tokens, discovers the organization
14054
+ * and wallet via KMS RPC, then returns a completed AuthResult.
14055
+ */
14056
+ async resumeAuthFromRedirect(provider) {
14057
+ const code = this.urlParamsAccessor.getParam("code");
14058
+ if (!code) {
14059
+ return null;
14060
+ }
14061
+ if (!this.stamper.getKeyInfo()) {
14062
+ await this.stamper.init();
14063
+ }
14064
+ const session = await this.storage.getSession();
14065
+ if (!session) {
14066
+ throw new Error("Session not found.");
14067
+ }
14068
+ const codeVerifier = session?.pkceCodeVerifier;
14069
+ if (!codeVerifier) {
14070
+ return null;
14071
+ }
14072
+ const state = this.urlParamsAccessor.getParam("state");
14073
+ if (!state || state !== session.sessionId) {
14074
+ throw new Error("Missing or invalid Auth2 state parameter \u2014 possible CSRF attack.");
14075
+ }
14076
+ const error = this.urlParamsAccessor.getParam("error");
14077
+ if (error) {
14078
+ const description = this.urlParamsAccessor.getParam("error_description");
14079
+ throw new Error(`Auth2 callback error: ${description ?? error}`);
14080
+ }
14081
+ const { idToken, bearerToken, authUserId, expiresInMs, refreshToken } = await exchangeAuthCode({
14082
+ authApiBaseUrl: this.auth2ProviderOptions.authApiBaseUrl,
14083
+ clientId: this.auth2ProviderOptions.clientId,
14084
+ redirectUri: this.auth2ProviderOptions.redirectUri,
14085
+ code,
14086
+ codeVerifier
14087
+ });
14088
+ await this.stamper.setTokens({ idToken, bearerToken, refreshToken, expiresInMs });
14089
+ await this.storage.saveSession({
14090
+ ...session,
14091
+ status: "completed",
14092
+ bearerToken,
14093
+ authUserId,
14094
+ pkceCodeVerifier: void 0
14095
+ // no longer needed after code exchange
14096
+ });
14097
+ const { organizationId, walletId } = await this.kms.discoverOrganizationAndWalletId(bearerToken, authUserId);
14098
+ return {
14099
+ walletId,
14100
+ organizationId,
14101
+ provider,
14102
+ accountDerivationIndex: 0,
14103
+ // discoverWalletId uses derivation index of 0.
14104
+ expiresInMs,
14105
+ authUserId,
14106
+ bearerToken
14107
+ };
14108
+ }
14109
+ };
14110
+ var STORE_NAME = "crypto-keys";
14111
+ var ACTIVE_KEY = "auth2-p256-signing-key";
14112
+ var Auth2Stamper = class {
14113
+ /**
14114
+ * @param dbName - IndexedDB database name (use a unique name per app to
14115
+ * avoid key collisions with other stampers, e.g. `phantom-auth2-<appId>`).
14116
+ * @param refreshConfig - When provided, the stamper will automatically refresh
14117
+ * the id_token using the refresh_token before it expires.
14118
+ */
14119
+ constructor(dbName, refreshConfig) {
14120
+ this.dbName = dbName;
14121
+ this.refreshConfig = refreshConfig;
14122
+ this.db = null;
14123
+ this._keyPair = null;
14124
+ this._keyInfo = null;
14125
+ this._idToken = null;
14126
+ this._bearerToken = null;
14127
+ this._refreshToken = null;
14128
+ this._tokenExpiresAt = null;
14129
+ this.algorithm = Algorithm.secp256r1;
14130
+ this.type = "OIDC";
14131
+ }
14132
+ async init() {
14133
+ await this.openDB();
14134
+ const stored = await this.loadRecord();
14135
+ if (stored) {
14136
+ this._keyPair = stored.keyPair;
14137
+ this._keyInfo = stored.keyInfo;
14138
+ if (stored.idToken) {
14139
+ this._idToken = stored.idToken;
14140
+ }
14141
+ if (stored.bearerToken) {
14142
+ this._bearerToken = stored.bearerToken;
14143
+ }
14144
+ if (stored.refreshToken) {
14145
+ this._refreshToken = stored.refreshToken;
14146
+ }
14147
+ if (stored.tokenExpiresAt) {
14148
+ this._tokenExpiresAt = stored.tokenExpiresAt;
14149
+ }
14150
+ return this._keyInfo;
14151
+ }
14152
+ return this.generateAndStore();
14153
+ }
14154
+ getKeyInfo() {
14155
+ return this._keyInfo;
14156
+ }
14157
+ getCryptoKeyPair() {
14158
+ return this._keyPair;
14159
+ }
14160
+ /**
14161
+ * Returns the current token state (refreshing proactively if near expiry),
14162
+ * or null if no token has been set yet.
14163
+ */
14164
+ async getTokens() {
14165
+ if (this.refreshConfig && this._refreshToken && this._tokenExpiresAt !== null && Date.now() >= this._tokenExpiresAt - TOKEN_REFRESH_BUFFER_MS) {
14166
+ const refreshed = await refreshToken({
14167
+ authApiBaseUrl: this.refreshConfig.authApiBaseUrl,
14168
+ clientId: this.refreshConfig.clientId,
14169
+ redirectUri: this.refreshConfig.redirectUri,
14170
+ refreshToken: this._refreshToken
14171
+ });
14172
+ await this.setTokens(refreshed);
14173
+ }
14174
+ if (!this._idToken || !this._bearerToken) {
14175
+ return null;
14176
+ }
14177
+ return {
14178
+ idToken: this._idToken,
14179
+ bearerToken: this._bearerToken,
14180
+ refreshToken: this._refreshToken ?? void 0
14181
+ };
14182
+ }
14183
+ /**
14184
+ * Arms the stamper with the OIDC token data for subsequent KMS stamp() calls.
14185
+ *
14186
+ * Persists the tokens to IndexedDB alongside the key pair so that
14187
+ * auto-connect can restore them on the next page load without a new login.
14188
+ *
14189
+ * @param refreshToken - When provided alongside a `refreshConfig`, enables
14190
+ * silent token refresh before the token expires.
14191
+ * @param expiresInMs - Token lifetime in milliseconds (from `expires_in * 1000`).
14192
+ * Used to compute the absolute expiry time for proactive refresh.
14193
+ */
14194
+ async setTokens({
14195
+ idToken,
14196
+ bearerToken,
14197
+ refreshToken,
14198
+ expiresInMs
14199
+ }) {
14200
+ if (!this.db) {
14201
+ await this.openDB();
14202
+ }
14203
+ this._idToken = idToken;
14204
+ this._bearerToken = bearerToken;
14205
+ this._refreshToken = refreshToken ?? null;
14206
+ this._tokenExpiresAt = expiresInMs != null ? Date.now() + expiresInMs : null;
14207
+ const existing = await this.loadRecord();
14208
+ if (existing) {
14209
+ await this.storeRecord({
14210
+ ...existing,
14211
+ idToken,
14212
+ bearerToken,
14213
+ refreshToken,
14214
+ tokenExpiresAt: this._tokenExpiresAt ?? void 0
14215
+ });
14216
+ }
14217
+ }
14218
+ async stamp(params) {
14219
+ if (!this._keyPair || !this._keyInfo || this._idToken === null) {
14220
+ throw new Error("Auth2Stamper not initialized. Call init() first.");
14221
+ }
14222
+ const signatureRaw = await crypto.subtle.sign(
14223
+ { name: "ECDSA", hash: "SHA-256" },
14224
+ this._keyPair.privateKey,
14225
+ new Uint8Array(params.data)
14226
+ );
14227
+ const rawPublicKey = index_native.bs582.decode(this._keyInfo.publicKey);
14228
+ const stampData = {
14229
+ kind: this.type,
14230
+ idToken: this._idToken,
14231
+ publicKey: base64urlEncode(rawPublicKey),
14232
+ algorithm: this.algorithm,
14233
+ // The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
14234
+ salt: "",
14235
+ signature: base64urlEncode(new Uint8Array(signatureRaw))
14236
+ };
14237
+ return base64urlEncode(new TextEncoder().encode(JSON.stringify(stampData)));
14238
+ }
14239
+ async resetKeyPair() {
14240
+ await this.clear();
14241
+ return this.generateAndStore();
14242
+ }
14243
+ async clear() {
14244
+ await this.clearStoredRecord();
14245
+ this._keyPair = null;
14246
+ this._keyInfo = null;
14247
+ this._idToken = null;
14248
+ this._bearerToken = null;
14249
+ this._refreshToken = null;
14250
+ this._tokenExpiresAt = null;
14251
+ }
14252
+ // Auth2 doesn't use key rotation; provide minimal no-op implementations.
14253
+ async rotateKeyPair() {
14254
+ return this.init();
14255
+ }
14256
+ // eslint-disable-next-line @typescript-eslint/require-await
14257
+ async commitRotation(authenticatorId) {
14258
+ if (this._keyInfo) {
14259
+ this._keyInfo.authenticatorId = authenticatorId;
14260
+ }
14261
+ }
14262
+ async rollbackRotation() {
14263
+ }
14264
+ async generateAndStore() {
14265
+ const keyPair = await crypto.subtle.generateKey(
14266
+ { name: "ECDSA", namedCurve: "P-256" },
14267
+ false,
14268
+ // non-extractable — private key never leaves Web Crypto
14269
+ ["sign", "verify"]
14270
+ );
14271
+ const rawPublicKey = new Uint8Array(await crypto.subtle.exportKey("raw", keyPair.publicKey));
14272
+ const publicKeyBase58 = index_native.bs582.encode(rawPublicKey);
14273
+ const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKey.buffer);
14274
+ const keyId = base64urlEncode(new Uint8Array(keyIdBuffer)).substring(0, 16);
14275
+ this._keyPair = keyPair;
14276
+ this._keyInfo = {
14277
+ keyId,
14278
+ publicKey: publicKeyBase58,
14279
+ createdAt: Date.now()
14280
+ };
14281
+ await this.storeRecord({ keyPair, keyInfo: this._keyInfo });
14282
+ return this._keyInfo;
14283
+ }
14284
+ async openDB() {
14285
+ return new Promise((resolve, reject) => {
14286
+ const request = indexedDB.open(this.dbName, 1);
14287
+ request.onsuccess = () => {
14288
+ this.db = request.result;
14289
+ resolve();
14290
+ };
14291
+ request.onerror = () => reject(request.error);
14292
+ request.onupgradeneeded = (event) => {
14293
+ const db = event.target.result;
14294
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
14295
+ db.createObjectStore(STORE_NAME);
14296
+ }
14297
+ };
14298
+ });
14299
+ }
14300
+ async loadRecord() {
14301
+ return new Promise((resolve, reject) => {
14302
+ if (!this.db) {
14303
+ throw new Error("Database not initialized");
14304
+ }
14305
+ const request = this.db.transaction([STORE_NAME], "readonly").objectStore(STORE_NAME).get(ACTIVE_KEY);
14306
+ request.onsuccess = () => {
14307
+ resolve(request.result ?? null);
14308
+ };
14309
+ request.onerror = () => {
14310
+ reject(request.error);
14311
+ };
14312
+ });
14313
+ }
14314
+ async storeRecord(record) {
14315
+ return new Promise((resolve, reject) => {
14316
+ if (!this.db) {
14317
+ throw new Error("Database not initialized");
14318
+ }
14319
+ const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).put(record, ACTIVE_KEY);
14320
+ request.onsuccess = () => {
14321
+ resolve();
14322
+ };
14323
+ request.onerror = () => {
14324
+ reject(request.error);
14325
+ };
14326
+ });
14327
+ }
14328
+ async clearStoredRecord() {
14329
+ return new Promise((resolve, reject) => {
14330
+ if (!this.db) {
14331
+ throw new Error("Database not initialized");
14332
+ }
14333
+ const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).delete(ACTIVE_KEY);
14334
+ request.onsuccess = () => {
14335
+ resolve();
14336
+ };
14337
+ request.onerror = () => {
14338
+ reject(request.error);
14339
+ };
14340
+ });
14341
+ }
14342
+ };
14343
+ async function waitForPhantomExtension(timeoutMs = 3e3) {
13619
14344
  return new Promise((resolve) => {
13620
14345
  const startTime = Date.now();
13621
14346
  const checkInterval = 100;
@@ -13638,6 +14363,27 @@ async function waitForExtension(timeoutMs) {
13638
14363
  });
13639
14364
  }
13640
14365
 
14366
+ // src/isPhantomLoginAvailable.ts
14367
+ async function isPhantomLoginAvailable(timeoutMs = 3e3) {
14368
+ const extensionInstalled = await waitForPhantomExtension(timeoutMs);
14369
+ if (!extensionInstalled) {
14370
+ return false;
14371
+ }
14372
+ try {
14373
+ if (!window.phantom?.app?.features || typeof window.phantom.app.features !== "function") {
14374
+ return false;
14375
+ }
14376
+ const response = await window.phantom.app.features();
14377
+ if (!Array.isArray(response.features)) {
14378
+ return false;
14379
+ }
14380
+ return response.features.includes("phantom_login");
14381
+ } catch (error) {
14382
+ console.error("Error checking Phantom extension features", error);
14383
+ return false;
14384
+ }
14385
+ }
14386
+
13641
14387
  // src/providers/embedded/adapters/phantom-app.ts
13642
14388
  var BrowserPhantomAppProvider = class {
13643
14389
  /**
@@ -13692,33 +14438,53 @@ var BrowserPhantomAppProvider = class {
13692
14438
 
13693
14439
  // src/providers/embedded/adapters/logger.ts
13694
14440
  var BrowserLogger = class {
13695
- info(category, message, data) {
13696
- debug.info(category, message, data);
14441
+ info(message, ...args) {
14442
+ debug.info(message, args.length > 0 ? String(args[0]) : "", args[1]);
13697
14443
  }
13698
- warn(category, message, data) {
13699
- debug.warn(category, message, data);
14444
+ warn(message, ...args) {
14445
+ debug.warn(message, args.length > 0 ? String(args[0]) : "", args[1]);
13700
14446
  }
13701
- error(category, message, data) {
13702
- debug.error(category, message, data);
14447
+ error(message, ...args) {
14448
+ debug.error(message, args.length > 0 ? String(args[0]) : "", args[1]);
13703
14449
  }
13704
- log(category, message, data) {
13705
- debug.log(category, message, data);
14450
+ debug(message, ...args) {
14451
+ debug.log(message, args.length > 0 ? String(args[0]) : "", args[1]);
13706
14452
  }
13707
14453
  };
13708
14454
  var EmbeddedProvider = class extends EmbeddedProvider$1 {
13709
14455
  constructor(config) {
13710
14456
  debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
13711
14457
  const urlParamsAccessor = new BrowserURLParamsAccessor();
13712
- const stamper = new IndexedDbStamper({
14458
+ const storage = new BrowserStorage();
14459
+ const stamper = config.unstable__auth2Options ? new Auth2Stamper(`phantom-auth2-${config.appId}`, {
14460
+ authApiBaseUrl: config.unstable__auth2Options.authApiBaseUrl,
14461
+ clientId: config.unstable__auth2Options.clientId,
14462
+ redirectUri: config.authOptions?.redirectUrl ?? ""
14463
+ }) : new IndexedDbStamper({
13713
14464
  dbName: `phantom-embedded-sdk-${config.appId}`,
13714
14465
  storeName: "crypto-keys",
13715
14466
  keyName: "signing-key"
13716
14467
  });
13717
14468
  const platformName = getPlatformName();
13718
14469
  const { name: browserName, version } = detectBrowser();
14470
+ const authProvider = config.unstable__auth2Options && config.authOptions?.authUrl && config.authOptions?.redirectUrl && stamper instanceof Auth2Stamper ? new Auth2AuthProvider(
14471
+ stamper,
14472
+ storage,
14473
+ urlParamsAccessor,
14474
+ {
14475
+ redirectUri: config.authOptions.redirectUrl,
14476
+ connectLoginUrl: config.authOptions.authUrl,
14477
+ clientId: config.unstable__auth2Options.clientId,
14478
+ authApiBaseUrl: config.unstable__auth2Options.authApiBaseUrl
14479
+ },
14480
+ {
14481
+ apiBaseUrl: config.apiBaseUrl,
14482
+ appId: config.appId
14483
+ }
14484
+ ) : new BrowserAuthProvider(urlParamsAccessor);
13719
14485
  const platform = {
13720
- storage: new BrowserStorage(),
13721
- authProvider: new BrowserAuthProvider(urlParamsAccessor),
14486
+ storage,
14487
+ authProvider,
13722
14488
  phantomAppProvider: new BrowserPhantomAppProvider(),
13723
14489
  urlParamsAccessor,
13724
14490
  stamper,
@@ -13726,13 +14492,12 @@ var EmbeddedProvider = class extends EmbeddedProvider$1 {
13726
14492
  // Use detected browser name and version for identification
13727
14493
  analyticsHeaders: {
13728
14494
  [ANALYTICS_HEADERS.SDK_TYPE]: "browser",
13729
- [ANALYTICS_HEADERS.PLATFORM]: browserName,
13730
- // firefox, chrome, safari, etc.
14495
+ [ANALYTICS_HEADERS.PLATFORM]: "ext-sdk",
13731
14496
  [ANALYTICS_HEADERS.PLATFORM_VERSION]: version,
13732
- // Full user agent for more detailed info
14497
+ [ANALYTICS_HEADERS.CLIENT]: browserName,
13733
14498
  [ANALYTICS_HEADERS.APP_ID]: config.appId,
13734
14499
  [ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
13735
- [ANALYTICS_HEADERS.SDK_VERSION]: "1.0.2"
14500
+ [ANALYTICS_HEADERS.SDK_VERSION]: "1.0.7"
13736
14501
  // Replaced at build time
13737
14502
  }
13738
14503
  };
@@ -13765,11 +14530,12 @@ function isAuthCallbackUrl(searchParams) {
13765
14530
  }
13766
14531
 
13767
14532
  // src/utils/deeplink.ts
13768
- function getDeeplinkToPhantom(ref) {
13769
- if (!window.location.href.startsWith("http:") && !window.location.href.startsWith("https:")) {
14533
+ function getDeeplinkToPhantom(ref, currentHref) {
14534
+ const resolvedHref = window.location.href;
14535
+ if (!resolvedHref.startsWith("http:") && !resolvedHref.startsWith("https:")) {
13770
14536
  throw new Error("Invalid URL protocol - only HTTP/HTTPS URLs are supported for deeplinks");
13771
14537
  }
13772
- const currentUrl = encodeURIComponent(window.location.href);
14538
+ const currentUrl = encodeURIComponent(resolvedHref);
13773
14539
  const refParam = "";
13774
14540
  return `https://phantom.app/ul/browse/${currentUrl}${refParam}`;
13775
14541
  }
@@ -13865,8 +14631,14 @@ var ProviderManager = class {
13865
14631
  } else if (requestedProvider === "deeplink") {
13866
14632
  try {
13867
14633
  const deeplinkUrl = getDeeplinkToPhantom();
13868
- if (typeof window !== "undefined") {
13869
- window.location.href = deeplinkUrl;
14634
+ if (typeof window !== "undefined" && window.location) {
14635
+ try {
14636
+ window.location.href = deeplinkUrl;
14637
+ } catch (error) {
14638
+ debug.warn(DebugCategory.PROVIDER_MANAGER, "Failed to set deeplink location", {
14639
+ error: error instanceof Error ? error.message : String(error)
14640
+ });
14641
+ }
13870
14642
  }
13871
14643
  return {
13872
14644
  addresses: [],
@@ -14139,6 +14911,7 @@ var ProviderManager = class {
14139
14911
  authUrl,
14140
14912
  redirectUrl: this.config.authOptions?.redirectUrl || this.getValidatedCurrentUrl()
14141
14913
  },
14914
+ unstable__auth2Options: this.config.unstable__auth2Options,
14142
14915
  embeddedWalletType: embeddedWalletType || DEFAULT_EMBEDDED_WALLET_TYPE,
14143
14916
  addressTypes: this.config.addressTypes || [exports.AddressType.solana]
14144
14917
  });
@@ -14333,6 +15106,7 @@ var BrowserSDK = class {
14333
15106
  */
14334
15107
  async autoConnect() {
14335
15108
  debug.log(DebugCategory.BROWSER_SDK, "Attempting auto-connect with fallback strategy");
15109
+ await this.discoverWallets();
14336
15110
  const result = await this.providerManager.autoConnect();
14337
15111
  if (result) {
14338
15112
  debug.info(DebugCategory.BROWSER_SDK, "Auto-connect successful", {
@@ -14479,28 +15253,6 @@ var BrowserSDK = class {
14479
15253
  }
14480
15254
  }
14481
15255
  };
14482
- async function waitForPhantomExtension(timeoutMs = 3e3) {
14483
- return new Promise((resolve) => {
14484
- const startTime = Date.now();
14485
- const checkInterval = 100;
14486
- const checkForExtension = () => {
14487
- try {
14488
- if (isInstalled()) {
14489
- resolve(true);
14490
- return;
14491
- }
14492
- } catch (error) {
14493
- }
14494
- const elapsed = Date.now() - startTime;
14495
- if (elapsed >= timeoutMs) {
14496
- resolve(false);
14497
- return;
14498
- }
14499
- setTimeout(checkForExtension, checkInterval);
14500
- };
14501
- checkForExtension();
14502
- });
14503
- }
14504
15256
 
14505
15257
  // src/utils/index.ts
14506
15258
  var hexToRgba = (hex, opacity) => {
@@ -16127,4 +16879,4 @@ exports.useModal = useModal;
16127
16879
  exports.usePhantom = usePhantom;
16128
16880
  exports.useSolana = useSolana;
16129
16881
  exports.useTheme = useTheme;
16130
- //# sourceMappingURL=index-CqoP9udN.js.map
16882
+ //# sourceMappingURL=index-BMrN-6oK.js.map