@bounded-sh/client 0.0.2 → 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 (55) hide show
  1. package/dist/{index-BL-0ZKBl.js → index-2UpSvA7V.js} +2514 -52
  2. package/dist/index-2UpSvA7V.js.map +1 -0
  3. package/dist/{index-CqoP9udN.js → index-C2JpxGAC.js} +1202 -450
  4. package/dist/index-C2JpxGAC.js.map +1 -0
  5. package/dist/{index-BFOmV3Pb.esm.js → index-C2yvle9S.esm.js} +1202 -450
  6. package/dist/index-C2yvle9S.esm.js.map +1 -0
  7. package/dist/{index-BgAygrhE.js → index-CYVVTWs4.js} +1202 -450
  8. package/dist/index-CYVVTWs4.js.map +1 -0
  9. package/dist/{index-B2ytfYTB.esm.js → index-DJg-Dduo.esm.js} +1202 -450
  10. package/dist/index-DJg-Dduo.esm.js.map +1 -0
  11. package/dist/{index-D986s6w7.esm.js → index-DyfiK3_X.esm.js} +2513 -52
  12. package/dist/index-DyfiK3_X.esm.js.map +1 -0
  13. package/dist/{index.browser-D8u31irV.js → index.browser-BTJZmhY1.js} +766 -773
  14. package/dist/index.browser-BTJZmhY1.js.map +1 -0
  15. package/dist/{index.browser-Bd0GwRur.esm.js → index.browser-C_TToxuO.esm.js} +230 -242
  16. package/dist/index.browser-C_TToxuO.esm.js.map +1 -0
  17. package/dist/{index.browser-BeM1bzpe.js → index.browser-DcHalmEf.js} +230 -242
  18. package/dist/index.browser-DcHalmEf.js.map +1 -0
  19. package/dist/{index.browser-D2xm-q6N.esm.js → index.browser-pymH6o1X.esm.js} +766 -773
  20. package/dist/index.browser-pymH6o1X.esm.js.map +1 -0
  21. package/dist/index.esm.js +1 -1
  22. package/dist/index.js +2 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/{index.native-B-cLm_BI.esm.js → index.native-BTjBgNiE.esm.js} +2510 -49
  25. package/dist/index.native-BTjBgNiE.esm.js.map +1 -0
  26. package/dist/{index.native-NgHStPq0.js → index.native-BvsmNFXn.js} +2511 -49
  27. package/dist/index.native-BvsmNFXn.js.map +1 -0
  28. package/dist/index.native.esm.js +1 -1
  29. package/dist/index.native.js +2 -1
  30. package/dist/index.native.js.map +1 -1
  31. package/dist/{phantom-wallet-provider-Dy48LSdU.js → phantom-wallet-provider-BXMvoOrI.js} +3 -3
  32. package/dist/{phantom-wallet-provider-Dy48LSdU.js.map → phantom-wallet-provider-BXMvoOrI.js.map} +1 -1
  33. package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js → phantom-wallet-provider-CTossIFB.esm.js} +3 -3
  34. package/dist/{phantom-wallet-provider-Cy5T9EVd.esm.js.map → phantom-wallet-provider-CTossIFB.esm.js.map} +1 -1
  35. package/dist/{privy-wallet-provider-BDsrUpk4.esm.js → privy-wallet-provider-1qE_f-DF.esm.js} +4 -4
  36. package/dist/{privy-wallet-provider-BDsrUpk4.esm.js.map → privy-wallet-provider-1qE_f-DF.esm.js.map} +1 -1
  37. package/dist/{privy-wallet-provider-CiKtBJ5M.js → privy-wallet-provider-D64DJ3u4.js} +4 -4
  38. package/dist/{privy-wallet-provider-CiKtBJ5M.js.map → privy-wallet-provider-D64DJ3u4.js.map} +1 -1
  39. package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js → solana-mobile-wallet-provider-9M8U6AA7.esm.js} +5 -5
  40. package/dist/{solana-mobile-wallet-provider-CSk_FIww.esm.js.map → solana-mobile-wallet-provider-9M8U6AA7.esm.js.map} +1 -1
  41. package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js → solana-mobile-wallet-provider-C1wQ1DRK.js} +5 -5
  42. package/dist/{solana-mobile-wallet-provider-k_YdrTJZ.js.map → solana-mobile-wallet-provider-C1wQ1DRK.js.map} +1 -1
  43. package/package.json +2 -2
  44. package/dist/index-B2ytfYTB.esm.js.map +0 -1
  45. package/dist/index-BFOmV3Pb.esm.js.map +0 -1
  46. package/dist/index-BL-0ZKBl.js.map +0 -1
  47. package/dist/index-BgAygrhE.js.map +0 -1
  48. package/dist/index-CqoP9udN.js.map +0 -1
  49. package/dist/index-D986s6w7.esm.js.map +0 -1
  50. package/dist/index.browser-Bd0GwRur.esm.js.map +0 -1
  51. package/dist/index.browser-BeM1bzpe.js.map +0 -1
  52. package/dist/index.browser-D2xm-q6N.esm.js.map +0 -1
  53. package/dist/index.browser-D8u31irV.js.map +0 -1
  54. package/dist/index.native-B-cLm_BI.esm.js.map +0 -1
  55. package/dist/index.native-NgHStPq0.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { useContext, createContext, useState, useMemo, useRef, useEffect, useCallback } from 'react';
3
3
  import axios, { isAxiosError } from 'axios';
4
- import { b as bufferExports, p as getDefaultExportFromCjs, o as base58 } from './index.native-B-cLm_BI.esm.js';
4
+ import { b as bufferExports, p as getDefaultExportFromCjs, o as bs582 } from './index.native-BTjBgNiE.esm.js';
5
5
  import { Transaction as Transaction$1, VersionedTransaction } from '@solana/web3.js';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import '@coral-xyz/anchor';
@@ -489,6 +489,50 @@ var GetAccountsMethodEnum;
489
489
  GetAccountsMethodEnum["getAccounts"] = "getAccounts";
490
490
  })(GetAccountsMethodEnum || (GetAccountsMethodEnum = {}));
491
491
 
492
+ /* tslint:disable */
493
+ /* eslint-disable */
494
+ /**
495
+ * kms-api
496
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
497
+ *
498
+ * The version of the OpenAPI document: 0.1.0
499
+ *
500
+ *
501
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
502
+ * https://openapi-generator.tech
503
+ * Do not edit the class manually.
504
+ */
505
+ /**
506
+ * @export
507
+ * @enum {string}
508
+ */
509
+ var GetOrCreatePhantomOrganizationMethodEnum;
510
+ (function (GetOrCreatePhantomOrganizationMethodEnum) {
511
+ GetOrCreatePhantomOrganizationMethodEnum["getOrCreatePhantomOrganization"] = "getOrCreatePhantomOrganization";
512
+ })(GetOrCreatePhantomOrganizationMethodEnum || (GetOrCreatePhantomOrganizationMethodEnum = {}));
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 GetOrganizationWalletsMethodEnum;
532
+ (function (GetOrganizationWalletsMethodEnum) {
533
+ GetOrganizationWalletsMethodEnum["getOrganizationWallets"] = "getOrganizationWallets";
534
+ })(GetOrganizationWalletsMethodEnum || (GetOrganizationWalletsMethodEnum = {}));
535
+
492
536
  /* tslint:disable */
493
537
  /* eslint-disable */
