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