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