@bounded-sh/client 0.0.2 → 0.0.4

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