494
538
  /**
@@ -577,6 +621,13 @@ var UserPolicyOneOfTypeEnum;
577
621
  UserPolicyOneOfTypeEnum["root"] = "ROOT";
578
622
  })(UserPolicyOneOfTypeEnum || (UserPolicyOneOfTypeEnum = {}));
579
623
 
624
+ // src/auth2.ts
625
+ var TOKEN_REFRESH_BUFFER_MS = 15 * 60 * 1e3;
626
+ var DEFAULT_AUTHENTICATOR_ALGORITHM = Algorithm.ed25519;
627
+
628
+ // src/icons.ts
629
+ var PHANTOM_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTA4IiBoZWlnaHQ9IjEwOCIgdmlld0JveD0iMCAwIDEwOCAxMDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMDgiIGhlaWdodD0iMTA4IiByeD0iMjYiIGZpbGw9IiNBQjlGRjIiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00Ni41MjY3IDY5LjkyMjlDNDIuMDA1NCA3Ni44NTA5IDM0LjQyOTIgODUuNjE4MiAyNC4zNDggODUuNjE4MkMxOS41ODI0IDg1LjYxODIgMTUgODMuNjU2MyAxNSA3NS4xMzQyQzE1IDUzLjQzMDUgNDQuNjMyNiAxOS44MzI3IDcyLjEyNjggMTkuODMyN0M4Ny43NjggMTkuODMyNyA5NCAzMC42ODQ2IDk0IDQzLjAwNzlDOTQgNTguODI1OCA4My43MzU1IDc2LjkxMjIgNzMuNTMyMSA3Ni45MTIyQzcwLjI5MzkgNzYuOTEyMiA2OC43MDUzIDc1LjEzNDIgNjguNzA1MyA3Mi4zMTRDNjguNzA1MyA3MS41NzgzIDY4LjgyNzUgNzAuNzgxMiA2OS4wNzE5IDY5LjkyMjlDNjUuNTg5MyA3NS44Njk5IDU4Ljg2ODUgODEuMzg3OCA1Mi41NzU0IDgxLjM4NzhDNDcuOTkzIDgxLjM4NzggNDUuNjcxMyA3OC41MDYzIDQ1LjY3MTMgNzQuNDU5OEM0NS42NzEzIDcyLjk4ODQgNDUuOTc2OCA3MS40NTU2IDQ2LjUyNjcgNjkuOTIyOVpNODMuNjc2MSA0Mi41Nzk0QzgzLjY3NjEgNDYuMTcwNCA4MS41NTc1IDQ3Ljk2NTggNzkuMTg3NSA0Ny45NjU4Qzc2Ljc4MTYgNDcuOTY1OCA3NC42OTg5IDQ2LjE3MDQgNzQuNjk4OSA0Mi41Nzk0Qzc0LjY5ODkgMzguOTg4NSA3Ni43ODE2IDM3LjE5MzEgNzkuMTg3NSAzNy4xOTMxQzgxLjU1NzUgMzcuMTkzMSA4My42NzYxIDM4Ljk4ODUgODMuNjc2MSA0Mi41Nzk0Wk03MC4yMTAzIDQyLjU3OTVDNzAuMjEwMyA0Ni4xNzA0IDY4LjA5MTYgNDcuOTY1OCA2NS43MjE2IDQ3Ljk2NThDNjMuMzE1NyA0Ny45NjU4IDYxLjIzMyA0Ni4xNzA0IDYxLjIzMyA0Mi41Nzk1QzYxLjIzMyAzOC45ODg1IDYzLjMxNTcgMzcuMTkzMSA2NS43MjE2IDM3LjE5MzFDNjguMDkxNiAzNy4xOTMxIDcwLjIxMDMgMzguOTg4NSA3MC4yMTAzIDQyLjU3OTVaIiBmaWxsPSIjRkZGREY4Ii8+Cjwvc3ZnPgo=";
630
+
580
631
  // src/network-ids.ts
581
632
  var NetworkId = /* @__PURE__ */ ((NetworkId2) => {
582
633
  NetworkId2["SOLANA_MAINNET"] = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
@@ -880,13 +931,15 @@ var ANALYTICS_HEADERS = {
880
931
  SDK_VERSION: "x-phantom-sdk-version",
881
932
  // SDK version, e.g. 1.0.0
882
933
  PLATFORM: "x-phantom-platform",
883
- // firefox, chrome, safari, ios, android, etc.
934
+ // ext-sdk for all SDK requests
884
935
  WALLET_TYPE: "x-phantom-wallet-type",
885
936
  // app-wallet, user-wallet
886
937
  APP_ID: "x-app-id",
887
938
  // Your application ID for identifying your app in analytics
888
- PLATFORM_VERSION: "x-phantom-platform-version"
939
+ PLATFORM_VERSION: "x-phantom-platform-version",
889
940
  // OS version, device model, etc.
941
+ CLIENT: "x-phantom-client"
942
+ // mcp, chrome, firefox, safari, node, ios, android, etc.
890
943
  };
891
944
 
892
945
  // src/environments.ts
@@ -998,6 +1051,12 @@ function isSolanaChain(networkId) {
998
1051
  return network === "solana";
999
1052
  }
1000
1053
 
1054
+ // src/index.ts
1055
+ async function sha256$2(input) {
1056
+ const digest = await crypto.subtle.digest("SHA-256", input);
1057
+ return new Uint8Array(digest);
1058
+ }
1059
+
1001
1060
  // src/PhantomClient.ts
1002
1061
  var CAIP2_NETWORK_MAPPINGS = {
1003
1062
  // Solana networks
@@ -1177,6 +1236,12 @@ function getErrorMessage(error, fallbackMessage = "An error occurred") {
1177
1236
  }
1178
1237
  return fallbackMessage;
1179
1238
  }
1239
+ function isAuthenticationError(error) {
1240
+ if (isAxiosError(error)) {
1241
+ return error.response?.status === 401 || error.response?.status === 403;
1242
+ }
1243
+ return false;
1244
+ }
1180
1245
  function parseWalletServiceError(data) {
1181
1246
  if (!data || !data.type) {
1182
1247
  return null;
@@ -1211,6 +1276,7 @@ var PhantomClient = class {
1211
1276
  ...config,
1212
1277
  walletType: config.walletType || "user-wallet"
1213
1278
  };
1279
+ this.logger = config.logger;
1214
1280
  this.axiosInstance = axios.create();
1215
1281
  const customHeaders = {};
1216
1282
  if (config.headers) {
@@ -1239,6 +1305,20 @@ var PhantomClient = class {
1239
1305
  }
1240
1306
  this.config.organizationId = organizationId;
1241
1307
  }
1308
+ /**
1309
+ * Gets the authenticator public key from the stamper if available.
1310
+ * Returns undefined if the stamper doesn't support key info retrieval.
1311
+ */
1312
+ getAuthenticatorPublicKey() {
1313
+ if (!this.stamper) {
1314
+ return void 0;
1315
+ }
1316
+ if ("getKeyInfo" in this.stamper && typeof this.stamper.getKeyInfo === "function") {
1317
+ const keyInfo = this.stamper.getKeyInfo();
1318
+ return keyInfo?.publicKey;
1319
+ }
1320
+ return void 0;
1321
+ }
1242
1322
  async createWallet(walletName) {
1243
1323
  try {
1244
1324
  if (!this.config.organizationId) {
@@ -1286,18 +1366,22 @@ var PhantomClient = class {
1286
1366
  }))
1287
1367
  };
1288
1368
  } catch (error) {
1289
- console.error("Failed to create wallet:", error.response?.data || error.message);
1369
+ this.logger?.error(`Failed to create wallet: ${JSON.stringify(error.response?.data) || error.message}`);
1290
1370
  throw new Error(`Failed to create wallet: ${error.response?.data?.message || error.message}`);
1291
1371
  }
1292
1372
  }
1293
- async prepare(transaction, organizationId, submissionConfig, account, methodName) {
1373
+ async prepare(transaction, organizationId, submissionConfig, account, authenticatorPublicKey, methodName) {
1294
1374
  try {
1295
1375
  const request = {
1296
1376
  transaction,
1297
1377
  organizationId,
1298
1378
  submissionConfig,
1299
- simulationConfig: { account }
1379
+ simulationConfig: { account },
1380
+ authenticatorPublicKey
1300
1381
  };
1382
+ this.logger?.debug(
1383
+ `prepare request: submissionConfig=${JSON.stringify(submissionConfig)} account=${account} methodName=${methodName} txLength=${transaction.length} request=${JSON.stringify(request)}`
1384
+ );
1301
1385
  const response = await this.axiosInstance.post(`${this.config.apiBaseUrl}/prepare`, request, {
1302
1386
  headers: {
1303
1387
  "Content-Type": "application/json",
@@ -1307,6 +1391,11 @@ var PhantomClient = class {
1307
1391
  return response.data;
1308
1392
  } catch (error) {
1309
1393
  const errorData = getAxiosErrorData(error);
1394
+ const axiosStatus = error.response?.status;
1395
+ const rawResponseData = error.response?.data;
1396
+ this.logger?.error(
1397
+ `[TX_DEBUG] prepare failed: status=${axiosStatus} methodName=${methodName} body=${JSON.stringify(rawResponseData)}`
1398
+ );
1310
1399
  const walletServiceError = parseWalletServiceError(errorData);
1311
1400
  if (walletServiceError) {
1312
1401
  throw walletServiceError;
@@ -1316,7 +1405,7 @@ var PhantomClient = class {
1316
1405
  }
1317
1406
  }
1318
1407
  async getTransactionForSigning(params) {
1319
- const { encodedTransaction, networkId, submissionConfig, account } = params;
1408
+ const { encodedTransaction, networkId, submissionConfig, account, authenticatorPublicKey } = params;
1320
1409
  const isEvmTransaction = isEthereumChain(networkId);
1321
1410
  const isSolanaTransaction = isSolanaChain(networkId);
1322
1411
  if (isEvmTransaction) {
@@ -1332,6 +1421,7 @@ var PhantomClient = class {
1332
1421
  this.config.organizationId,
1333
1422
  submissionConfig,
1334
1423
  account,
1424
+ authenticatorPublicKey,
1335
1425
  params.methodName
1336
1426
  );
1337
1427
  return prepareResponse.transaction;
@@ -1355,7 +1445,7 @@ var PhantomClient = class {
1355
1445
  /**
1356
1446
  * Private method for shared signing logic
1357
1447
  */
1358
- async performTransactionSigning(params, includeSubmissionConfig) {
1448
+ async performTransactionSigning(params, includeSubmissionConfig, presignTransaction) {
1359
1449
  const walletId = params.walletId;
1360
1450
  const encodedTransaction = params.transaction;
1361
1451
  const networkIdParam = params.networkId;
@@ -1378,13 +1468,25 @@ var PhantomClient = class {
1378
1468
  curve: networkConfig.curve,
1379
1469
  addressFormat: networkConfig.addressFormat
1380
1470
  };
1381
- const transactionForSigning = await this.getTransactionForSigning({
1471
+ const authenticatorPublicKey = this.getAuthenticatorPublicKey();
1472
+ let transactionForSigning = await this.getTransactionForSigning({
1382
1473
  encodedTransaction,
1383
1474
  networkId: networkIdParam,
1384
1475
  submissionConfig,
1476
+ authenticatorPublicKey,
1385
1477
  account: params.account,
1386
1478
  methodName
1387
1479
  });
1480
+ if (presignTransaction && typeof transactionForSigning === "string") {
1481
+ try {
1482
+ transactionForSigning = await presignTransaction(transactionForSigning, {
1483
+ networkId: networkIdParam,
1484
+ walletId
1485
+ });
1486
+ } catch (hookError) {
1487
+ throw new Error(`presignTransaction hook failed: ${getErrorMessage(hookError, "unknown error")}`);
1488
+ }
1489
+ }
1388
1490
  const signRequest = {
1389
1491
  organizationId: this.config.organizationId,
1390
1492
  walletId,
@@ -1404,6 +1506,10 @@ var PhantomClient = class {
1404
1506
  params: signRequest,
1405
1507
  timestampMs: await getSecureTimestamp()
1406
1508
  };
1509
+ this.logger?.debug(
1510
+ `[TX_DEBUG] KMS request: methodName=${methodName} networkId=${networkIdParam} walletId=${walletId} account=${params.account}`
1511
+ );
1512
+ this.logger?.debug(`[TX_DEBUG] transactionForSigning=${JSON.stringify(transactionForSigning)}`);
1407
1513
  const response = await this.kmsApi.postKmsRpc(request, {
1408
1514
  headers: {
1409
1515
  "X-Rpc-Method": methodName
@@ -1411,7 +1517,29 @@ var PhantomClient = class {
1411
1517
  });
1412
1518
  const result = response.data.result;
1413
1519
  const rpcSubmissionResult = response.data["rpc_submission_result"];
1414
- const hash = includeSubmissionConfig && rpcSubmissionResult ? rpcSubmissionResult.result : null;
1520
+ this.logger?.debug(
1521
+ `[TX_DEBUG] KMS response: methodName=${methodName} hasResult=${!!result} rpcSubmissionResult=${JSON.stringify(rpcSubmissionResult)} fullResponse=${JSON.stringify(response.data)}`
1522
+ );
1523
+ let hash = void 0;
1524
+ if (includeSubmissionConfig && rpcSubmissionResult) {
1525
+ if (rpcSubmissionResult.error) {
1526
+ const { error } = rpcSubmissionResult;
1527
+ throw new Error(
1528
+ `Transaction broadcast failed: ${error.data ?? error.message ?? JSON.stringify(rpcSubmissionResult)}`
1529
+ );
1530
+ }
1531
+ const envelope = rpcSubmissionResult.result;
1532
+ if (envelope != null) {
1533
+ if (typeof envelope === "string") {
1534
+ hash = envelope;
1535
+ } else if (typeof envelope.result === "string") {
1536
+ hash = envelope.result;
1537
+ } else if (envelope.error) {
1538
+ const { error } = envelope;
1539
+ throw new Error(`Transaction broadcast failed: ${error.data ?? error.message ?? JSON.stringify(envelope)}`);
1540
+ }
1541
+ }
1542
+ }
1415
1543
  return {
1416
1544
  signedTransaction: result.transaction,
1417
1545
  // Base64 encoded signed transaction
@@ -1422,6 +1550,11 @@ var PhantomClient = class {
1422
1550
  if (error instanceof WalletServiceError) {
1423
1551
  throw error;
1424
1552
  }
1553
+ const axiosStatus = error.response?.status;
1554
+ const axiosData = error.response?.data;
1555
+ this.logger?.error(
1556
+ `[TX_DEBUG] performTransactionSigning failed: methodName=${methodName} status=${axiosStatus} body=${JSON.stringify(axiosData)}`
1557
+ );
1425
1558
  throw new Error(getErrorMessage(error, `Failed to ${actionType} transaction`));
1426
1559
  }
1427
1560
  }
@@ -1429,7 +1562,7 @@ var PhantomClient = class {
1429
1562
  * Sign a transaction
1430
1563
  */
1431
1564
  async signTransaction(params) {
1432
- const result = await this.performTransactionSigning(params, false);
1565
+ const result = await this.performTransactionSigning(params, false, params.presignTransaction);
1433
1566
  return {
1434
1567
  rawTransaction: result.signedTransaction
1435
1568
  };
@@ -1438,7 +1571,7 @@ var PhantomClient = class {
1438
1571
  * Sign and send a transaction
1439
1572
  */
1440
1573
  async signAndSendTransaction(params) {
1441
- const result = await this.performTransactionSigning(params, true);
1574
+ const result = await this.performTransactionSigning(params, true, params.presignTransaction);
1442
1575
  return {
1443
1576
  rawTransaction: result.signedTransaction,
1444
1577
  hash: result.hash
@@ -1470,7 +1603,7 @@ var PhantomClient = class {
1470
1603
  }));
1471
1604
  return addresses;
1472
1605
  } catch (error) {
1473
- console.error("Failed to get wallet addresses:", error.response?.data || error.message);
1606
+ this.logger?.error(`Failed to get wallet addresses: ${JSON.stringify(error.response?.data) || error.message}`);
1474
1607
  throw new Error(`Failed to get wallet addresses: ${error.response?.data?.message || error.message}`);
1475
1608
  }
1476
1609
  }
@@ -1510,7 +1643,7 @@ var PhantomClient = class {
1510
1643
  const result = response.data.result;
1511
1644
  return result.signature;
1512
1645
  } catch (error) {
1513
- console.error("Failed to sign Ethereum message:", error.response?.data || error.message);
1646
+ this.logger?.error(`Failed to sign Ethereum message: ${JSON.stringify(error.response?.data) || error.message}`);
1514
1647
  throw new Error(`Failed to sign Ethereum message: ${error.response?.data?.message || error.message}`);
1515
1648
  }
1516
1649
  }
@@ -1551,7 +1684,7 @@ var PhantomClient = class {
1551
1684
  const result = response.data.result;
1552
1685
  return result.signature;
1553
1686
  } catch (error) {
1554
- console.error("Failed to sign raw payload:", error.response?.data || error.message);
1687
+ this.logger?.error(`Failed to sign raw payload: ${JSON.stringify(error.response?.data) || error.message}`);
1555
1688
  throw new Error(`Failed to sign raw payload: ${error.response?.data?.message || error.message}`);
1556
1689
  }
1557
1690
  }
@@ -1590,7 +1723,7 @@ var PhantomClient = class {
1590
1723
  const result = response.data.result;
1591
1724
  return result.signature;
1592
1725
  } catch (error) {
1593
- console.error("Failed to sign typed data:", error.response?.data || error.message);
1726
+ this.logger?.error(`Failed to sign typed data: ${JSON.stringify(error.response?.data) || error.message}`);
1594
1727
  throw new Error(`Failed to sign typed data: ${error.response?.data?.message || error.message}`);
1595
1728
  }
1596
1729
  }
@@ -1617,7 +1750,7 @@ var PhantomClient = class {
1617
1750
  offset: result.offset
1618
1751
  };
1619
1752
  } catch (error) {
1620
- console.error("Failed to get wallets:", error.response?.data || error.message);
1753
+ this.logger?.error(`Failed to get wallets: ${JSON.stringify(error.response?.data) || error.message}`);
1621
1754
  throw new Error(`Failed to get wallets: ${error.response?.data?.message || error.message}`);
1622
1755
  }
1623
1756
  }
@@ -1637,7 +1770,7 @@ var PhantomClient = class {
1637
1770
  const result = response.data.result;
1638
1771
  return result;
1639
1772
  } catch (error) {
1640
- console.error("Failed to get organization:", error.response?.data || error.message);
1773
+ this.logger?.error(`Failed to get organization: ${JSON.stringify(error.response?.data) || error.message}`);
1641
1774
  throw new Error(`Failed to get organization: ${error.response?.data?.message || error.message}`);
1642
1775
  }
1643
1776
  }
@@ -1691,7 +1824,7 @@ var PhantomClient = class {
1691
1824
  const result = response.data.result;
1692
1825
  return result;
1693
1826
  } catch (error) {
1694
- console.error("Failed to create organization:", error.response?.data || error.message);
1827
+ this.logger?.error(`Failed to create organization: ${JSON.stringify(error.response?.data) || error.message}`);
1695
1828
  throw new Error(`Failed to create organization: ${error.response?.data?.message || error.message}`);
1696
1829
  }
1697
1830
  }
@@ -1725,7 +1858,7 @@ var PhantomClient = class {
1725
1858
  const result = response.data.result;
1726
1859
  return result;
1727
1860
  } catch (error) {
1728
- console.error("Failed to create authenticator:", error.response?.data || error.message);
1861
+ this.logger?.error(`Failed to create authenticator: ${JSON.stringify(error.response?.data) || error.message}`);
1729
1862
  throw new Error(`Failed to create authenticator: ${error.response?.data?.message || error.message}`);
1730
1863
  }
1731
1864
  }
@@ -1748,7 +1881,7 @@ var PhantomClient = class {
1748
1881
  const result = response.data.result;
1749
1882
  return result;
1750
1883
  } catch (error) {
1751
- console.error("Failed to delete authenticator:", error.response?.data || error.message);
1884
+ this.logger?.error(`Failed to delete authenticator: ${JSON.stringify(error.response?.data) || error.message}`);
1752
1885
  throw new Error(`Failed to delete authenticator: ${error.response?.data?.message || error.message}`);
1753
1886
  }
1754
1887
  }
@@ -1763,7 +1896,9 @@ var PhantomClient = class {
1763
1896
  const result = response.data.result;
1764
1897
  return result;
1765
1898
  } catch (error) {
1766
- console.error("Failed to grant organization access:", error.response?.data || error.message);
1899
+ this.logger?.error(
1900
+ `Failed to grant organization access: ${JSON.stringify(error.response?.data) || error.message}`
1901
+ );
1767
1902
  throw new Error(`Failed to grant organization access: ${error.response?.data?.message || error.message}`);
1768
1903
  }
1769
1904
  }
@@ -1779,7 +1914,9 @@ var PhantomClient = class {
1779
1914
  };
1780
1915
  await this.kmsApi.postKmsRpc(request);
1781
1916
  } catch (error) {
1782
- console.error("Failed to add user to organization:", error.response?.data || error.message);
1917
+ this.logger?.error(
1918
+ `Failed to add user to organization: ${JSON.stringify(error.response?.data) || error.message}`
1919
+ );
1783
1920
  throw new Error(`Failed to add user to organization: ${error.response?.data?.message || error.message}`);
1784
1921
  }
1785
1922
  }
@@ -1801,7 +1938,7 @@ var PhantomClient = class {
1801
1938
  const result = response.data.result;
1802
1939
  return result;
1803
1940
  } catch (error) {
1804
- console.error("Failed to get wallet with tag:", error.response?.data || error.message);
1941
+ this.logger?.error(`Failed to get wallet with tag: ${JSON.stringify(error.response?.data) || error.message}`);
1805
1942
  throw new Error(`Failed to get wallet with tag: ${error.response?.data?.message || error.message}`);
1806
1943
  }
1807
1944
  }
@@ -1834,6 +1971,22 @@ var __privateMethod = (obj, member, method) => {
1834
1971
  return method;
1835
1972
  };
1836
1973
 
1974
+ // src/extension/isInstalled.ts
1975
+ function isInstalled() {
1976
+ try {
1977
+ const phantom = window?.phantom;
1978
+ return !!phantom;
1979
+ } catch (error) {
1980
+ return false;
1981
+ }
1982
+ }
1983
+
1984
+ // src/errors.ts
1985
+ var PHANTOM_NOT_DETECTED = "Phantom wallet not detected.";
1986
+ var ETHEREUM_PROVIDER_NOT_FOUND = "Ethereum provider not found on window.phantom.";
1987
+ var SOLANA_PROVIDER_NOT_FOUND = "Solana provider not found on window.phantom.";
1988
+ var APP_PROVIDER_NOT_FOUND = "App provider not found on window.phantom.";
1989
+
1837
1990
  // src/ethereum/siwe.ts
1838
1991
  var ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
1839
1992
  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})?$/;
@@ -1958,7 +2111,7 @@ function splitUri(value) {
1958
2111
  }
1959
2112
 
1960
2113
  // src/ethereum/strategies/injected.ts
1961
- var MAX_RETRIES$1 = 4;
2114
+ var MAX_RETRIES$1 = 6;
1962
2115
  var BASE_DELAY$1 = 100;
1963
2116
  var _getProvider$1, getProvider_fn$1;
1964
2117
  var InjectedEthereumStrategy = class {
@@ -1977,7 +2130,11 @@ var InjectedEthereumStrategy = class {
1977
2130
  }
1978
2131
  retryCount++;
1979
2132
  if (retryCount >= MAX_RETRIES$1) {
1980
- reject();
2133
+ if (!isInstalled()) {
2134
+ reject(new Error(PHANTOM_NOT_DETECTED));
2135
+ } else {
2136
+ reject(new Error(ETHEREUM_PROVIDER_NOT_FOUND));
2137
+ }
1981
2138
  } else {
1982
2139
  scheduleRetry(resolve, reject);
1983
2140
  }
@@ -1997,7 +2154,7 @@ var InjectedEthereumStrategy = class {
1997
2154
  async connect({ onlyIfTrusted }) {
1998
2155
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
1999
2156
  if (!provider) {
2000
- throw new Error("Provider not found.");
2157
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2001
2158
  }
2002
2159
  if (provider.isConnected && provider.selectedAddress) {
2003
2160
  return this.getAccounts();
@@ -2029,7 +2186,7 @@ var InjectedEthereumStrategy = class {
2029
2186
  async signMessage(message, address) {
2030
2187
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2031
2188
  if (!provider) {
2032
- throw new Error("Provider not found.");
2189
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2033
2190
  }
2034
2191
  if (!provider.isConnected) {
2035
2192
  throw new Error("Provider is not connected.");
@@ -2043,7 +2200,7 @@ var InjectedEthereumStrategy = class {
2043
2200
  async signPersonalMessage(message, address) {
2044
2201
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2045
2202
  if (!provider) {
2046
- throw new Error("Provider not found.");
2203
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2047
2204
  }
2048
2205
  if (!provider.isConnected) {
2049
2206
  throw new Error("Provider is not connected.");
@@ -2057,7 +2214,7 @@ var InjectedEthereumStrategy = class {
2057
2214
  async signTypedData(typedData, address) {
2058
2215
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2059
2216
  if (!provider) {
2060
- throw new Error("Provider not found.");
2217
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2061
2218
  }
2062
2219
  if (!provider.isConnected) {
2063
2220
  throw new Error("Provider is not connected.");
@@ -2071,7 +2228,7 @@ var InjectedEthereumStrategy = class {
2071
2228
  async signIn(signInData) {
2072
2229
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2073
2230
  if (!provider) {
2074
- throw new Error("Provider not found.");
2231
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2075
2232
  }
2076
2233
  const message = createSiweMessage(signInData);
2077
2234
  const address = provider.selectedAddress;
@@ -2088,7 +2245,7 @@ var InjectedEthereumStrategy = class {
2088
2245
  async sendTransaction(transaction) {
2089
2246
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2090
2247
  if (!provider) {
2091
- throw new Error("Provider not found.");
2248
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2092
2249
  }
2093
2250
  if (!provider.isConnected) {
2094
2251
  throw new Error("Provider is not connected.");
@@ -2102,7 +2259,7 @@ var InjectedEthereumStrategy = class {
2102
2259
  async signTransaction(transaction) {
2103
2260
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2104
2261
  if (!provider) {
2105
- throw new Error("Provider not found.");
2262
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2106
2263
  }
2107
2264
  if (!provider.isConnected) {
2108
2265
  throw new Error("Provider is not connected.");
@@ -2116,7 +2273,7 @@ var InjectedEthereumStrategy = class {
2116
2273
  async getChainId() {
2117
2274
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2118
2275
  if (!provider) {
2119
- throw new Error("Provider not found.");
2276
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2120
2277
  }
2121
2278
  const chainId = await provider.request({ method: "eth_chainId" });
2122
2279
  return chainId;
@@ -2124,7 +2281,7 @@ var InjectedEthereumStrategy = class {
2124
2281
  async switchChain(chainId) {
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
  await provider.request({
2130
2287
  method: "wallet_switchEthereumChain",
@@ -2134,29 +2291,25 @@ var InjectedEthereumStrategy = class {
2134
2291
  async request(args) {
2135
2292
  const provider = __privateMethod(this, _getProvider$1, getProvider_fn$1).call(this);
2136
2293
  if (!provider) {
2137
- throw new Error("Provider not found.");
2294
+ throw new Error(ETHEREUM_PROVIDER_NOT_FOUND);
2138
2295
  }
2139
2296
  return await provider.request(args);
2140
2297
  }
2141
2298
  };
2142
2299
  _getProvider$1 = new WeakSet();
2143
2300
  getProvider_fn$1 = function() {
2144
- if (typeof window === "undefined") {
2301
+ if (!isInstalled()) {
2145
2302
  return void 0;
2146
2303
  }
2147
- return window?.phantom?.ethereum;
2304
+ return window.phantom.ethereum;
2148
2305
  };
2149
2306
 
2150
2307
  // src/ethereum/getProvider.ts
2151
2308
  async function getProvider$2(strategy = "injected" /* INJECTED */) {
2152
2309
  if (strategy === "injected") {
2153
2310
  const provider = new InjectedEthereumStrategy();
2154
- try {
2155
- await provider.load();
2156
- return provider;
2157
- } catch (error) {
2158
- throw new Error("Provider not found.");
2159
- }
2311
+ await provider.load();
2312
+ return provider;
2160
2313
  } else {
2161
2314
  throw new Error("Invalid provider type.");
2162
2315
  }
@@ -2194,9 +2347,6 @@ function triggerEvent$1(event, data) {
2194
2347
  // src/ethereum/connect.ts
2195
2348
  async function connect$1({ onlyIfTrusted = false } = {}) {
2196
2349
  const provider = await getProvider$2();
2197
- if (!provider) {
2198
- throw new Error("Provider not found.");
2199
- }
2200
2350
  if (provider.isConnected) {
2201
2351
  const accounts = await provider.getAccounts();
2202
2352
  return accounts;
@@ -2226,9 +2376,6 @@ async function connect$1({ onlyIfTrusted = false } = {}) {
2226
2376
  // src/ethereum/disconnect.ts
2227
2377
  async function disconnect$1() {
2228
2378
  const provider = await getProvider$2();
2229
- if (!provider) {
2230
- throw new Error("Provider not found.");
2231
- }
2232
2379
  await provider.disconnect();
2233
2380
  triggerEvent$1("disconnect", []);
2234
2381
  }
@@ -2236,18 +2383,12 @@ async function disconnect$1() {
2236
2383
  // src/ethereum/getAccounts.ts
2237
2384
  async function getAccounts() {
2238
2385
  const provider = await getProvider$2();
2239
- if (!provider) {
2240
- throw new Error("Provider not found.");
2241
- }
2242
2386
  return provider.getAccounts();
2243
2387
  }
2244
2388
 
2245
2389
  // src/ethereum/signMessage.ts
2246
2390
  async function signPersonalMessage(message, address) {
2247
2391
  const provider = await getProvider$2();
2248
- if (!provider) {
2249
- throw new Error("Provider not found.");
2250
- }
2251
2392
  if (!provider.isConnected) {
2252
2393
  await provider.connect({ onlyIfTrusted: false });
2253
2394
  }
@@ -2255,9 +2396,6 @@ async function signPersonalMessage(message, address) {
2255
2396
  }
2256
2397
  async function signTypedData(typedData, address) {
2257
2398
  const provider = await getProvider$2();
2258
- if (!provider) {
2259
- throw new Error("Provider not found.");
2260
- }
2261
2399
  if (!provider.isConnected) {
2262
2400
  await provider.connect({ onlyIfTrusted: false });
2263
2401
  }
@@ -2267,9 +2405,6 @@ async function signTypedData(typedData, address) {
2267
2405
  // src/ethereum/sendTransaction.ts
2268
2406
  async function sendTransaction(transaction) {
2269
2407
  const provider = await getProvider$2();
2270
- if (!provider) {
2271
- throw new Error("Provider not found.");
2272
- }
2273
2408
  if (!provider.isConnected) {
2274
2409
  await provider.connect({ onlyIfTrusted: false });
2275
2410
  }
@@ -2277,9 +2412,6 @@ async function sendTransaction(transaction) {
2277
2412
  }
2278
2413
  async function signTransaction$1(transaction) {
2279
2414
  const provider = await getProvider$2();
2280
- if (!provider) {
2281
- throw new Error("Provider not found.");
2282
- }
2283
2415
  if (!provider.isConnected) {
2284
2416
  await provider.connect({ onlyIfTrusted: false });
2285
2417
  }
@@ -2289,16 +2421,10 @@ async function signTransaction$1(transaction) {
2289
2421
  // src/ethereum/chainUtils.ts
2290
2422
  async function getChainId() {
2291
2423
  const provider = await getProvider$2();
2292
- if (!provider) {
2293
- throw new Error("Provider not found.");
2294
- }
2295
2424
  return provider.getChainId();
2296
2425
  }
2297
2426
  async function switchChain(chainId) {
2298
2427
  const provider = await getProvider$2();
2299
- if (!provider) {
2300
- throw new Error("Provider not found.");
2301
- }
2302
2428
  return provider.switchChain(chainId);
2303
2429
  }
2304
2430
 
@@ -2309,9 +2435,6 @@ var Ethereum = class {
2309
2435
  this._accounts = [];
2310
2436
  this.bindProviderEvents();
2311
2437
  }
2312
- get connected() {
2313
- return this._accounts.length > 0;
2314
- }
2315
2438
  get chainId() {
2316
2439
  return this._chainId;
2317
2440
  }
@@ -2320,9 +2443,6 @@ var Ethereum = class {
2320
2443
  }
2321
2444
  async request(args) {
2322
2445
  const provider = await getProvider$2();
2323
- if (!provider) {
2324
- throw new Error("Provider not found.");
2325
- }
2326
2446
  const providerInstance = provider.getProvider();
2327
2447
  if (!providerInstance) {
2328
2448
  throw new Error("Provider instance not found.");
@@ -2423,16 +2543,6 @@ function createEthereumPlugin() {
2423
2543
  };
2424
2544
  }
2425
2545
 
2426
- // src/extension/isInstalled.ts
2427
- function isInstalled() {
2428
- try {
2429
- const phantom = window?.phantom;
2430
- return !!phantom;
2431
- } catch (error) {
2432
- return false;
2433
- }
2434
- }
2435
-
2436
2546
  // src/extension/plugin.ts
2437
2547
  var extension = {
2438
2548
  isInstalled
@@ -2454,7 +2564,7 @@ function createPhantom({ plugins = [] }) {
2454
2564
  }
2455
2565
 
2456
2566
  // src/solana/strategies/injected.ts
2457
- var MAX_RETRIES = 4;
2567
+ var MAX_RETRIES = 6;
2458
2568
  var BASE_DELAY = 100;
2459
2569
  var _getProvider, getProvider_fn;
2460
2570
  var InjectedSolanaStrategy = class {
@@ -2473,7 +2583,11 @@ var InjectedSolanaStrategy = class {
2473
2583
  }
2474
2584
  retryCount++;
2475
2585
  if (retryCount >= MAX_RETRIES) {
2476
- reject();
2586
+ if (!isInstalled()) {
2587
+ reject(new Error(PHANTOM_NOT_DETECTED));
2588
+ } else {
2589
+ reject(new Error(SOLANA_PROVIDER_NOT_FOUND));
2590
+ }
2477
2591
  } else {
2478
2592
  scheduleRetry(resolve, reject);
2479
2593
  }
@@ -2493,7 +2607,7 @@ var InjectedSolanaStrategy = class {
2493
2607
  async connect({ onlyIfTrusted }) {
2494
2608
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2495
2609
  if (!provider) {
2496
- throw new Error("Provider not found.");
2610
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2497
2611
  }
2498
2612
  if (provider.isConnected && provider.publicKey) {
2499
2613
  return this.getAccount() ?? void 0;
@@ -2508,7 +2622,7 @@ var InjectedSolanaStrategy = class {
2508
2622
  async disconnect() {
2509
2623
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2510
2624
  if (!provider) {
2511
- throw new Error("Provider not found.");
2625
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2512
2626
  }
2513
2627
  await provider.disconnect();
2514
2628
  }
@@ -2522,7 +2636,7 @@ var InjectedSolanaStrategy = class {
2522
2636
  async signMessage(message, display) {
2523
2637
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2524
2638
  if (!provider) {
2525
- throw new Error("Provider not found.");
2639
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2526
2640
  }
2527
2641
  if (!provider.isConnected) {
2528
2642
  throw new Error("Provider is not connected.");
@@ -2536,7 +2650,7 @@ var InjectedSolanaStrategy = class {
2536
2650
  async signIn(signInData) {
2537
2651
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2538
2652
  if (!provider) {
2539
- throw new Error("Provider not found.");
2653
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2540
2654
  }
2541
2655
  const result = await provider.signIn(signInData);
2542
2656
  return {
@@ -2548,7 +2662,7 @@ var InjectedSolanaStrategy = class {
2548
2662
  async signAndSendTransaction(transaction) {
2549
2663
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2550
2664
  if (!provider) {
2551
- throw new Error("Provider not found.");
2665
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2552
2666
  }
2553
2667
  if (!provider.isConnected) {
2554
2668
  throw new Error("Provider is not connected.");
@@ -2562,7 +2676,7 @@ var InjectedSolanaStrategy = class {
2562
2676
  async signAndSendAllTransactions(transactions) {
2563
2677
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2564
2678
  if (!provider) {
2565
- throw new Error("Provider not found.");
2679
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2566
2680
  }
2567
2681
  if (!provider.isConnected) {
2568
2682
  throw new Error("Provider is not connected.");
@@ -2579,7 +2693,7 @@ var InjectedSolanaStrategy = class {
2579
2693
  async signTransaction(transaction) {
2580
2694
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2581
2695
  if (!provider) {
2582
- throw new Error("Provider not found.");
2696
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2583
2697
  }
2584
2698
  if (!provider.isConnected) {
2585
2699
  throw new Error("Provider is not connected.");
@@ -2590,7 +2704,7 @@ var InjectedSolanaStrategy = class {
2590
2704
  async signAllTransactions(transactions) {
2591
2705
  const provider = __privateMethod(this, _getProvider, getProvider_fn).call(this);
2592
2706
  if (!provider) {
2593
- throw new Error("Provider not found.");
2707
+ throw new Error(SOLANA_PROVIDER_NOT_FOUND);
2594
2708
  }
2595
2709
  if (!provider.isConnected) {
2596
2710
  throw new Error("Provider is not connected.");
@@ -2601,22 +2715,18 @@ var InjectedSolanaStrategy = class {
2601
2715
  };
2602
2716
  _getProvider = new WeakSet();
2603
2717
  getProvider_fn = function() {
2604
- if (typeof window === "undefined") {
2718
+ if (!isInstalled()) {
2605
2719
  return void 0;
2606
2720
  }
2607
- return window?.phantom?.solana;
2721
+ return window.phantom.solana;
2608
2722
  };
2609
2723
 
2610
2724
  // src/solana/getProvider.ts
2611
2725
  async function getProvider$1(strategy = "injected" /* INJECTED */) {
2612
2726
  if (strategy === "injected") {
2613
2727
  const provider = new InjectedSolanaStrategy();
2614
- try {
2615
- await provider.load();
2616
- return provider;
2617
- } catch (error) {
2618
- throw new Error("Provider not found.");
2619
- }
2728
+ await provider.load();
2729
+ return provider;
2620
2730
  } else {
2621
2731
  throw new Error("Invalid provider type.");
2622
2732
  }
@@ -2656,9 +2766,6 @@ function triggerEvent(event, ...args) {
2656
2766
  // src/solana/connect.ts
2657
2767
  async function connect({ onlyIfTrusted = false } = {}) {
2658
2768
  const provider = await getProvider$1();
2659
- if (!provider) {
2660
- throw new Error("Provider not found.");
2661
- }
2662
2769
  if (provider.isConnected) {
2663
2770
  return provider.getAccount();
2664
2771
  }
@@ -2687,25 +2794,13 @@ async function connect({ onlyIfTrusted = false } = {}) {
2687
2794
  // src/solana/disconnect.ts
2688
2795
  async function disconnect() {
2689
2796
  const provider = await getProvider$1();
2690
- if (!provider) {
2691
- throw new Error("Provider not found.");
2692
- }
2693
2797
  await provider.disconnect();
2694
2798
  triggerEvent("disconnect");
2695
2799
  }
2696
2800
 
2697
- // src/solana/getAccount.ts
2698
- async function getAccount() {
2699
- const provider = await getProvider$1();
2700
- return provider.getAccount();
2701
- }
2702
-
2703
2801
  // src/solana/signAndSendTransaction.ts
2704
2802
  async function signAndSendTransaction(transaction) {
2705
2803
  const provider = await getProvider$1();
2706
- if (!provider) {
2707
- throw new Error("Provider not found.");
2708
- }
2709
2804
  if (!provider.isConnected) {
2710
2805
  await provider.connect({ onlyIfTrusted: false });
2711
2806
  }
@@ -2715,9 +2810,6 @@ async function signAndSendTransaction(transaction) {
2715
2810
  // src/solana/signAndSendAllTransactions.ts
2716
2811
  async function signAndSendAllTransactions(transactions) {
2717
2812
  const provider = await getProvider$1();
2718
- if (!provider) {
2719
- throw new Error("Provider not found.");
2720
- }
2721
2813
  if (!provider.isConnected) {
2722
2814
  await provider.connect({ onlyIfTrusted: false });
2723
2815
  }
@@ -2727,9 +2819,6 @@ async function signAndSendAllTransactions(transactions) {
2727
2819
  // src/solana/signTransaction.ts
2728
2820
  async function signTransaction(transaction) {
2729
2821
  const provider = await getProvider$1();
2730
- if (!provider) {
2731
- throw new Error("Provider not found.");
2732
- }
2733
2822
  if (!provider.isConnected) {
2734
2823
  await provider.connect({ onlyIfTrusted: false });
2735
2824
  }
@@ -2739,9 +2828,6 @@ async function signTransaction(transaction) {
2739
2828
  // src/solana/signAllTransactions.ts
2740
2829
  async function signAllTransactions(transactions) {
2741
2830
  const provider = await getProvider$1();
2742
- if (!provider) {
2743
- throw new Error("Provider not found.");
2744
- }
2745
2831
  if (!provider.isConnected) {
2746
2832
  await provider.connect({ onlyIfTrusted: false });
2747
2833
  }
@@ -2751,9 +2837,6 @@ async function signAllTransactions(transactions) {
2751
2837
  // src/solana/signMessage.ts
2752
2838
  async function signMessage(message, display) {
2753
2839
  const provider = await getProvider$1();
2754
- if (!provider) {
2755
- throw new Error("Provider not found.");
2756
- }
2757
2840
  if (!provider.isConnected) {
2758
2841
  await provider.connect({ onlyIfTrusted: false });
2759
2842
  }
@@ -2769,7 +2852,7 @@ var Solana = class {
2769
2852
  get publicKey() {
2770
2853
  return this._publicKey;
2771
2854
  }
2772
- get connected() {
2855
+ get isConnected() {
2773
2856
  return this._publicKey !== null;
2774
2857
  }
2775
2858
  async connect(options) {
@@ -2809,21 +2892,6 @@ var Solana = class {
2809
2892
  async switchNetwork(_network) {
2810
2893
  return Promise.resolve();
2811
2894
  }
2812
- async getPublicKey() {
2813
- if (this._publicKey) {
2814
- return this._publicKey;
2815
- }
2816
- try {
2817
- const account = await getAccount();
2818
- this._publicKey = account || null;
2819
- return this._publicKey;
2820
- } catch {
2821
- return null;
2822
- }
2823
- }
2824
- isConnected() {
2825
- return this._publicKey !== null;
2826
- }
2827
2895
  on(event, listener) {
2828
2896
  addEventListener(event, listener);
2829
2897
  }
@@ -2873,20 +2941,17 @@ function createSolanaPlugin() {
2873
2941
 
2874
2942
  // src/auto-confirm/getProvider.ts
2875
2943
  function getProvider() {
2876
- if (typeof window === "undefined") {
2877
- return null;
2944
+ if (!isInstalled()) {
2945
+ throw new Error(PHANTOM_NOT_DETECTED);
2878
2946
  }
2879
- const provider = window?.phantom?.app;
2947
+ const provider = window.phantom.app;
2880
2948
  if (!provider) {
2881
- return null;
2949
+ throw new Error(APP_PROVIDER_NOT_FOUND);
2882
2950
  }
2883
2951
  return provider;
2884
2952
  }
2885
2953
  async function autoConfirmEnable(params) {
2886
- const provider = await getProvider();
2887
- if (!provider) {
2888
- throw new Error("Provider not found.");
2889
- }
2954
+ const provider = getProvider();
2890
2955
  const transformedParams = params?.chains ? { chains: params.chains.map(networkIdToInternalCaip) } : {};
2891
2956
  const result = await provider.request({
2892
2957
  method: "phantom_auto_confirm_enable",
@@ -2898,10 +2963,7 @@ async function autoConfirmEnable(params) {
2898
2963
  };
2899
2964
  }
2900
2965
  async function autoConfirmDisable() {
2901
- const provider = await getProvider();
2902
- if (!provider) {
2903
- throw new Error("Provider not found.");
2904
- }
2966
+ const provider = getProvider();
2905
2967
  const result = await provider.request({
2906
2968
  method: "phantom_auto_confirm_disable",
2907
2969
  params: {}
@@ -2912,10 +2974,7 @@ async function autoConfirmDisable() {
2912
2974
  };
2913
2975
  }
2914
2976
  async function autoConfirmStatus() {
2915
- const provider = await getProvider();
2916
- if (!provider) {
2917
- throw new Error("Provider not found.");
2918
- }
2977
+ const provider = getProvider();
2919
2978
  const result = await provider.request({
2920
2979
  method: "phantom_auto_confirm_status",
2921
2980
  params: {}
@@ -2926,10 +2985,7 @@ async function autoConfirmStatus() {
2926
2985
  };
2927
2986
  }
2928
2987
  async function autoConfirmSupportedChains() {
2929
- const provider = await getProvider();
2930
- if (!provider) {
2931
- throw new Error("Provider not found.");
2932
- }
2988
+ const provider = getProvider();
2933
2989
  const result = await provider.request({
2934
2990
  method: "phantom_auto_confirm_supported_chains",
2935
2991
  params: {}
@@ -3350,7 +3406,7 @@ function stringToBase64url(str) {
3350
3406
  /**
3351
3407
  * The current version of Ethers.
3352
3408
  */
3353
- const version = "6.16.0";
3409
+ const version = "6.17.0";
3354
3410
 
3355
3411
  /**
3356
3412
  * Property helper functions.
@@ -8676,7 +8732,7 @@ function parseTransactionResponse(base64RawTransaction, networkId, hash) {
8676
8732
  function parseSolanaSignatureResponse(base64Response) {
8677
8733
  try {
8678
8734
  const signatureBytes = base64urlDecode(base64Response);
8679
- const signature = base58.encode(signatureBytes);
8735
+ const signature = bs582.encode(signatureBytes);
8680
8736
  return {
8681
8737
  signature,
8682
8738
  rawSignature: base64Response
@@ -8746,8 +8802,6 @@ function deserializeSolanaTransaction(transactionBytes) {
8746
8802
  throw legacyError;
8747
8803
  }
8748
8804
  }
8749
-
8750
- // src/index.ts
8751
8805
  async function parseToKmsTransaction(transaction, networkId) {
8752
8806
  const networkPrefix = networkId.split(":")[0].toLowerCase();
8753
8807
  switch (networkPrefix) {
@@ -9269,27 +9323,25 @@ var EventEmitter2 = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
9269
9323
  // src/embedded-provider.ts
9270
9324
 
9271
9325
  // src/constants.ts
9272
- var AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1e3;
9326
+ var AUTHENTICATOR_EXPIRATION_TIME_MS = 31 * 24 * 60 * 60 * 1e3;
9273
9327
  var EMBEDDED_PROVIDER_AUTH_TYPES = ["google", "apple", "phantom"];
9274
9328
  var EmbeddedSolanaChain = class {
9275
9329
  constructor(provider) {
9276
9330
  this.provider = provider;
9277
9331
  this.currentNetworkId = NetworkId.SOLANA_MAINNET;
9278
- this._connected = false;
9279
9332
  this._publicKey = null;
9280
9333
  this.eventEmitter = new EventEmitter2();
9281
9334
  this.setupEventListeners();
9282
9335
  this.syncInitialState();
9283
9336
  }
9284
- // Wallet adapter compliant properties
9285
- get connected() {
9286
- return this._connected;
9287
- }
9288
9337
  get publicKey() {
9289
9338
  return this._publicKey;
9290
9339
  }
9340
+ get isConnected() {
9341
+ return this._publicKey !== null;
9342
+ }
9291
9343
  ensureConnected() {
9292
- if (!this.provider.isConnected()) {
9344
+ if (!this.isConnected) {
9293
9345
  throw new Error("Solana chain not available. Ensure SDK is connected.");
9294
9346
  }
9295
9347
  }
@@ -9301,7 +9353,7 @@ var EmbeddedSolanaChain = class {
9301
9353
  message: messageStr,
9302
9354
  networkId: this.currentNetworkId
9303
9355
  });
9304
- const signature = typeof result.signature === "string" ? new Uint8Array(base58.decode(result.signature)) : result.signature;
9356
+ const signature = typeof result.signature === "string" ? new Uint8Array(bs582.decode(result.signature)) : result.signature;
9305
9357
  return {
9306
9358
  signature,
9307
9359
  publicKey: this._publicKey || ""
@@ -9319,11 +9371,12 @@ var EmbeddedSolanaChain = class {
9319
9371
  }
9320
9372
  return signedTransaction;
9321
9373
  }
9322
- async signAndSendTransaction(transaction) {
9374
+ async signAndSendTransaction(transaction, options) {
9323
9375
  this.ensureConnected();
9324
9376
  const result = await this.provider.signAndSendTransaction({
9325
9377
  transaction,
9326
- networkId: this.currentNetworkId
9378
+ networkId: this.currentNetworkId,
9379
+ presignTransaction: options?.presignTransaction
9327
9380
  });
9328
9381
  if (!result.hash) {
9329
9382
  throw new Error("Transaction not submitted");
@@ -9347,7 +9400,7 @@ var EmbeddedSolanaChain = class {
9347
9400
  const solanaAddr = addresses.find((a) => a.addressType === "Solana");
9348
9401
  if (!solanaAddr)
9349
9402
  throw new Error("No Solana address found");
9350
- this.updateConnectionState(true, solanaAddr.address);
9403
+ this._publicKey = solanaAddr.address;
9351
9404
  return Promise.resolve({ publicKey: solanaAddr.address });
9352
9405
  }
9353
9406
  async disconnect() {
@@ -9357,41 +9410,25 @@ var EmbeddedSolanaChain = class {
9357
9410
  this.currentNetworkId = network === "mainnet" ? NetworkId.SOLANA_MAINNET : NetworkId.SOLANA_DEVNET;
9358
9411
  return Promise.resolve();
9359
9412
  }
9360
- getPublicKey() {
9361
- if (!this.provider.isConnected())
9362
- return Promise.resolve(null);
9363
- const addresses = this.provider.getAddresses();
9364
- const solanaAddr = addresses.find((a) => a.addressType === "Solana");
9365
- return Promise.resolve(solanaAddr?.address || null);
9366
- }
9367
- isConnected() {
9368
- return this._connected && this.provider.isConnected();
9369
- }
9370
9413
  setupEventListeners() {
9371
9414
  this.provider.on("connect", (data) => {
9372
9415
  const solanaAddress = data.addresses?.find((addr) => addr.addressType === "Solana");
9373
9416
  if (solanaAddress) {
9374
- this.updateConnectionState(true, solanaAddress.address);
9417
+ this._publicKey = solanaAddress.address;
9375
9418
  this.eventEmitter.emit("connect", solanaAddress.address);
9376
9419
  }
9377
9420
  });
9378
9421
  this.provider.on("disconnect", () => {
9379
- this.updateConnectionState(false, null);
9422
+ this._publicKey = null;
9380
9423
  this.eventEmitter.emit("disconnect");
9381
9424
  });
9382
9425
  }
9383
9426
  syncInitialState() {
9384
- if (this.provider.isConnected()) {
9385
- const addresses = this.provider.getAddresses();
9386
- const solanaAddress = addresses.find((a) => a.addressType === "Solana");
9387
- if (solanaAddress) {
9388
- this.updateConnectionState(true, solanaAddress.address);
9389
- }
9390
- }
9391
- }
9392
- updateConnectionState(connected, publicKey) {
9393
- this._connected = connected;
9394
- this._publicKey = publicKey;
9427
+ if (!this.provider.isConnected())
9428
+ return;
9429
+ const addresses = this.provider.getAddresses();
9430
+ const solanaAddr = addresses.find((a) => a.addressType === "Solana");
9431
+ this._publicKey = solanaAddr?.address || null;
9395
9432
  }
9396
9433
  // Event methods for interface compliance
9397
9434
  on(event, listener) {
@@ -9405,16 +9442,11 @@ var EmbeddedEthereumChain = class {
9405
9442
  constructor(provider) {
9406
9443
  this.provider = provider;
9407
9444
  this.currentNetworkId = NetworkId.ETHEREUM_MAINNET;
9408
- this._connected = false;
9409
9445
  this._accounts = [];
9410
9446
  this.eventEmitter = new EventEmitter2();
9411
9447
  this.setupEventListeners();
9412
9448
  this.syncInitialState();
9413
9449
  }
9414
- // EIP-1193 compliant properties
9415
- get connected() {
9416
- return this._connected;
9417
- }
9418
9450
  get chainId() {
9419
9451
  const chainId = networkIdToChainId(this.currentNetworkId) || 1;
9420
9452
  return `0x${chainId.toString(16)}`;
@@ -9438,7 +9470,7 @@ var EmbeddedEthereumChain = class {
9438
9470
  }
9439
9471
  const addresses = this.provider.getAddresses();
9440
9472
  const ethAddresses = addresses.filter((a) => a.addressType === "Ethereum").map((a) => a.address);
9441
- this.updateConnectionState(true, ethAddresses);
9473
+ this.updateConnectionState(ethAddresses);
9442
9474
  return Promise.resolve(ethAddresses);
9443
9475
  }
9444
9476
  async disconnect() {
@@ -9504,19 +9536,19 @@ var EmbeddedEthereumChain = class {
9504
9536
  return this.request({ method: "eth_accounts" });
9505
9537
  }
9506
9538
  isConnected() {
9507
- return this._connected && this.provider.isConnected();
9539
+ return this.provider.isConnected() && this._accounts.length > 0;
9508
9540
  }
9509
9541
  setupEventListeners() {
9510
9542
  this.provider.on("connect", (data) => {
9511
9543
  const ethAddresses = data.addresses?.filter((addr) => addr.addressType === "Ethereum")?.map((addr) => addr.address) || [];
9512
9544
  if (ethAddresses.length > 0) {
9513
- this.updateConnectionState(true, ethAddresses);
9545
+ this.updateConnectionState(ethAddresses);
9514
9546
  this.eventEmitter.emit("connect", { chainId: this.chainId });
9515
9547
  this.eventEmitter.emit("accountsChanged", ethAddresses);
9516
9548
  }
9517
9549
  });
9518
9550
  this.provider.on("disconnect", () => {
9519
- this.updateConnectionState(false, []);
9551
+ this.updateConnectionState([]);
9520
9552
  this.eventEmitter.emit("disconnect", { code: 4900, message: "Provider disconnected" });
9521
9553
  this.eventEmitter.emit("accountsChanged", []);
9522
9554
  });
@@ -9526,12 +9558,11 @@ var EmbeddedEthereumChain = class {
9526
9558
  const addresses = this.provider.getAddresses();
9527
9559
  const ethAddresses = addresses.filter((a) => a.addressType === "Ethereum").map((a) => a.address);
9528
9560
  if (ethAddresses.length > 0) {
9529
- this.updateConnectionState(true, ethAddresses);
9561
+ this.updateConnectionState(ethAddresses);
9530
9562
  }
9531
9563
  }
9532
9564
  }
9533
- updateConnectionState(connected, accounts) {
9534
- this._connected = connected;
9565
+ updateConnectionState(accounts) {
9535
9566
  this._accounts = accounts;
9536
9567
  }
9537
9568
  async handleEmbeddedRequest(args) {
@@ -9607,7 +9638,7 @@ async function retryWithBackoff(operation, operationName, logger, maxRetries = 3
9607
9638
  let lastError;
9608
9639
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
9609
9640
  try {
9610
- logger.log("EMBEDDED_PROVIDER", `Attempting ${operationName}`, {
9641
+ logger.debug("EMBEDDED_PROVIDER", `Attempting ${operationName}`, {
9611
9642
  attempt,
9612
9643
  maxRetries
9613
9644
  });
@@ -9626,7 +9657,7 @@ async function retryWithBackoff(operation, operationName, logger, maxRetries = 3
9626
9657
  break;
9627
9658
  }
9628
9659
  const delay = baseDelay * Math.pow(2, attempt - 1);
9629
- logger.log("EMBEDDED_PROVIDER", `Retrying ${operationName} in ${delay}ms`, {
9660
+ logger.debug("EMBEDDED_PROVIDER", `Retrying ${operationName} in ${delay}ms`, {
9630
9661
  attempt: attempt + 1,
9631
9662
  delay
9632
9663
  });
@@ -9642,6 +9673,16 @@ function generateSessionId() {
9642
9673
  }
9643
9674
 
9644
9675
  // src/embedded-provider.ts
9676
+ var noopLogger = {
9677
+ info: () => {
9678
+ },
9679
+ warn: () => {
9680
+ },
9681
+ error: () => {
9682
+ },
9683
+ debug: () => {
9684
+ }
9685
+ };
9645
9686
  var EmbeddedProvider$1 = class EmbeddedProvider {
9646
9687
  constructor(config, platform, logger) {
9647
9688
  this.client = null;
@@ -9649,7 +9690,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9649
9690
  this.addresses = [];
9650
9691
  this.eventListeners = /* @__PURE__ */ new Map();
9651
9692
  this.logger = logger;
9652
- this.logger.log("EMBEDDED_PROVIDER", "Initializing EmbeddedProvider", { config });
9693
+ this.logger.debug("EMBEDDED_PROVIDER", "Initializing EmbeddedProvider", { config });
9653
9694
  if (config.embeddedWalletType === "app-wallet") {
9654
9695
  throw new Error("app-wallet type is not currently supported. Please use 'user-wallet' instead.");
9655
9696
  }
@@ -9672,19 +9713,19 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9672
9713
  this.eventListeners.set(event, /* @__PURE__ */ new Set());
9673
9714
  }
9674
9715
  this.eventListeners.get(event)?.add(callback);
9675
- this.logger.log("EMBEDDED_PROVIDER", "Event listener added", { event });
9716
+ this.logger.debug("EMBEDDED_PROVIDER", "Event listener added", { event });
9676
9717
  }
9677
9718
  off(event, callback) {
9678
9719
  const listeners = this.eventListeners.get(event);
9679
9720
  if (listeners) {
9680
9721
  listeners.delete(callback);
9681
- this.logger.log("EMBEDDED_PROVIDER", "Event listener removed", { event });
9722
+ this.logger.debug("EMBEDDED_PROVIDER", "Event listener removed", { event });
9682
9723
  }
9683
9724
  }
9684
9725
  emit(event, data) {
9685
9726
  const listeners = this.eventListeners.get(event);
9686
9727
  if (listeners && listeners.size > 0) {
9687
- this.logger.log("EMBEDDED_PROVIDER", "Emitting event", { event, listenerCount: listeners.size, data });
9728
+ this.logger.debug("EMBEDDED_PROVIDER", "Emitting event", { event, listenerCount: listeners.size, data });
9688
9729
  listeners.forEach((callback) => {
9689
9730
  try {
9690
9731
  callback(data);
@@ -9752,14 +9793,15 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9752
9793
  async validateAndCleanSession(session) {
9753
9794
  if (!session)
9754
9795
  return null;
9755
- this.logger.log("EMBEDDED_PROVIDER", "Found existing session, validating", {
9796
+ this.logger.debug("EMBEDDED_PROVIDER", "Found existing session, validating", {
9756
9797
  sessionId: session.sessionId,
9757
9798
  status: session.status,
9758
9799
  walletId: session.walletId
9759
9800
  });
9760
9801
  if (session.status !== "completed") {
9761
9802
  const urlSessionId = this.urlParamsAccessor.getParam("session_id");
9762
- if (session.status === "pending" && !urlSessionId) {
9803
+ const urlCode = this.urlParamsAccessor.getParam("code");
9804
+ if (session.status === "pending" && !urlSessionId && !urlCode) {
9763
9805
  this.logger.warn("EMBEDDED_PROVIDER", "Session mismatch detected - pending session without redirect context", {
9764
9806
  sessionId: session.sessionId,
9765
9807
  status: session.status
@@ -9797,11 +9839,11 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9797
9839
  * Returns ConnectResult if connection succeeds, null if should continue with new auth flow.
9798
9840
  */
9799
9841
  async tryExistingConnection(isAutoConnect) {
9800
- this.logger.log("EMBEDDED_PROVIDER", "Getting existing session");
9842
+ this.logger.debug("EMBEDDED_PROVIDER", "Getting existing session");
9801
9843
  let session = await this.storage.getSession();
9802
9844
  session = await this.validateAndCleanSession(session);
9803
9845
  if (!session) {
9804
- this.logger.log("EMBEDDED_PROVIDER", "No existing session found");
9846
+ this.logger.debug("EMBEDDED_PROVIDER", "No existing session found");
9805
9847
  return null;
9806
9848
  }
9807
9849
  if (session.status === "completed") {
@@ -9830,9 +9872,9 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9830
9872
  });
9831
9873
  return result;
9832
9874
  }
9833
- this.logger.log("EMBEDDED_PROVIDER", "No completed session found, checking for redirect resume");
9875
+ this.logger.debug("EMBEDDED_PROVIDER", "No completed session found, checking for redirect resume");
9834
9876
  if (this.authProvider.resumeAuthFromRedirect) {
9835
- const authResult = this.authProvider.resumeAuthFromRedirect(session.authProvider);
9877
+ const authResult = await this.authProvider.resumeAuthFromRedirect(session.authProvider);
9836
9878
  if (authResult) {
9837
9879
  this.logger.info("EMBEDDED_PROVIDER", "Resuming from redirect", {
9838
9880
  walletId: authResult.walletId,
@@ -9880,7 +9922,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9880
9922
  return false;
9881
9923
  }
9882
9924
  if (!session.walletId || !session.organizationId || !session.stamperInfo) {
9883
- this.logger.log("EMBEDDED_PROVIDER", "Session missing required fields", {
9925
+ this.logger.debug("EMBEDDED_PROVIDER", "Session missing required fields", {
9884
9926
  hasWalletId: !!session.walletId,
9885
9927
  hasOrganizationId: !!session.organizationId,
9886
9928
  hasStamperInfo: !!session.stamperInfo
@@ -9888,23 +9930,23 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9888
9930
  return false;
9889
9931
  }
9890
9932
  if (session.status !== "completed") {
9891
- this.logger.log("EMBEDDED_PROVIDER", "Session not completed", { status: session.status });
9933
+ this.logger.debug("EMBEDDED_PROVIDER", "Session not completed", { status: session.status });
9892
9934
  return false;
9893
9935
  }
9894
9936
  if (!session.authenticatorExpiresAt) {
9895
- this.logger.log("EMBEDDED_PROVIDER", "Session invalid - missing authenticator timing", {
9937
+ this.logger.debug("EMBEDDED_PROVIDER", "Session invalid - missing authenticator timing", {
9896
9938
  sessionId: session.sessionId
9897
9939
  });
9898
9940
  return false;
9899
9941
  }
9900
9942
  if (Date.now() >= session.authenticatorExpiresAt) {
9901
- this.logger.log("EMBEDDED_PROVIDER", "Authenticator expired, session invalid", {
9943
+ this.logger.debug("EMBEDDED_PROVIDER", "Authenticator expired, session invalid", {
9902
9944
  authenticatorExpiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
9903
9945
  now: (/* @__PURE__ */ new Date()).toISOString()
9904
9946
  });
9905
9947
  return false;
9906
9948
  }
9907
- this.logger.log("EMBEDDED_PROVIDER", "Session is valid", {
9949
+ this.logger.debug("EMBEDDED_PROVIDER", "Session is valid", {
9908
9950
  sessionId: session.sessionId,
9909
9951
  walletId: session.walletId,
9910
9952
  authenticatorExpires: new Date(session.authenticatorExpiresAt).toISOString()
@@ -9918,7 +9960,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9918
9960
  */
9919
9961
  async autoConnect() {
9920
9962
  try {
9921
- this.logger.log("EMBEDDED_PROVIDER", "Starting auto-connect attempt");
9963
+ this.logger.debug("EMBEDDED_PROVIDER", "Starting auto-connect attempt");
9922
9964
  this.emit("connect_start", { source: "auto-connect" });
9923
9965
  const result = await this.tryExistingConnection(true);
9924
9966
  if (result) {
@@ -9932,7 +9974,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9932
9974
  });
9933
9975
  return;
9934
9976
  }
9935
- this.logger.log("EMBEDDED_PROVIDER", "Auto-connect failed: no valid session found");
9977
+ this.logger.debug("EMBEDDED_PROVIDER", "Auto-connect failed: no valid session found");
9936
9978
  this.emit("connect_error", {
9937
9979
  error: "No valid session found",
9938
9980
  source: "auto-connect"
@@ -9953,11 +9995,11 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9953
9995
  * This is the first step when no existing session is found and we need to set up a new wallet.
9954
9996
  */
9955
9997
  async initializeStamper() {
9956
- this.logger.log("EMBEDDED_PROVIDER", "Initializing stamper");
9998
+ this.logger.debug("EMBEDDED_PROVIDER", "Initializing stamper");
9957
9999
  await this.stamper.init();
9958
- this.logger.log("EMBEDDED_PROVIDER", "Resetting keypair to avoid conflicts with existing keypairs");
10000
+ this.logger.debug("EMBEDDED_PROVIDER", "Resetting keypair to avoid conflicts with existing keypairs");
9959
10001
  const stamperInfo = await this.stamper.resetKeyPair();
9960
- this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized with fresh keypair", {
10002
+ this.logger.debug("EMBEDDED_PROVIDER", "Stamper initialized with fresh keypair", {
9961
10003
  publicKey: stamperInfo.publicKey,
9962
10004
  keyId: stamperInfo.keyId,
9963
10005
  algorithm: this.stamper.algorithm
@@ -9974,17 +10016,18 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9974
10016
  apiBaseUrl: this.config.apiBaseUrl,
9975
10017
  headers: {
9976
10018
  ...this.platform.analyticsHeaders || {}
9977
- }
10019
+ },
10020
+ logger: noopLogger
9978
10021
  });
9979
10022
  const platformName = this.platform.name || "unknown";
9980
10023
  const shortPubKey = stamperInfo.publicKey.slice(0, 8);
9981
10024
  const organizationName = `${this.config.appId.substring(0, 8)}-${platformName}-${shortPubKey}`;
9982
- this.logger.log("EMBEDDED_PROVIDER", "Creating organization for app-wallet", {
10025
+ this.logger.debug("EMBEDDED_PROVIDER", "Creating organization for app-wallet", {
9983
10026
  organizationName,
9984
10027
  publicKey: stamperInfo.publicKey,
9985
10028
  platform: platformName
9986
10029
  });
9987
- const base64urlPublicKey = base64urlEncode(base58.decode(stamperInfo.publicKey));
10030
+ const base64urlPublicKey = base64urlEncode(bs582.decode(stamperInfo.publicKey));
9988
10031
  const username = `user-${randomUUID()}`;
9989
10032
  const { organizationId } = await tempClient.createOrganization(organizationName, [
9990
10033
  {
@@ -9995,7 +10038,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
9995
10038
  authenticatorName: `auth-${shortPubKey}`,
9996
10039
  authenticatorKind: "keypair",
9997
10040
  publicKey: base64urlPublicKey,
9998
- algorithm: "Ed25519",
10041
+ algorithm: this.stamper.algorithm,
9999
10042
  expiresInMs
10000
10043
  }
10001
10044
  ]
@@ -10099,7 +10142,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10099
10142
  async disconnect(shouldClearPreviousSession = true) {
10100
10143
  const wasConnected = this.client !== null;
10101
10144
  await this.storage.setShouldClearPreviousSession(shouldClearPreviousSession);
10102
- this.logger.log("EMBEDDED_PROVIDER", "Set flag to clear previous session on next login");
10145
+ this.logger.debug("EMBEDDED_PROVIDER", "Set flag to clear previous session on next login");
10103
10146
  await this.storage.clearSession();
10104
10147
  this.client = null;
10105
10148
  this.walletId = null;
@@ -10111,6 +10154,21 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10111
10154
  });
10112
10155
  }
10113
10156
  }
10157
+ /**
10158
+ * Handles errors from signing operations.
10159
+ * Disconnects the user if the server returns a 401/403 (revoked or expired authenticator).
10160
+ */
10161
+ async handleSigningError(error) {
10162
+ if (isAuthenticationError(error)) {
10163
+ this.logger.warn("EMBEDDED_PROVIDER", "Authenticator rejected by server (401/403), disconnecting", { error });
10164
+ await this.disconnect(false);
10165
+ throw new Error("Authenticator revoked");
10166
+ }
10167
+ if (error instanceof SpendingLimitError) {
10168
+ this.emit("spending_limit_reached", { error });
10169
+ }
10170
+ throw error;
10171
+ }
10114
10172
  async signMessage(params) {
10115
10173
  if (!this.client || !this.walletId) {
10116
10174
  throw new Error("Not connected");
@@ -10127,7 +10185,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10127
10185
  message: params.message,
10128
10186
  networkId: params.networkId,
10129
10187
  derivationIndex
10130
- });
10188
+ }).catch((error) => this.handleSigningError(error));
10131
10189
  this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
10132
10190
  walletId: this.walletId,
10133
10191
  message: params.message
@@ -10160,7 +10218,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10160
10218
  message: base64UrlMessage,
10161
10219
  networkId: params.networkId,
10162
10220
  derivationIndex
10163
- });
10221
+ }).catch((error) => this.handleSigningError(error));
10164
10222
  this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
10165
10223
  walletId: this.walletId,
10166
10224
  message: params.message
@@ -10183,7 +10241,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10183
10241
  typedData: params.typedData,
10184
10242
  networkId: params.networkId,
10185
10243
  derivationIndex
10186
- });
10244
+ }).catch((error) => this.handleSigningError(error));
10187
10245
  this.logger.info("EMBEDDED_PROVIDER", "Typed data signed successfully", {
10188
10246
  walletId: this.walletId
10189
10247
  });
@@ -10201,7 +10259,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10201
10259
  const parsedTransaction = await parseToKmsTransaction(params.transaction, params.networkId);
10202
10260
  const session = await this.storage.getSession();
10203
10261
  const derivationIndex = session?.accountDerivationIndex ?? 0;
10204
- this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10262
+ this.logger.debug("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10205
10263
  walletId: this.walletId,
10206
10264
  transaction: parsedTransaction,
10207
10265
  derivationIndex
@@ -10220,7 +10278,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10220
10278
  networkId: params.networkId,
10221
10279
  derivationIndex,
10222
10280
  account
10223
- });
10281
+ }).catch((error) => this.handleSigningError(error));
10224
10282
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed successfully", {
10225
10283
  walletId: this.walletId,
10226
10284
  networkId: params.networkId,
@@ -10240,7 +10298,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10240
10298
  const parsedTransaction = await parseToKmsTransaction(params.transaction, params.networkId);
10241
10299
  const session = await this.storage.getSession();
10242
10300
  const derivationIndex = session?.accountDerivationIndex ?? 0;
10243
- this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10301
+ this.logger.debug("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
10244
10302
  walletId: this.walletId,
10245
10303
  transaction: parsedTransaction,
10246
10304
  derivationIndex
@@ -10253,21 +10311,14 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10253
10311
  if (!account) {
10254
10312
  throw new Error(`No address found for network ${params.networkId}`);
10255
10313
  }
10256
- let rawResponse;
10257
- try {
10258
- rawResponse = await this.client.signAndSendTransaction({
10259
- walletId: this.walletId,
10260
- transaction: transactionPayload,
10261
- networkId: params.networkId,
10262
- derivationIndex,
10263
- account
10264
- });
10265
- } catch (error) {
10266
- if (error instanceof SpendingLimitError) {
10267
- this.emit("spending_limit_reached", { error });
10268
- }
10269
- throw error;
10270
- }
10314
+ const rawResponse = await this.client.signAndSendTransaction({
10315
+ walletId: this.walletId,
10316
+ transaction: transactionPayload,
10317
+ networkId: params.networkId,
10318
+ derivationIndex,
10319
+ account,
10320
+ presignTransaction: params.presignTransaction
10321
+ }).catch((error) => this.handleSigningError(error));
10271
10322
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
10272
10323
  walletId: this.walletId,
10273
10324
  networkId: params.networkId,
@@ -10312,7 +10363,8 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10312
10363
  organizationId,
10313
10364
  headers: {
10314
10365
  ...this.platform.analyticsHeaders || {}
10315
- }
10366
+ },
10367
+ logger: noopLogger
10316
10368
  },
10317
10369
  this.stamper
10318
10370
  );
@@ -10391,7 +10443,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10391
10443
  lastRenewalAttempt: void 0,
10392
10444
  authUserId: authResult.authUserId
10393
10445
  };
10394
- this.logger.log("EMBEDDED_PROVIDER", "Saving Phantom session");
10446
+ this.logger.debug("EMBEDDED_PROVIDER", "Saving Phantom session");
10395
10447
  await this.storage.saveSession(session);
10396
10448
  return session;
10397
10449
  }
@@ -10426,7 +10478,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10426
10478
  authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,
10427
10479
  lastRenewalAttempt: void 0
10428
10480
  };
10429
- this.logger.log("EMBEDDED_PROVIDER", "Saving temporary session before redirect", {
10481
+ this.logger.debug("EMBEDDED_PROVIDER", "Saving temporary session before redirect", {
10430
10482
  sessionId: tempSession.sessionId,
10431
10483
  tempWalletId: tempSession.walletId
10432
10484
  });
@@ -10451,8 +10503,9 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10451
10503
  // OAuth session management - defaults to allowing refresh unless user explicitly logged out
10452
10504
  clearPreviousSession: shouldClearPreviousSession,
10453
10505
  // true only after logout
10454
- allowRefresh: !shouldClearPreviousSession
10506
+ allowRefresh: !shouldClearPreviousSession,
10455
10507
  // false only after logout
10508
+ algorithm: this.stamper.algorithm
10456
10509
  });
10457
10510
  if (authResult && "walletId" in authResult) {
10458
10511
  this.logger.info("EMBEDDED_PROVIDER", "Authentication completed after redirect", {
@@ -10465,20 +10518,21 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10465
10518
  tempSession.authProvider = authResult.provider || tempSession.authProvider;
10466
10519
  tempSession.accountDerivationIndex = authResult.accountDerivationIndex;
10467
10520
  tempSession.authUserId = authResult.authUserId;
10521
+ tempSession.bearerToken = authResult.bearerToken;
10468
10522
  tempSession.status = "completed";
10469
10523
  tempSession.lastUsed = Date.now();
10470
10524
  if (authResult.expiresInMs > 0) {
10471
10525
  const now2 = Date.now();
10472
10526
  tempSession.authenticatorCreatedAt = now2;
10473
10527
  tempSession.authenticatorExpiresAt = now2 + authResult.expiresInMs;
10474
- this.logger.log("EMBEDDED_PROVIDER", "Updated authenticator expiration from immediate auth response", {
10528
+ this.logger.debug("EMBEDDED_PROVIDER", "Updated authenticator expiration from immediate auth response", {
10475
10529
  expiresInMs: authResult.expiresInMs,
10476
10530
  expiresAt: new Date(tempSession.authenticatorExpiresAt).toISOString()
10477
10531
  });
10478
10532
  }
10479
10533
  await this.storage.saveSession(tempSession);
10480
10534
  await this.storage.setShouldClearPreviousSession(false);
10481
- this.logger.log("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10535
+ this.logger.debug("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10482
10536
  return tempSession;
10483
10537
  }
10484
10538
  this.logger.info("EMBEDDED_PROVIDER", "Redirect authentication initiated, waiting for redirect completion");
@@ -10494,20 +10548,21 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10494
10548
  session.organizationId = authResult.organizationId;
10495
10549
  session.accountDerivationIndex = authResult.accountDerivationIndex;
10496
10550
  session.authUserId = authResult.authUserId;
10551
+ session.bearerToken = authResult.bearerToken;
10497
10552
  session.status = "completed";
10498
10553
  session.lastUsed = Date.now();
10499
10554
  if (authResult.expiresInMs > 0) {
10500
10555
  const now = Date.now();
10501
10556
  session.authenticatorCreatedAt = now;
10502
10557
  session.authenticatorExpiresAt = now + authResult.expiresInMs;
10503
- this.logger.log("EMBEDDED_PROVIDER", "Updated authenticator expiration from auth response", {
10558
+ this.logger.debug("EMBEDDED_PROVIDER", "Updated authenticator expiration from auth response", {
10504
10559
  expiresInMs: authResult.expiresInMs,
10505
10560
  expiresAt: new Date(session.authenticatorExpiresAt).toISOString()
10506
10561
  });
10507
10562
  }
10508
10563
  await this.storage.saveSession(session);
10509
10564
  await this.storage.setShouldClearPreviousSession(false);
10510
- this.logger.log("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10565
+ this.logger.debug("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
10511
10566
  await this.initializeClientFromSession(session);
10512
10567
  await this.ensureValidAuthenticator();
10513
10568
  return {
@@ -10534,7 +10589,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10534
10589
  throw new Error("Invalid session - missing authenticator timing");
10535
10590
  }
10536
10591
  const timeUntilExpiry = session.authenticatorExpiresAt - now;
10537
- this.logger.log("EMBEDDED_PROVIDER", "Checking authenticator expiration", {
10592
+ this.logger.debug("EMBEDDED_PROVIDER", "Checking authenticator expiration", {
10538
10593
  expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
10539
10594
  timeUntilExpiry
10540
10595
  });
@@ -10549,7 +10604,7 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10549
10604
  * This is the final step that sets up the provider's client state and retrieves available addresses.
10550
10605
  */
10551
10606
  async initializeClientFromSession(session) {
10552
- this.logger.log("EMBEDDED_PROVIDER", "Initializing PhantomClient from session", {
10607
+ this.logger.debug("EMBEDDED_PROVIDER", "Initializing PhantomClient from session", {
10553
10608
  organizationId: session.organizationId,
10554
10609
  walletId: session.walletId,
10555
10610
  appId: session.appId
@@ -10563,7 +10618,8 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10563
10618
  organizationId: session.organizationId,
10564
10619
  headers: {
10565
10620
  ...this.platform.analyticsHeaders || {},
10566
- ...session.authUserId ? { "x-auth-user-id": session.authUserId } : {}
10621
+ ...session.authUserId ? { "x-auth-user-id": session.authUserId } : {},
10622
+ ...session.bearerToken ? { Authorization: session.bearerToken } : {}
10567
10623
  }
10568
10624
  },
10569
10625
  this.stamper
@@ -10574,14 +10630,23 @@ var EmbeddedProvider$1 = class EmbeddedProvider {
10574
10630
  };
10575
10631
 
10576
10632
  // src/index.ts
10633
+ var WEB_CRYPTO_ALGORITHM_CONFIGS = {
10634
+ [DEFAULT_AUTHENTICATOR_ALGORITHM]: {
10635
+ generateParams: { name: "Ed25519" },
10636
+ signParams: { name: "Ed25519" }
10637
+ },
10638
+ [Algorithm.secp256r1]: {
10639
+ generateParams: { name: "ECDSA", namedCurve: "P-256" },
10640
+ signParams: { name: "ECDSA", hash: "SHA-256" }
10641
+ }
10642
+ };
10577
10643
  var IndexedDbStamper = class {
10578
10644
  // Optional for PKI, required for OIDC
10579
10645
  constructor(config = {}) {
10580
10646
  this.db = null;
10581
10647
  this.activeKeyPairRecord = null;
10582
10648
  this.pendingKeyPairRecord = null;
10583
- this.algorithm = Algorithm.ed25519;
10584
- // Use Ed25519 for maximum security and performance
10649
+ this.algorithm = DEFAULT_AUTHENTICATOR_ALGORITHM;
10585
10650
  // The type of stamper, can be changed at any time
10586
10651
  this.type = "PKI";
10587
10652
  if (typeof window === "undefined" || !window.indexedDB) {
@@ -10595,17 +10660,34 @@ var IndexedDbStamper = class {
10595
10660
  this.salt = config.salt;
10596
10661
  }
10597
10662
  /**
10598
- * Initialize the stamper by opening IndexedDB and retrieving or generating keys
10663
+ * Initialize the stamper by opening IndexedDB and retrieving or generating keys.
10664
+ * Automatically selects the best supported algorithm.
10599
10665
  */
10600
10666
  async init() {
10601
10667
  await this.openDB();
10602
10668
  this.activeKeyPairRecord = await this.loadActiveKeyPairRecord();
10603
- if (!this.activeKeyPairRecord) {
10669
+ if (this.activeKeyPairRecord) {
10670
+ this.algorithm = this.activeKeyPairRecord.keyPair.privateKey.algorithm.name === "Ed25519" ? Algorithm.ed25519 : Algorithm.secp256r1;
10671
+ } else {
10672
+ this.algorithm = await this.getSupportedAlgorithm();
10604
10673
  this.activeKeyPairRecord = await this.generateAndStoreNewKeyPair("active");
10605
10674
  }
10606
10675
  this.pendingKeyPairRecord = await this.loadPendingKeyPairRecord();
10607
10676
  return this.activeKeyPairRecord.keyInfo;
10608
10677
  }
10678
+ async getSupportedAlgorithm() {
10679
+ for (const [algorithm, params] of Object.entries(WEB_CRYPTO_ALGORITHM_CONFIGS)) {
10680
+ try {
10681
+ await crypto.subtle.generateKey(params.generateParams, false, ["sign", "verify"]);
10682
+ return algorithm;
10683
+ } catch {
10684
+ continue;
10685
+ }
10686
+ }
10687
+ throw new Error(
10688
+ "Your browser does not support the encryption needed for secure authentication. Please use a different browser or upgrade to a supported browser."
10689
+ );
10690
+ }
10609
10691
  /**
10610
10692
  * Get the public key information
10611
10693
  */
@@ -10633,10 +10715,7 @@ var IndexedDbStamper = class {
10633
10715
  }
10634
10716
  const dataBytes = new Uint8Array(data);
10635
10717
  const signature = await crypto.subtle.sign(
10636
- {
10637
- name: this.algorithm,
10638
- hash: "SHA-256"
10639
- },
10718
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].signParams,
10640
10719
  this.activeKeyPairRecord.keyPair.privateKey,
10641
10720
  dataBytes
10642
10721
  );
@@ -10646,14 +10725,14 @@ var IndexedDbStamper = class {
10646
10725
  const salt = params.type === "OIDC" ? params.salt : this.salt;
10647
10726
  const stampData = stampType === "PKI" ? {
10648
10727
  // Decode base58 public key to bytes, then encode as base64url (consistent with ApiKeyStamper)
10649
- publicKey: base64urlEncode(base58.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10728
+ publicKey: base64urlEncode(bs582.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10650
10729
  signature: signatureBase64url,
10651
10730
  kind: "PKI",
10652
10731
  algorithm: this.algorithm
10653
10732
  } : {
10654
10733
  kind: "OIDC",
10655
10734
  idToken,
10656
- publicKey: base64urlEncode(base58.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10735
+ publicKey: base64urlEncode(bs582.decode(this.activeKeyPairRecord.keyInfo.publicKey)),
10657
10736
  salt,
10658
10737
  algorithm: this.algorithm,
10659
10738
  signature: signatureBase64url
@@ -10748,15 +10827,13 @@ var IndexedDbStamper = class {
10748
10827
  }
10749
10828
  async generateAndStoreNewKeyPair(type) {
10750
10829
  const keyPair = await crypto.subtle.generateKey(
10751
- {
10752
- name: "Ed25519"
10753
- },
10830
+ WEB_CRYPTO_ALGORITHM_CONFIGS[this.algorithm].generateParams,
10754
10831
  false,
10755
10832
  // non-extractable - private key can never be exported
10756
10833
  ["sign", "verify"]
10757
10834
  );
10758
10835
  const rawPublicKeyBuffer = await crypto.subtle.exportKey("raw", keyPair.publicKey);
10759
- const publicKeyBase58 = base58.encode(new Uint8Array(rawPublicKeyBuffer));
10836
+ const publicKeyBase58 = bs582.encode(new Uint8Array(rawPublicKeyBuffer));
10760
10837
  const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKeyBuffer);
10761
10838
  const keyId = base64urlEncode(new Uint8Array(keyIdBuffer)).substring(0, 16);
10762
10839
  const now = Date.now();
@@ -10826,15 +10903,301 @@ var IndexedDbStamper = class {
10826
10903
  }
10827
10904
  };
10828
10905
 
10829
- // src/types.ts
10830
-
10831
- // src/debug.ts
10832
- var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
10833
- DebugLevel2[DebugLevel2["ERROR"] = 0] = "ERROR";
10834
- DebugLevel2[DebugLevel2["WARN"] = 1] = "WARN";
10835
- DebugLevel2[DebugLevel2["INFO"] = 2] = "INFO";
10836
- DebugLevel2[DebugLevel2["DEBUG"] = 3] = "DEBUG";
10837
- return DebugLevel2;
10906
+ // src/index.ts
10907
+ var AUTH2_JAR_ALGORITHM = "ES256";
10908
+ var AUTH2_JAR_TYP = "oauth-authz-req+jwt";
10909
+ var textEncoder = new TextEncoder();
10910
+ async function createAuth2RequestJar(input) {
10911
+ const publicJwk = await globalThis.crypto.subtle.exportKey("jwk", input.keyPair.publicKey);
10912
+ if (!_isValidPublicJwk(publicJwk)) {
10913
+ throw new Error("Unable to export a valid P-256 public JWK for JAR header.");
10914
+ }
10915
+ const header = {
10916
+ alg: AUTH2_JAR_ALGORITHM,
10917
+ typ: AUTH2_JAR_TYP,
10918
+ jwk: {
10919
+ kty: "EC",
10920
+ crv: "P-256",
10921
+ x: publicJwk.x,
10922
+ y: publicJwk.y
10923
+ }
10924
+ };
10925
+ const encodedHeader = base64urlEncode(textEncoder.encode(JSON.stringify(header)));
10926
+ const encodedPayload = base64urlEncode(textEncoder.encode(JSON.stringify(input.payload)));
10927
+ const signingInput = `${encodedHeader}.${encodedPayload}`;
10928
+ const signature = await globalThis.crypto.subtle.sign(
10929
+ { name: "ECDSA", hash: "SHA-256" },
10930
+ input.keyPair.privateKey,
10931
+ textEncoder.encode(signingInput)
10932
+ );
10933
+ return `${signingInput}.${base64urlEncode(new Uint8Array(signature))}`;
10934
+ }
10935
+ function _isValidPublicJwk(jwk) {
10936
+ return jwk.kty === "EC" && jwk.crv === "P-256" && typeof jwk.x === "string" && typeof jwk.y === "string";
10937
+ }
10938
+ var DEFAULT_KMS_API_VERSION = "2025-11-24";
10939
+ var Auth2KmsRpcClient = class {
10940
+ constructor(stamper, options) {
10941
+ this.stamper = stamper;
10942
+ const axiosInstance = axios.create();
10943
+ axiosInstance.interceptors.request.use(async (config) => {
10944
+ config.headers = config.headers || {};
10945
+ config.headers["x-app-id"] = options.appId;
10946
+ config.headers["x-api-version"] = DEFAULT_KMS_API_VERSION;
10947
+ const tokens = await this.stamper.getTokens();
10948
+ if (tokens) {
10949
+ config.headers["authorization"] = tokens.bearerToken;
10950
+ }
10951
+ const requestBody = typeof config.data === "string" ? config.data : config.data === void 0 ? "" : JSON.stringify(config.data);
10952
+ const stamp = await this.stamper.stamp({ data: bufferExports.Buffer.from(requestBody, "utf-8") });
10953
+ config.headers["x-phantom-stamp"] = stamp;
10954
+ return config;
10955
+ });
10956
+ const configuration = new Configuration({ basePath: options.apiBaseUrl });
10957
+ this.kmsApi = new KMSRPCApi(configuration, options.apiBaseUrl, axiosInstance);
10958
+ }
10959
+ async postKmsRpc(request, bearerToken, authUserId) {
10960
+ const headers = { authorization: bearerToken };
10961
+ if (authUserId) {
10962
+ headers["x-auth-user-id"] = authUserId;
10963
+ }
10964
+ const response = await this.kmsApi.postKmsRpc(request, { headers });
10965
+ const rpcBody = response.data;
10966
+ if (rpcBody?.error) {
10967
+ throw new Error(`KMS RPC error: ${JSON.stringify(rpcBody.error)}`);
10968
+ }
10969
+ return response.data;
10970
+ }
10971
+ extractOrganizationId(body) {
10972
+ const result = body?.result;
10973
+ return extractStringFromPath(result, "organizationId", "organization_id");
10974
+ }
10975
+ async discoverOrganizationAndWalletId(bearerToken, authUserId) {
10976
+ const organizationId = await this.discoverOrganizationId(bearerToken, authUserId);
10977
+ if (!organizationId) {
10978
+ throw new Error("Unable to resolve organizationId. The Auth2 KMS did not return one.");
10979
+ }
10980
+ const walletId = await this.discoverWalletId(bearerToken, organizationId, authUserId);
10981
+ if (!walletId) {
10982
+ throw new Error("Unable to resolve walletId. The Auth2 KMS did not return or create one.");
10983
+ }
10984
+ return {
10985
+ organizationId,
10986
+ walletId
10987
+ };
10988
+ }
10989
+ async discoverOrganizationId(bearerToken, authUserId) {
10990
+ const keyInfo = this.stamper.getKeyInfo();
10991
+ if (!keyInfo) {
10992
+ throw new Error("Stamper not initialized");
10993
+ }
10994
+ const publicKey = base64urlEncode(bs582.decode(keyInfo.publicKey));
10995
+ const created = await this.postKmsRpc(
10996
+ {
10997
+ method: GetOrCreatePhantomOrganizationMethodEnum.getOrCreatePhantomOrganization,
10998
+ params: { publicKey },
10999
+ timestampMs: Date.now()
11000
+ },
11001
+ bearerToken,
11002
+ authUserId
11003
+ );
11004
+ return this.extractOrganizationId(created);
11005
+ }
11006
+ async discoverWalletId(bearerToken, organizationId, authUserId) {
11007
+ const listResponse = await this.postKmsRpc(
11008
+ {
11009
+ method: GetOrganizationWalletsMethodEnum.getOrganizationWallets,
11010
+ params: { organizationId, limit: 20, offset: 0 },
11011
+ timestampMs: Date.now()
11012
+ },
11013
+ bearerToken,
11014
+ authUserId
11015
+ );
11016
+ const result = listResponse?.result;
11017
+ const wallets = result?.wallets;
11018
+ if (Array.isArray(wallets) && wallets.length > 0) {
11019
+ return extractStringFromPath(wallets[0], "walletId", "wallet_id");
11020
+ }
11021
+ const createResponse = await this.postKmsRpc(
11022
+ {
11023
+ method: CreateWalletMethodEnum.createWallet,
11024
+ params: {
11025
+ walletName: `Auth2 SDK Wallet ${Date.now()}`,
11026
+ organizationId,
11027
+ accounts: [
11028
+ { curve: "Ed25519", derivationPath: "m/44'/501'/0'/0'", addressFormat: "Solana" },
11029
+ { curve: "Secp256k1", derivationPath: "m/44'/60'/0'/0/0", addressFormat: "Ethereum" },
11030
+ { curve: "Secp256k1", derivationPath: "m/84'/0'/0'/0", addressFormat: "BitcoinSegwit" },
11031
+ { curve: "Ed25519", derivationPath: "m/44'/784'/0'/0'/0'", addressFormat: "Sui" }
11032
+ ]
11033
+ },
11034
+ timestampMs: Date.now()
11035
+ },
11036
+ bearerToken,
11037
+ authUserId
11038
+ );
11039
+ const createResult = createResponse?.result;
11040
+ return extractStringFromPath(createResult, "walletId", "wallet_id");
11041
+ }
11042
+ };
11043
+ function extractStringFromPath(obj, ...keys) {
11044
+ if (!obj || typeof obj !== "object") {
11045
+ return null;
11046
+ }
11047
+ for (const key of keys) {
11048
+ const val = obj[key];
11049
+ if (typeof val === "string" && val.trim().length > 0) {
11050
+ return val.trim();
11051
+ }
11052
+ }
11053
+ return null;
11054
+ }
11055
+
11056
+ // src/index.ts
11057
+ var DEFAULT_SCOPE = "openid offline_access";
11058
+ function createCodeVerifier() {
11059
+ const bytes = new Uint8Array(64);
11060
+ crypto.getRandomValues(bytes);
11061
+ return base64urlEncode(bytes).slice(0, 96);
11062
+ }
11063
+ async function createConnectStartUrl({
11064
+ keyPair,
11065
+ connectLoginUrl,
11066
+ clientId,
11067
+ redirectUri,
11068
+ sessionId,
11069
+ provider,
11070
+ codeVerifier,
11071
+ salt
11072
+ }) {
11073
+ const nonce = await _deriveNonce(keyPair, salt);
11074
+ const codeChallenge = await _createCodeChallenge(codeVerifier);
11075
+ const nowSeconds = Math.floor(Date.now() / 1e3);
11076
+ const jarPayload = {
11077
+ aud: connectLoginUrl,
11078
+ iat: nowSeconds,
11079
+ exp: nowSeconds + 5 * 60,
11080
+ // 5 minutes
11081
+ client_id: clientId,
11082
+ redirect_uri: redirectUri,
11083
+ scope: DEFAULT_SCOPE,
11084
+ nonce,
11085
+ code_challenge: codeChallenge,
11086
+ code_challenge_method: "S256",
11087
+ ...provider && provider !== "phantom" && provider !== "device" && {
11088
+ login_hint: `${provider}:auth2`
11089
+ },
11090
+ // Use session_id as the OAuth state so it comes back in the callback URL
11091
+ // and can be validated without an extra sessionStorage entry.
11092
+ state: sessionId
11093
+ };
11094
+ const jar = await createAuth2RequestJar({
11095
+ payload: jarPayload,
11096
+ keyPair
11097
+ });
11098
+ const url = new URL(connectLoginUrl);
11099
+ url.hash = `jar=${jar}`;
11100
+ return url.toString();
11101
+ }
11102
+ async function _createCodeChallenge(codeVerifier) {
11103
+ return base64urlEncode(await sha256$2(new TextEncoder().encode(codeVerifier)));
11104
+ }
11105
+ async function _deriveNonce(keyPair, salt) {
11106
+ const publicKey = await crypto.subtle.exportKey("raw", keyPair.publicKey);
11107
+ const rawPublicKey = new Uint8Array(publicKey);
11108
+ const saltBytes = new TextEncoder().encode(salt);
11109
+ const combined = new Uint8Array(rawPublicKey.length + saltBytes.length);
11110
+ combined.set(rawPublicKey);
11111
+ combined.set(saltBytes, rawPublicKey.length);
11112
+ return base64urlEncode(await sha256$2(combined));
11113
+ }
11114
+ async function exchangeAuthCode(options) {
11115
+ return _postTokenRequest(
11116
+ options.authApiBaseUrl,
11117
+ new URLSearchParams({
11118
+ grant_type: "authorization_code",
11119
+ client_id: options.clientId,
11120
+ redirect_uri: options.redirectUri,
11121
+ code: options.code,
11122
+ code_verifier: options.codeVerifier
11123
+ })
11124
+ );
11125
+ }
11126
+ async function refreshToken(options) {
11127
+ const result = await _postTokenRequest(
11128
+ options.authApiBaseUrl,
11129
+ new URLSearchParams({
11130
+ grant_type: "refresh_token",
11131
+ client_id: options.clientId,
11132
+ redirect_uri: options.redirectUri,
11133
+ refresh_token: options.refreshToken
11134
+ })
11135
+ );
11136
+ if (!result.refreshToken) {
11137
+ throw new Error("Auth2 refresh token request did not return a refresh_token.");
11138
+ }
11139
+ return result;
11140
+ }
11141
+ async function _postTokenRequest(authApiBaseUrl, body) {
11142
+ const tokenEndpoint = new URL("/oauth2/token", authApiBaseUrl).toString();
11143
+ const tokenResponse = await fetch(tokenEndpoint, {
11144
+ method: "POST",
11145
+ headers: { "content-type": "application/x-www-form-urlencoded" },
11146
+ body: body.toString()
11147
+ });
11148
+ if (!tokenResponse.ok) {
11149
+ const text = await tokenResponse.text();
11150
+ throw new Error(`Auth2 token request failed (${tokenResponse.status} ${tokenResponse.statusText}): ${text}`);
11151
+ }
11152
+ const tokens = await tokenResponse.json();
11153
+ const accessToken = tokens.access_token;
11154
+ if (!accessToken) {
11155
+ throw new Error("Auth2 token request did not return an access_token.");
11156
+ }
11157
+ const idToken = tokens.id_token;
11158
+ if (!idToken) {
11159
+ throw new Error("Auth2 token request did not return an id_token.");
11160
+ }
11161
+ const bearerToken = `${tokens?.token_type ?? "Bearer"} ${accessToken}`;
11162
+ const authUserId = _parseJwtClaim(accessToken, ["sub"]) ?? void 0;
11163
+ const expiresInMs = tokens.expires_in != null ? tokens.expires_in * 1e3 : 0;
11164
+ return {
11165
+ idToken,
11166
+ bearerToken,
11167
+ authUserId,
11168
+ expiresInMs,
11169
+ refreshToken: tokens.refresh_token
11170
+ };
11171
+ }
11172
+ function _parseJwtClaim(token, keys) {
11173
+ try {
11174
+ const parts = token.split(".");
11175
+ if (parts.length < 2 || !parts[1]) {
11176
+ return null;
11177
+ }
11178
+ const padded = parts[1].replace(/-/g, "+").replace(/_/g, "/");
11179
+ const payload = JSON.parse(atob(padded));
11180
+ for (const key of keys) {
11181
+ const val = payload[key];
11182
+ if (typeof val === "string" && val.length > 0) {
11183
+ return val;
11184
+ }
11185
+ }
11186
+ return null;
11187
+ } catch {
11188
+ return null;
11189
+ }
11190
+ }
11191
+
11192
+ // src/types.ts
11193
+
11194
+ // src/debug.ts
11195
+ var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
11196
+ DebugLevel2[DebugLevel2["ERROR"] = 0] = "ERROR";
11197
+ DebugLevel2[DebugLevel2["WARN"] = 1] = "WARN";
11198
+ DebugLevel2[DebugLevel2["INFO"] = 2] = "INFO";
11199
+ DebugLevel2[DebugLevel2["DEBUG"] = 3] = "DEBUG";
11200
+ return DebugLevel2;
10838
11201
  })(DebugLevel || {});
10839
11202
  var Debug = class {
10840
11203
  constructor() {
@@ -10901,6 +11264,17 @@ var DebugCategory = {
10901
11264
  STORAGE: "Storage",
10902
11265
  SESSION: "Session"
10903
11266
  };
11267
+ var CUSTOM_WALLET_CONFIGS = [
11268
+ {
11269
+ id: "coinbase-wallet",
11270
+ name: "Coinbase Wallet",
11271
+ icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI4IDU2YzE1LjQ2NCAwIDI4LTEyLjUzNiAyOC0yOFM0My40NjQgMCAyOCAwIDAgMTIuNTM2IDAgMjhzMTIuNTM2IDI4IDI4IDI4WiIgZmlsbD0iIzFCNTNFNCIvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNyAyOGMwIDExLjU5OCA5LjQwMiAyMSAyMSAyMXMyMS05LjQwMiAyMS0yMVMzOS41OTggNyAyOCA3IDcgMTYuNDAyIDcgMjhabTE3LjIzNC02Ljc2NmEzIDMgMCAwIDAtMyAzdjcuNTMzYTMgMyAwIDAgMCAzIDNoNy41MzNhMyAzIDAgMCAwIDMtM3YtNy41MzNhMyAzIDAgMCAwLTMtM2gtNy41MzNaIiBmaWxsPSIjZmZmIi8+PC9zdmc+",
11272
+ windowProperty: "coinbaseSolana",
11273
+ addressTypes: [DerivationInfoAddressFormatEnum.solana]
11274
+ }
11275
+ ];
11276
+
11277
+ // src/wallets/discovery.ts
10904
11278
  function generateWalletIdFromEIP6963(info) {
10905
11279
  if (info.rdns) {
10906
11280
  return info.rdns.split(".").reverse().join("-");
@@ -11164,6 +11538,51 @@ async function discoverSolanaWallets() {
11164
11538
  walletNames: wallets.map((w) => w.name)
11165
11539
  };
11166
11540
  debug.log(DebugCategory.BROWSER_SDK, "Wallet Standard Solana discovery completed", finalLogData);
11541
+ const customWallets = discoverCustomSolanaWallets();
11542
+ wallets.push(...customWallets);
11543
+ return wallets;
11544
+ }
11545
+ function discoverCustomSolanaWallets() {
11546
+ const wallets = [];
11547
+ if (typeof window === "undefined") {
11548
+ debug.log(DebugCategory.BROWSER_SDK, "Custom wallet discovery skipped (not in browser environment)");
11549
+ return wallets;
11550
+ }
11551
+ debug.log(DebugCategory.BROWSER_SDK, "Starting custom Solana wallet discovery", {
11552
+ configCount: CUSTOM_WALLET_CONFIGS.length
11553
+ });
11554
+ for (const config of CUSTOM_WALLET_CONFIGS) {
11555
+ if (!config.addressTypes.includes(DerivationInfoAddressFormatEnum.solana)) {
11556
+ continue;
11557
+ }
11558
+ const provider = window[config.windowProperty];
11559
+ if (!provider) {
11560
+ debug.log(DebugCategory.BROWSER_SDK, "Custom wallet not found", {
11561
+ walletId: config.id,
11562
+ windowProperty: config.windowProperty
11563
+ });
11564
+ continue;
11565
+ }
11566
+ debug.log(DebugCategory.BROWSER_SDK, "Discovered custom Solana wallet", {
11567
+ walletId: config.id,
11568
+ walletName: config.name,
11569
+ windowProperty: config.windowProperty
11570
+ });
11571
+ wallets.push({
11572
+ id: config.id,
11573
+ name: config.name,
11574
+ icon: config.icon,
11575
+ addressTypes: config.addressTypes,
11576
+ providers: {
11577
+ solana: provider
11578
+ },
11579
+ discovery: "custom"
11580
+ });
11581
+ }
11582
+ debug.log(DebugCategory.BROWSER_SDK, "Custom Solana wallet discovery completed", {
11583
+ discoveredCount: wallets.length,
11584
+ walletIds: wallets.map((w) => w.id)
11585
+ });
11167
11586
  return wallets;
11168
11587
  }
11169
11588
  function discoverPhantomWallet(addressTypes) {
@@ -11185,8 +11604,7 @@ function discoverPhantomWallet(addressTypes) {
11185
11604
  return {
11186
11605
  id: "phantom",
11187
11606
  name: "Phantom",
11188
- icon: void 0,
11189
- // Icon will be rendered from icons package in UI components
11607
+ icon: PHANTOM_ICON,
11190
11608
  addressTypes,
11191
11609
  providers: {
11192
11610
  solana: addressTypes.includes(DerivationInfoAddressFormatEnum.solana) ? phantomInstance.solana : void 0,
@@ -11258,61 +11676,55 @@ var InjectedWalletSolanaChain = class {
11258
11676
  constructor(provider, walletId, walletName) {
11259
11677
  // Expose eventEmitter for testing - allows tests to trigger events directly
11260
11678
  this.eventEmitter = new EventEmitter3();
11261
- this._connected = false;
11262
11679
  this._publicKey = null;
11263
11680
  this.provider = provider;
11264
11681
  this.walletId = walletId;
11265
11682
  this.walletName = walletName;
11266
11683
  this.setupEventListeners();
11267
11684
  }
11268
- get connected() {
11269
- return this._connected;
11270
- }
11271
11685
  get publicKey() {
11272
11686
  return this._publicKey;
11273
11687
  }
11688
+ get isConnected() {
11689
+ return this.provider.isConnected || !!this._publicKey;
11690
+ }
11274
11691
  async connect(options) {
11275
- debug.log(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect", {
11276
- walletId: this.walletId,
11277
- walletName: this.walletName,
11278
- onlyIfTrusted: options?.onlyIfTrusted
11279
- });
11280
11692
  try {
11281
- const result = await this.provider.connect(options);
11282
- if (typeof result === "string") {
11283
- this._connected = true;
11284
- this._publicKey = result;
11285
- debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11693
+ await this.provider.connect(options);
11694
+ const isConnected = this.provider.isConnected;
11695
+ if (!isConnected || this.provider.publicKey === null) {
11696
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Provider not connected after connect() call", {
11286
11697
  walletId: this.walletId,
11287
11698
  walletName: this.walletName,
11288
- publicKey: result
11699
+ providerConnected: isConnected,
11700
+ providerPublicKey: this.provider.publicKey
11289
11701
  });
11290
- return { publicKey: result };
11702
+ throw new Error("Provider not connected after connect() call");
11291
11703
  }
11292
- if (typeof result === "object" && result !== null && "publicKey" in result) {
11293
- this._connected = true;
11294
- this._publicKey = result.publicKey;
11295
- debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11704
+ let publicKey;
11705
+ const providerPublicKey = this.provider.publicKey;
11706
+ if (typeof providerPublicKey === "string") {
11707
+ publicKey = providerPublicKey;
11708
+ } else if (providerPublicKey !== null && providerPublicKey !== void 0 && typeof providerPublicKey.toString === "function") {
11709
+ publicKey = providerPublicKey.toString();
11710
+ } else {
11711
+ debug.error(DebugCategory.INJECTED_PROVIDER, "Invalid publicKey format in provider state", {
11296
11712
  walletId: this.walletId,
11297
11713
  walletName: this.walletName,
11298
- publicKey: result.publicKey
11714
+ publicKeyType: typeof providerPublicKey
11299
11715
  });
11300
- return result;
11716
+ throw new Error("Invalid publicKey format in provider state");
11301
11717
  }
11302
- if (Array.isArray(result) && result.length > 0) {
11303
- const firstAccount = result[0];
11304
- if (typeof firstAccount === "object" && firstAccount !== null && "address" in firstAccount) {
11305
- this._connected = true;
11306
- this._publicKey = firstAccount.address;
11307
- debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11308
- walletId: this.walletId,
11309
- walletName: this.walletName,
11310
- publicKey: firstAccount.address
11311
- });
11312
- return { publicKey: firstAccount.address };
11313
- }
11718
+ if (!publicKey || publicKey.length === 0) {
11719
+ throw new Error("Empty publicKey from provider");
11314
11720
  }
11315
- throw new Error("Unexpected connect result format");
11721
+ this._publicKey = publicKey;
11722
+ debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connected", {
11723
+ walletId: this.walletId,
11724
+ walletName: this.walletName,
11725
+ publicKey
11726
+ });
11727
+ return { publicKey };
11316
11728
  } catch (error) {
11317
11729
  debug.error(DebugCategory.INJECTED_PROVIDER, "External wallet Solana connect failed", {
11318
11730
  walletId: this.walletId,
@@ -11329,7 +11741,6 @@ var InjectedWalletSolanaChain = class {
11329
11741
  });
11330
11742
  try {
11331
11743
  await this.provider.disconnect();
11332
- this._connected = false;
11333
11744
  this._publicKey = null;
11334
11745
  debug.info(DebugCategory.INJECTED_PROVIDER, "External wallet Solana disconnected", {
11335
11746
  walletId: this.walletId,
@@ -11465,28 +11876,19 @@ var InjectedWalletSolanaChain = class {
11465
11876
  switchNetwork(_network) {
11466
11877
  return Promise.resolve();
11467
11878
  }
11468
- getPublicKey() {
11469
- return Promise.resolve(this._publicKey);
11470
- }
11471
- isConnected() {
11472
- return this._connected;
11473
- }
11474
11879
  setupEventListeners() {
11475
11880
  if (typeof this.provider.on === "function") {
11476
11881
  this.provider.on("connect", (publicKey) => {
11477
- this._connected = true;
11478
11882
  this._publicKey = publicKey;
11479
11883
  this.eventEmitter.emit("connect", publicKey);
11480
11884
  });
11481
11885
  this.provider.on("disconnect", () => {
11482
- this._connected = false;
11483
11886
  this._publicKey = null;
11484
11887
  this.eventEmitter.emit("disconnect");
11485
11888
  });
11486
11889
  this.provider.on("accountChanged", (publicKey) => {
11487
- this._publicKey = publicKey;
11488
- this._connected = publicKey != null && publicKey.length > 0;
11489
- this.eventEmitter.emit("accountChanged", publicKey);
11890
+ this._publicKey = publicKey ? publicKey : null;
11891
+ this.eventEmitter.emit("accountChanged", this._publicKey);
11490
11892
  });
11491
11893
  }
11492
11894
  }
@@ -11506,12 +11908,12 @@ var WalletStandardSolanaAdapter = class {
11506
11908
  this.walletName = walletName;
11507
11909
  this.setupEventListeners();
11508
11910
  }
11509
- get connected() {
11510
- return this._publicKey !== null;
11511
- }
11512
11911
  get publicKey() {
11513
11912
  return this._publicKey;
11514
11913
  }
11914
+ get isConnected() {
11915
+ return this._publicKey !== null;
11916
+ }
11515
11917
  async connect(_options) {
11516
11918
  try {
11517
11919
  const connectFeature = this.wallet.features["standard:connect"];
@@ -11675,7 +12077,7 @@ var WalletStandardSolanaAdapter = class {
11675
12077
  throw new Error("No signature found in signAndSendTransaction result");
11676
12078
  }
11677
12079
  const signatureBytes = this.parseUint8Array(signatureOutput.signature);
11678
- const signature = base58.encode(signatureBytes);
12080
+ const signature = bs582.encode(signatureBytes);
11679
12081
  return { signature };
11680
12082
  } catch (error) {
11681
12083
  debug.error(DebugCategory.INJECTED_PROVIDER, "Wallet Standard Solana signAndSendTransaction failed", {
@@ -11723,12 +12125,6 @@ var WalletStandardSolanaAdapter = class {
11723
12125
  async switchNetwork(_network) {
11724
12126
  return Promise.resolve();
11725
12127
  }
11726
- getPublicKey() {
11727
- return Promise.resolve(this._publicKey);
11728
- }
11729
- isConnected() {
11730
- return this._publicKey !== null;
11731
- }
11732
12128
  /**
11733
12129
  * Set up event listeners for Wallet Standard events
11734
12130
  * Maps Wallet Standard "change" events to "accountChanged" events
@@ -11860,9 +12256,6 @@ var InjectedWalletEthereumChain = class {
11860
12256
  this.walletName = walletName;
11861
12257
  this.setupEventListeners();
11862
12258
  }
11863
- get connected() {
11864
- return this._connected;
11865
- }
11866
12259
  get chainId() {
11867
12260
  return this._chainId;
11868
12261
  }
@@ -11992,7 +12385,8 @@ var InjectedWalletEthereumChain = class {
11992
12385
  address
11993
12386
  });
11994
12387
  try {
11995
- const providerConnected = this.provider.isConnected?.() || this.provider.connected || false;
12388
+ const providerAny = this.provider;
12389
+ const providerConnected = (typeof providerAny.isConnected === "function" ? providerAny.isConnected() : false) || (typeof providerAny.connected === "boolean" ? providerAny.connected : false);
11996
12390
  if (!this._connected || this._accounts.length === 0 || !providerConnected) {
11997
12391
  debug.log(DebugCategory.INJECTED_PROVIDER, "Not connected, attempting to connect before signing", {
11998
12392
  walletId: this.walletId,
@@ -12306,8 +12700,7 @@ var InjectedWalletRegistry = class {
12306
12700
  const phantomWallet = {
12307
12701
  id: "phantom",
12308
12702
  name: "Phantom",
12309
- icon: "",
12310
- // Icon will be rendered from icons package in UI components
12703
+ icon: PHANTOM_ICON,
12311
12704
  addressTypes,
12312
12705
  providers: wrappedProviders,
12313
12706
  isPhantom: true,
@@ -12521,16 +12914,11 @@ var InjectedProvider = class {
12521
12914
  walletName: walletInfo.name
12522
12915
  });
12523
12916
  } catch (err) {
12524
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana, stopping", {
12917
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana, continuing with other chains", {
12525
12918
  error: err,
12526
12919
  walletId: this.selectedWalletId,
12527
12920
  walletName: walletInfo.name
12528
12921
  });
12529
- this.emit("connect_error", {
12530
- error: err instanceof Error ? err.message : "Failed to connect",
12531
- source: options?.skipEventListeners ? "auto-connect" : "manual-connect"
12532
- });
12533
- throw err;
12534
12922
  }
12535
12923
  }
12536
12924
  if (this.addressTypes.includes(DerivationInfoAddressFormatEnum.ethereum) && walletInfo.providers?.ethereum) {
@@ -12560,16 +12948,11 @@ var InjectedProvider = class {
12560
12948
  });
12561
12949
  }
12562
12950
  } catch (err) {
12563
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum, stopping", {
12951
+ debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum, continuing with other chains", {
12564
12952
  error: err,
12565
12953
  walletId: this.selectedWalletId,
12566
12954
  walletName: walletInfo.name
12567
12955
  });
12568
- this.emit("connect_error", {
12569
- error: err instanceof Error ? err.message : "Failed to connect",
12570
- source: options?.skipEventListeners ? "auto-connect" : "manual-connect"
12571
- });
12572
- throw err;
12573
12956
  }
12574
12957
  }
12575
12958
  return connectedAddresses;
@@ -12629,7 +13012,8 @@ var InjectedProvider = class {
12629
13012
  this.emit("connect", {
12630
13013
  addresses: connectedAddresses,
12631
13014
  source: "manual-connect",
12632
- authUserId
13015
+ authUserId,
13016
+ walletId
12633
13017
  });
12634
13018
  return result;
12635
13019
  }
@@ -12641,12 +13025,13 @@ var InjectedProvider = class {
12641
13025
  if (authOptions.provider !== "injected") {
12642
13026
  throw new Error(`Invalid provider for injected connection: ${authOptions.provider}. Must be "injected"`);
12643
13027
  }
13028
+ const requestedWalletId = authOptions.walletId || "phantom";
12644
13029
  this.emit("connect_start", {
12645
13030
  source: "manual-connect",
12646
- providerType: "injected"
13031
+ providerType: "injected",
13032
+ walletId: requestedWalletId
12647
13033
  });
12648
13034
  try {
12649
- const requestedWalletId = authOptions.walletId || "phantom";
12650
13035
  const walletInfo = this.validateAndSelectWallet(requestedWalletId);
12651
13036
  const connectedAddresses = await this.connectToWallet(walletInfo);
12652
13037
  return await this.finalizeConnection(connectedAddresses, "injected", this.selectedWalletId || void 0);
@@ -12766,7 +13151,8 @@ var InjectedProvider = class {
12766
13151
  this.emit("connect", {
12767
13152
  addresses: connectedAddresses,
12768
13153
  source: "auto-connect",
12769
- authUserId
13154
+ authUserId,
13155
+ walletId: this.selectedWalletId
12770
13156
  });
12771
13157
  debug.info(DebugCategory.INJECTED_PROVIDER, "Auto-connect successful", {
12772
13158
  addressCount: connectedAddresses.length,
@@ -12832,7 +13218,8 @@ var InjectedProvider = class {
12832
13218
  this.emit("connect", {
12833
13219
  addresses: newAddresses,
12834
13220
  source,
12835
- authUserId
13221
+ authUserId,
13222
+ walletId: this.selectedWalletId
12836
13223
  });
12837
13224
  };
12838
13225
  }
@@ -12866,7 +13253,8 @@ var InjectedProvider = class {
12866
13253
  this.emit("connect", {
12867
13254
  addresses: newAddresses,
12868
13255
  source: this.getAccountChangeSource(source),
12869
- authUserId
13256
+ authUserId,
13257
+ walletId: this.selectedWalletId
12870
13258
  });
12871
13259
  } else {
12872
13260
  const state = this.getWalletState(walletId);
@@ -12907,7 +13295,8 @@ var InjectedProvider = class {
12907
13295
  this.emit("connect", {
12908
13296
  addresses: newAddresses,
12909
13297
  source,
12910
- authUserId
13298
+ authUserId,
13299
+ walletId: this.selectedWalletId
12911
13300
  });
12912
13301
  }
12913
13302
  };
@@ -12941,7 +13330,8 @@ var InjectedProvider = class {
12941
13330
  this.emit("connect", {
12942
13331
  addresses: newAddresses,
12943
13332
  source: this.getAccountChangeSource(source),
12944
- authUserId
13333
+ authUserId,
13334
+ walletId: this.selectedWalletId
12945
13335
  });
12946
13336
  } else {
12947
13337
  const state = this.getWalletState(walletId);
@@ -13139,7 +13529,9 @@ var InjectedProvider = class {
13139
13529
  this.eventListenerCleanups.set(walletId, [...existingCleanups, ...cleanups]);
13140
13530
  }
13141
13531
  /**
13142
- * Unified event listener setup for all wallet types (Phantom and external)
13532
+ * Unified event listener setup for all wallet types (Phantom and external).
13533
+ * Cleans up listeners for previously selected wallets to prevent stale events
13534
+ * from causing walletId flicker during connections.
13143
13535
  */
13144
13536
  setupEventListeners(walletInfo) {
13145
13537
  const walletId = this.selectedWalletId || "phantom";
@@ -13147,6 +13539,17 @@ var InjectedProvider = class {
13147
13539
  debug.log(DebugCategory.INJECTED_PROVIDER, "Event listeners already set up for wallet", { walletId });
13148
13540
  return;
13149
13541
  }
13542
+ for (const existingWalletId of this.eventListenersSetup) {
13543
+ if (existingWalletId === walletId) {
13544
+ continue;
13545
+ }
13546
+ const cleanups = this.eventListenerCleanups.get(existingWalletId);
13547
+ if (cleanups) {
13548
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Cleaning up event listeners for wallet", { existingWalletId });
13549
+ cleanups.forEach((cleanup) => cleanup());
13550
+ }
13551
+ this.eventListenersSetup.delete(existingWalletId);
13552
+ }
13150
13553
  debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up event listeners", { walletId });
13151
13554
  if (this.addressTypes.includes(DerivationInfoAddressFormatEnum.solana) && walletInfo.providers?.solana) {
13152
13555
  this.setupSolanaEventListeners(walletInfo.providers.solana, walletId, "wallet");
@@ -13457,9 +13860,10 @@ var BrowserAuthProvider = class {
13457
13860
  // OAuth session management - defaults to allow refresh unless explicitly clearing after logout
13458
13861
  clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
13459
13862
  allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
13460
- sdk_version: "1.0.2",
13863
+ sdk_version: "1.0.7",
13461
13864
  sdk_type: "browser",
13462
- platform: detectBrowser().name
13865
+ platform: detectBrowser().name,
13866
+ algorithm: phantomOptions.algorithm || DEFAULT_AUTHENTICATOR_ALGORITHM
13463
13867
  });
13464
13868
  if (phantomOptions.provider) {
13465
13869
  debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
@@ -13487,7 +13891,7 @@ var BrowserAuthProvider = class {
13487
13891
  resolve();
13488
13892
  });
13489
13893
  }
13490
- resumeAuthFromRedirect(provider) {
13894
+ async resumeAuthFromRedirect(provider) {
13491
13895
  try {
13492
13896
  const walletId = this.urlParamsAccessor.getParam("wallet_id");
13493
13897
  const sessionId = this.urlParamsAccessor.getParam("session_id");
@@ -13562,40 +13966,361 @@ var BrowserAuthProvider = class {
13562
13966
  }
13563
13967
  );
13564
13968
  }
13565
- return {
13969
+ return Promise.resolve({
13566
13970
  walletId,
13567
13971
  organizationId,
13568
13972
  accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : 0,
13569
13973
  expiresInMs: expiresInMs ? parseInt(expiresInMs) : 0,
13570
13974
  authUserId: authUserId || void 0,
13571
13975
  provider
13572
- };
13976
+ });
13573
13977
  } catch (error) {
13574
13978
  sessionStorage.removeItem("phantom-auth-context");
13575
13979
  throw error;
13576
13980
  }
13577
13981
  }
13578
13982
  };
13579
- async function isPhantomLoginAvailable(timeoutMs = 3e3) {
13580
- const extensionInstalled = await waitForExtension(timeoutMs);
13581
- if (!extensionInstalled) {
13582
- return false;
13983
+ var Auth2AuthProvider = class {
13984
+ constructor(stamper, storage, urlParamsAccessor, auth2ProviderOptions, kmsClientOptions) {
13985
+ this.stamper = stamper;
13986
+ this.storage = storage;
13987
+ this.urlParamsAccessor = urlParamsAccessor;
13988
+ this.auth2ProviderOptions = auth2ProviderOptions;
13989
+ this.kms = new Auth2KmsRpcClient(stamper, kmsClientOptions);
13583
13990
  }
13584
- try {
13585
- if (!window.phantom?.app?.features || typeof window.phantom.app.features !== "function") {
13586
- return false;
13991
+ /** Redirect the browser. Extracted as a static method so tests can spy on it. */
13992
+ static navigate(url) {
13993
+ window.location.href = url;
13994
+ }
13995
+ /**
13996
+ * Builds the Auth2 /login/start URL and redirects the browser.
13997
+ *
13998
+ * Called by EmbeddedProvider.handleRedirectAuth() after the stamper has
13999
+ * already been initialized and a pending Session has been saved to storage.
14000
+ * We store the PKCE code_verifier into that session so it survives the page
14001
+ * redirect without ever touching sessionStorage.
14002
+ */
14003
+ async authenticate(options) {
14004
+ if (!this.stamper.getKeyInfo()) {
14005
+ await this.stamper.init();
13587
14006
  }
13588
- const response = await window.phantom.app.features();
13589
- if (!Array.isArray(response.features)) {
13590
- return false;
14007
+ const keyPair = this.stamper.getCryptoKeyPair();
14008
+ if (!keyPair) {
14009
+ throw new Error("Stamper key pair not found.");
13591
14010
  }
13592
- return response.features.includes("phantom_login");
13593
- } catch (error) {
13594
- console.error("Error checking Phantom extension features", error);
13595
- return false;
14011
+ const codeVerifier = createCodeVerifier();
14012
+ const session = await this.storage.getSession();
14013
+ if (!session) {
14014
+ throw new Error("Session not found.");
14015
+ }
14016
+ await this.storage.saveSession({ ...session, pkceCodeVerifier: codeVerifier });
14017
+ const url = await createConnectStartUrl({
14018
+ keyPair,
14019
+ connectLoginUrl: this.auth2ProviderOptions.connectLoginUrl,
14020
+ clientId: this.auth2ProviderOptions.clientId,
14021
+ redirectUri: this.auth2ProviderOptions.redirectUri,
14022
+ sessionId: options.sessionId,
14023
+ provider: options.provider,
14024
+ codeVerifier,
14025
+ // The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
14026
+ salt: ""
14027
+ });
14028
+ Auth2AuthProvider.navigate(url);
13596
14029
  }
13597
- }
13598
- async function waitForExtension(timeoutMs) {
14030
+ /**
14031
+ * Processes the Auth2 callback after the browser returns from /login/start.
14032
+ *
14033
+ * Exchanges the authorization code for tokens, discovers the organization
14034
+ * and wallet via KMS RPC, then returns a completed AuthResult.
14035
+ */
14036
+ async resumeAuthFromRedirect(provider) {
14037
+ const code = this.urlParamsAccessor.getParam("code");
14038
+ if (!code) {
14039
+ return null;
14040
+ }
14041
+ if (!this.stamper.getKeyInfo()) {
14042
+ await this.stamper.init();
14043
+ }
14044
+ const session = await this.storage.getSession();
14045
+ if (!session) {
14046
+ throw new Error("Session not found.");
14047
+ }
14048
+ const codeVerifier = session?.pkceCodeVerifier;
14049
+ if (!codeVerifier) {
14050
+ return null;
14051
+ }
14052
+ const state = this.urlParamsAccessor.getParam("state");
14053
+ if (!state || state !== session.sessionId) {
14054
+ throw new Error("Missing or invalid Auth2 state parameter \u2014 possible CSRF attack.");
14055
+ }
14056
+ const error = this.urlParamsAccessor.getParam("error");
14057
+ if (error) {
14058
+ const description = this.urlParamsAccessor.getParam("error_description");
14059
+ throw new Error(`Auth2 callback error: ${description ?? error}`);
14060
+ }
14061
+ const { idToken, bearerToken, authUserId, expiresInMs, refreshToken } = await exchangeAuthCode({
14062
+ authApiBaseUrl: this.auth2ProviderOptions.authApiBaseUrl,
14063
+ clientId: this.auth2ProviderOptions.clientId,
14064
+ redirectUri: this.auth2ProviderOptions.redirectUri,
14065
+ code,
14066
+ codeVerifier
14067
+ });
14068
+ await this.stamper.setTokens({ idToken, bearerToken, refreshToken, expiresInMs });
14069
+ await this.storage.saveSession({
14070
+ ...session,
14071
+ status: "completed",
14072
+ bearerToken,
14073
+ authUserId,
14074
+ pkceCodeVerifier: void 0
14075
+ // no longer needed after code exchange
14076
+ });
14077
+ const { organizationId, walletId } = await this.kms.discoverOrganizationAndWalletId(bearerToken, authUserId);
14078
+ return {
14079
+ walletId,
14080
+ organizationId,
14081
+ provider,
14082
+ accountDerivationIndex: 0,
14083
+ // discoverWalletId uses derivation index of 0.
14084
+ expiresInMs,
14085
+ authUserId,
14086
+ bearerToken
14087
+ };
14088
+ }
14089
+ };
14090
+ var STORE_NAME = "crypto-keys";
14091
+ var ACTIVE_KEY = "auth2-p256-signing-key";
14092
+ var Auth2Stamper = class {
14093
+ /**
14094
+ * @param dbName - IndexedDB database name (use a unique name per app to
14095
+ * avoid key collisions with other stampers, e.g. `phantom-auth2-<appId>`).
14096
+ * @param refreshConfig - When provided, the stamper will automatically refresh
14097
+ * the id_token using the refresh_token before it expires.
14098
+ */
14099
+ constructor(dbName, refreshConfig) {
14100
+ this.dbName = dbName;
14101
+ this.refreshConfig = refreshConfig;
14102
+ this.db = null;
14103
+ this._keyPair = null;
14104
+ this._keyInfo = null;
14105
+ this._idToken = null;
14106
+ this._bearerToken = null;
14107
+ this._refreshToken = null;
14108
+ this._tokenExpiresAt = null;
14109
+ this.algorithm = Algorithm.secp256r1;
14110
+ this.type = "OIDC";
14111
+ }
14112
+ async init() {
14113
+ await this.openDB();
14114
+ const stored = await this.loadRecord();
14115
+ if (stored) {
14116
+ this._keyPair = stored.keyPair;
14117
+ this._keyInfo = stored.keyInfo;
14118
+ if (stored.idToken) {
14119
+ this._idToken = stored.idToken;
14120
+ }
14121
+ if (stored.bearerToken) {
14122
+ this._bearerToken = stored.bearerToken;
14123
+ }
14124
+ if (stored.refreshToken) {
14125
+ this._refreshToken = stored.refreshToken;
14126
+ }
14127
+ if (stored.tokenExpiresAt) {
14128
+ this._tokenExpiresAt = stored.tokenExpiresAt;
14129
+ }
14130
+ return this._keyInfo;
14131
+ }
14132
+ return this.generateAndStore();
14133
+ }
14134
+ getKeyInfo() {
14135
+ return this._keyInfo;
14136
+ }
14137
+ getCryptoKeyPair() {
14138
+ return this._keyPair;
14139
+ }
14140
+ /**
14141
+ * Returns the current token state (refreshing proactively if near expiry),
14142
+ * or null if no token has been set yet.
14143
+ */
14144
+ async getTokens() {
14145
+ if (this.refreshConfig && this._refreshToken && this._tokenExpiresAt !== null && Date.now() >= this._tokenExpiresAt - TOKEN_REFRESH_BUFFER_MS) {
14146
+ const refreshed = await refreshToken({
14147
+ authApiBaseUrl: this.refreshConfig.authApiBaseUrl,
14148
+ clientId: this.refreshConfig.clientId,
14149
+ redirectUri: this.refreshConfig.redirectUri,
14150
+ refreshToken: this._refreshToken
14151
+ });
14152
+ await this.setTokens(refreshed);
14153
+ }
14154
+ if (!this._idToken || !this._bearerToken) {
14155
+ return null;
14156
+ }
14157
+ return {
14158
+ idToken: this._idToken,
14159
+ bearerToken: this._bearerToken,
14160
+ refreshToken: this._refreshToken ?? void 0
14161
+ };
14162
+ }
14163
+ /**
14164
+ * Arms the stamper with the OIDC token data for subsequent KMS stamp() calls.
14165
+ *
14166
+ * Persists the tokens to IndexedDB alongside the key pair so that
14167
+ * auto-connect can restore them on the next page load without a new login.
14168
+ *
14169
+ * @param refreshToken - When provided alongside a `refreshConfig`, enables
14170
+ * silent token refresh before the token expires.
14171
+ * @param expiresInMs - Token lifetime in milliseconds (from `expires_in * 1000`).
14172
+ * Used to compute the absolute expiry time for proactive refresh.
14173
+ */
14174
+ async setTokens({
14175
+ idToken,
14176
+ bearerToken,
14177
+ refreshToken,
14178
+ expiresInMs
14179
+ }) {
14180
+ if (!this.db) {
14181
+ await this.openDB();
14182
+ }
14183
+ this._idToken = idToken;
14184
+ this._bearerToken = bearerToken;
14185
+ this._refreshToken = refreshToken ?? null;
14186
+ this._tokenExpiresAt = expiresInMs != null ? Date.now() + expiresInMs : null;
14187
+ const existing = await this.loadRecord();
14188
+ if (existing) {
14189
+ await this.storeRecord({
14190
+ ...existing,
14191
+ idToken,
14192
+ bearerToken,
14193
+ refreshToken,
14194
+ tokenExpiresAt: this._tokenExpiresAt ?? void 0
14195
+ });
14196
+ }
14197
+ }
14198
+ async stamp(params) {
14199
+ if (!this._keyPair || !this._keyInfo || this._idToken === null) {
14200
+ throw new Error("Auth2Stamper not initialized. Call init() first.");
14201
+ }
14202
+ const signatureRaw = await crypto.subtle.sign(
14203
+ { name: "ECDSA", hash: "SHA-256" },
14204
+ this._keyPair.privateKey,
14205
+ new Uint8Array(params.data)
14206
+ );
14207
+ const rawPublicKey = bs582.decode(this._keyInfo.publicKey);
14208
+ const stampData = {
14209
+ kind: this.type,
14210
+ idToken: this._idToken,
14211
+ publicKey: base64urlEncode(rawPublicKey),
14212
+ algorithm: this.algorithm,
14213
+ // The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
14214
+ salt: "",
14215
+ signature: base64urlEncode(new Uint8Array(signatureRaw))
14216
+ };
14217
+ return base64urlEncode(new TextEncoder().encode(JSON.stringify(stampData)));
14218
+ }
14219
+ async resetKeyPair() {
14220
+ await this.clear();
14221
+ return this.generateAndStore();
14222
+ }
14223
+ async clear() {
14224
+ await this.clearStoredRecord();
14225
+ this._keyPair = null;
14226
+ this._keyInfo = null;
14227
+ this._idToken = null;
14228
+ this._bearerToken = null;
14229
+ this._refreshToken = null;
14230
+ this._tokenExpiresAt = null;
14231
+ }
14232
+ // Auth2 doesn't use key rotation; provide minimal no-op implementations.
14233
+ async rotateKeyPair() {
14234
+ return this.init();
14235
+ }
14236
+ // eslint-disable-next-line @typescript-eslint/require-await
14237
+ async commitRotation(authenticatorId) {
14238
+ if (this._keyInfo) {
14239
+ this._keyInfo.authenticatorId = authenticatorId;
14240
+ }
14241
+ }
14242
+ async rollbackRotation() {
14243
+ }
14244
+ async generateAndStore() {
14245
+ const keyPair = await crypto.subtle.generateKey(
14246
+ { name: "ECDSA", namedCurve: "P-256" },
14247
+ false,
14248
+ // non-extractable — private key never leaves Web Crypto
14249
+ ["sign", "verify"]
14250
+ );
14251
+ const rawPublicKey = new Uint8Array(await crypto.subtle.exportKey("raw", keyPair.publicKey));
14252
+ const publicKeyBase58 = bs582.encode(rawPublicKey);
14253
+ const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKey.buffer);
14254
+ const keyId = base64urlEncode(new Uint8Array(keyIdBuffer)).substring(0, 16);
14255
+ this._keyPair = keyPair;
14256
+ this._keyInfo = {
14257
+ keyId,
14258
+ publicKey: publicKeyBase58,
14259
+ createdAt: Date.now()
14260
+ };
14261
+ await this.storeRecord({ keyPair, keyInfo: this._keyInfo });
14262
+ return this._keyInfo;
14263
+ }
14264
+ async openDB() {
14265
+ return new Promise((resolve, reject) => {
14266
+ const request = indexedDB.open(this.dbName, 1);
14267
+ request.onsuccess = () => {
14268
+ this.db = request.result;
14269
+ resolve();
14270
+ };
14271
+ request.onerror = () => reject(request.error);
14272
+ request.onupgradeneeded = (event) => {
14273
+ const db = event.target.result;
14274
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
14275
+ db.createObjectStore(STORE_NAME);
14276
+ }
14277
+ };
14278
+ });
14279
+ }
14280
+ async loadRecord() {
14281
+ return new Promise((resolve, reject) => {
14282
+ if (!this.db) {
14283
+ throw new Error("Database not initialized");
14284
+ }
14285
+ const request = this.db.transaction([STORE_NAME], "readonly").objectStore(STORE_NAME).get(ACTIVE_KEY);
14286
+ request.onsuccess = () => {
14287
+ resolve(request.result ?? null);
14288
+ };
14289
+ request.onerror = () => {
14290
+ reject(request.error);
14291
+ };
14292
+ });
14293
+ }
14294
+ async storeRecord(record) {
14295
+ return new Promise((resolve, reject) => {
14296
+ if (!this.db) {
14297
+ throw new Error("Database not initialized");
14298
+ }
14299
+ const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).put(record, ACTIVE_KEY);
14300
+ request.onsuccess = () => {
14301
+ resolve();
14302
+ };
14303
+ request.onerror = () => {
14304
+ reject(request.error);
14305
+ };
14306
+ });
14307
+ }
14308
+ async clearStoredRecord() {
14309
+ return new Promise((resolve, reject) => {
14310
+ if (!this.db) {
14311
+ throw new Error("Database not initialized");
14312
+ }
14313
+ const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).delete(ACTIVE_KEY);
14314
+ request.onsuccess = () => {
14315
+ resolve();
14316
+ };
14317
+ request.onerror = () => {
14318
+ reject(request.error);
14319
+ };
14320
+ });
14321
+ }
14322
+ };
14323
+ async function waitForPhantomExtension(timeoutMs = 3e3) {
13599
14324
  return new Promise((resolve) => {
13600
14325
  const startTime = Date.now();
13601
14326
  const checkInterval = 100;
@@ -13618,6 +14343,27 @@ async function waitForExtension(timeoutMs) {
13618
14343
  });
13619
14344
  }
13620
14345
 
14346
+ // src/isPhantomLoginAvailable.ts
14347
+ async function isPhantomLoginAvailable(timeoutMs = 3e3) {
14348
+ const extensionInstalled = await waitForPhantomExtension(timeoutMs);
14349
+ if (!extensionInstalled) {
14350
+ return false;
14351
+ }
14352
+ try {
14353
+ if (!window.phantom?.app?.features || typeof window.phantom.app.features !== "function") {
14354
+ return false;
14355
+ }
14356
+ const response = await window.phantom.app.features();
14357
+ if (!Array.isArray(response.features)) {
14358
+ return false;
14359
+ }
14360
+ return response.features.includes("phantom_login");
14361
+ } catch (error) {
14362
+ console.error("Error checking Phantom extension features", error);
14363
+ return false;
14364
+ }
14365
+ }
14366
+
13621
14367
  // src/providers/embedded/adapters/phantom-app.ts
13622
14368
  var BrowserPhantomAppProvider = class {
13623
14369
  /**
@@ -13672,33 +14418,53 @@ var BrowserPhantomAppProvider = class {
13672
14418
 
13673
14419
  // src/providers/embedded/adapters/logger.ts
13674
14420
  var BrowserLogger = class {
13675
- info(category, message, data) {
13676
- debug.info(category, message, data);
14421
+ info(message, ...args) {
14422
+ debug.info(message, args.length > 0 ? String(args[0]) : "", args[1]);
13677
14423
  }
13678
- warn(category, message, data) {
13679
- debug.warn(category, message, data);
14424
+ warn(message, ...args) {
14425
+ debug.warn(message, args.length > 0 ? String(args[0]) : "", args[1]);
13680
14426
  }
13681
- error(category, message, data) {
13682
- debug.error(category, message, data);
14427
+ error(message, ...args) {
14428
+ debug.error(message, args.length > 0 ? String(args[0]) : "", args[1]);
13683
14429
  }
13684
- log(category, message, data) {
13685
- debug.log(category, message, data);
14430
+ debug(message, ...args) {
14431
+ debug.log(message, args.length > 0 ? String(args[0]) : "", args[1]);
13686
14432
  }
13687
14433
  };
13688
14434
  var EmbeddedProvider = class extends EmbeddedProvider$1 {
13689
14435
  constructor(config) {
13690
14436
  debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
13691
14437
  const urlParamsAccessor = new BrowserURLParamsAccessor();
13692
- const stamper = new IndexedDbStamper({
14438
+ const storage = new BrowserStorage();
14439
+ const stamper = config.unstable__auth2Options ? new Auth2Stamper(`phantom-auth2-${config.appId}`, {
14440
+ authApiBaseUrl: config.unstable__auth2Options.authApiBaseUrl,
14441
+ clientId: config.unstable__auth2Options.clientId,
14442
+ redirectUri: config.authOptions?.redirectUrl ?? ""
14443
+ }) : new IndexedDbStamper({
13693
14444
  dbName: `phantom-embedded-sdk-${config.appId}`,
13694
14445
  storeName: "crypto-keys",
13695
14446
  keyName: "signing-key"
13696
14447
  });
13697
14448
  const platformName = getPlatformName();
13698
14449
  const { name: browserName, version } = detectBrowser();
14450
+ const authProvider = config.unstable__auth2Options && config.authOptions?.authUrl && config.authOptions?.redirectUrl && stamper instanceof Auth2Stamper ? new Auth2AuthProvider(
14451
+ stamper,
14452
+ storage,
14453
+ urlParamsAccessor,
14454
+ {
14455
+ redirectUri: config.authOptions.redirectUrl,
14456
+ connectLoginUrl: config.authOptions.authUrl,
14457
+ clientId: config.unstable__auth2Options.clientId,
14458
+ authApiBaseUrl: config.unstable__auth2Options.authApiBaseUrl
14459
+ },
14460
+ {
14461
+ apiBaseUrl: config.apiBaseUrl,
14462
+ appId: config.appId
14463
+ }
14464
+ ) : new BrowserAuthProvider(urlParamsAccessor);
13699
14465
  const platform = {
13700
- storage: new BrowserStorage(),
13701
- authProvider: new BrowserAuthProvider(urlParamsAccessor),
14466
+ storage,
14467
+ authProvider,
13702
14468
  phantomAppProvider: new BrowserPhantomAppProvider(),
13703
14469
  urlParamsAccessor,
13704
14470
  stamper,
@@ -13706,13 +14472,12 @@ var EmbeddedProvider = class extends EmbeddedProvider$1 {
13706
14472
  // Use detected browser name and version for identification
13707
14473
  analyticsHeaders: {
13708
14474
  [ANALYTICS_HEADERS.SDK_TYPE]: "browser",
13709
- [ANALYTICS_HEADERS.PLATFORM]: browserName,
13710
- // firefox, chrome, safari, etc.
14475
+ [ANALYTICS_HEADERS.PLATFORM]: "ext-sdk",
13711
14476
  [ANALYTICS_HEADERS.PLATFORM_VERSION]: version,
13712
- // Full user agent for more detailed info
14477
+ [ANALYTICS_HEADERS.CLIENT]: browserName,
13713
14478
  [ANALYTICS_HEADERS.APP_ID]: config.appId,
13714
14479
  [ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
13715
- [ANALYTICS_HEADERS.SDK_VERSION]: "1.0.2"
14480
+ [ANALYTICS_HEADERS.SDK_VERSION]: "1.0.7"
13716
14481
  // Replaced at build time
13717
14482
  }
13718
14483
  };
@@ -13745,11 +14510,12 @@ function isAuthCallbackUrl(searchParams) {
13745
14510
  }
13746
14511
 
13747
14512
  // src/utils/deeplink.ts
13748
- function getDeeplinkToPhantom(ref) {
13749
- if (!window.location.href.startsWith("http:") && !window.location.href.startsWith("https:")) {
14513
+ function getDeeplinkToPhantom(ref, currentHref) {
14514
+ const resolvedHref = window.location.href;
14515
+ if (!resolvedHref.startsWith("http:") && !resolvedHref.startsWith("https:")) {
13750
14516
  throw new Error("Invalid URL protocol - only HTTP/HTTPS URLs are supported for deeplinks");
13751
14517
  }
13752
- const currentUrl = encodeURIComponent(window.location.href);
14518
+ const currentUrl = encodeURIComponent(resolvedHref);
13753
14519
  const refParam = "";
13754
14520
  return `https://phantom.app/ul/browse/${currentUrl}${refParam}`;
13755
14521
  }
@@ -13845,8 +14611,14 @@ var ProviderManager = class {
13845
14611
  } else if (requestedProvider === "deeplink") {
13846
14612
  try {
13847
14613
  const deeplinkUrl = getDeeplinkToPhantom();
13848
- if (typeof window !== "undefined") {
13849
- window.location.href = deeplinkUrl;
14614
+ if (typeof window !== "undefined" && window.location) {
14615
+ try {
14616
+ window.location.href = deeplinkUrl;
14617
+ } catch (error) {
14618
+ debug.warn(DebugCategory.PROVIDER_MANAGER, "Failed to set deeplink location", {
14619
+ error: error instanceof Error ? error.message : String(error)
14620
+ });
14621
+ }
13850
14622
  }
13851
14623
  return {
13852
14624
  addresses: [],
@@ -14119,6 +14891,7 @@ var ProviderManager = class {
14119
14891
  authUrl,
14120
14892
  redirectUrl: this.config.authOptions?.redirectUrl || this.getValidatedCurrentUrl()
14121
14893
  },
14894
+ unstable__auth2Options: this.config.unstable__auth2Options,
14122
14895
  embeddedWalletType: embeddedWalletType || DEFAULT_EMBEDDED_WALLET_TYPE,
14123
14896
  addressTypes: this.config.addressTypes || [DerivationInfoAddressFormatEnum.solana]
14124
14897
  });
@@ -14313,6 +15086,7 @@ var BrowserSDK = class {
14313
15086
  */
14314
15087
  async autoConnect() {
14315
15088
  debug.log(DebugCategory.BROWSER_SDK, "Attempting auto-connect with fallback strategy");
15089
+ await this.discoverWallets();
14316
15090
  const result = await this.providerManager.autoConnect();
14317
15091
  if (result) {
14318
15092
  debug.info(DebugCategory.BROWSER_SDK, "Auto-connect successful", {
@@ -14459,28 +15233,6 @@ var BrowserSDK = class {
14459
15233
  }
14460
15234
  }
14461
15235
  };
14462
- async function waitForPhantomExtension(timeoutMs = 3e3) {
14463
- return new Promise((resolve) => {
14464
- const startTime = Date.now();
14465
- const checkInterval = 100;
14466
- const checkForExtension = () => {
14467
- try {
14468
- if (isInstalled()) {
14469
- resolve(true);
14470
- return;
14471
- }
14472
- } catch (error) {
14473
- }
14474
- const elapsed = Date.now() - startTime;
14475
- if (elapsed >= timeoutMs) {
14476
- resolve(false);
14477
- return;
14478
- }
14479
- setTimeout(checkForExtension, checkInterval);
14480
- };
14481
- checkForExtension();
14482
- });
14483
- }
14484
15236
 
14485
15237
  // src/utils/index.ts
14486
15238
  var hexToRgba = (hex, opacity) => {
@@ -16086,4 +16838,4 @@ function ConnectBox({ maxWidth = "350px", transparent = false, appIcon, appName
16086
16838
  }
16087
16839
 
16088
16840
  export { DerivationInfoAddressFormatEnum as AddressType, ConnectBox, ConnectButton, DebugLevel, NetworkId, PhantomProvider, darkTheme, debug, isMobileDevice, lightTheme, mergeTheme, useAccounts, useAutoConfirm, useConnect, useDisconnect, useDiscoveredWallets, useEthereum, useIsExtensionInstalled, useIsPhantomLoginAvailable, useModal, usePhantom, useSolana, useTheme };
16089
- //# sourceMappingURL=index-BFOmV3Pb.esm.js.map
16841
+ //# sourceMappingURL=index-C2yvle9S.esm.js.map