@bounded-sh/client 0.0.1 → 0.0.3

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