@phantom/browser-sdk 1.0.4 → 1.0.6
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/index.js +145 -65
- package/dist/index.mjs +128 -49
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -34,8 +34,8 @@ __export(src_exports, {
|
|
|
34
34
|
BrowserSDK: () => BrowserSDK,
|
|
35
35
|
DebugCategory: () => DebugCategory,
|
|
36
36
|
DebugLevel: () => DebugLevel,
|
|
37
|
-
NetworkId: () =>
|
|
38
|
-
PHANTOM_ICON: () =>
|
|
37
|
+
NetworkId: () => import_constants8.NetworkId,
|
|
38
|
+
PHANTOM_ICON: () => import_constants9.PHANTOM_ICON,
|
|
39
39
|
debug: () => debug,
|
|
40
40
|
detectBrowser: () => detectBrowser,
|
|
41
41
|
getBrowserDisplayName: () => getBrowserDisplayName,
|
|
@@ -2764,7 +2764,7 @@ var BrowserAuthProvider = class {
|
|
|
2764
2764
|
// OAuth session management - defaults to allow refresh unless explicitly clearing after logout
|
|
2765
2765
|
clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
|
|
2766
2766
|
allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
|
|
2767
|
-
sdk_version: "1.0.
|
|
2767
|
+
sdk_version: "1.0.6",
|
|
2768
2768
|
sdk_type: "browser",
|
|
2769
2769
|
platform: detectBrowser().name,
|
|
2770
2770
|
algorithm: phantomOptions.algorithm || import_constants3.DEFAULT_AUTHENTICATOR_ALGORITHM
|
|
@@ -2904,8 +2904,8 @@ var Auth2AuthProvider = class {
|
|
|
2904
2904
|
*
|
|
2905
2905
|
* Called by EmbeddedProvider.handleRedirectAuth() after the stamper has
|
|
2906
2906
|
* already been initialized and a pending Session has been saved to storage.
|
|
2907
|
-
* We store the PKCE code_verifier
|
|
2908
|
-
*
|
|
2907
|
+
* We store the PKCE code_verifier into that session so it survives the page
|
|
2908
|
+
* redirect without ever touching sessionStorage.
|
|
2909
2909
|
*/
|
|
2910
2910
|
async authenticate(options) {
|
|
2911
2911
|
if (!this.stamper.getKeyInfo()) {
|
|
@@ -2916,12 +2916,11 @@ var Auth2AuthProvider = class {
|
|
|
2916
2916
|
throw new Error("Stamper key pair not found.");
|
|
2917
2917
|
}
|
|
2918
2918
|
const codeVerifier = (0, import_auth2.createCodeVerifier)();
|
|
2919
|
-
const salt = (0, import_auth2.createSalt)();
|
|
2920
2919
|
const session = await this.storage.getSession();
|
|
2921
2920
|
if (!session) {
|
|
2922
2921
|
throw new Error("Session not found.");
|
|
2923
2922
|
}
|
|
2924
|
-
await this.storage.saveSession({ ...session, pkceCodeVerifier: codeVerifier
|
|
2923
|
+
await this.storage.saveSession({ ...session, pkceCodeVerifier: codeVerifier });
|
|
2925
2924
|
const url = await (0, import_auth2.createConnectStartUrl)({
|
|
2926
2925
|
keyPair,
|
|
2927
2926
|
connectLoginUrl: this.auth2ProviderOptions.connectLoginUrl,
|
|
@@ -2930,7 +2929,8 @@ var Auth2AuthProvider = class {
|
|
|
2930
2929
|
sessionId: options.sessionId,
|
|
2931
2930
|
provider: options.provider,
|
|
2932
2931
|
codeVerifier,
|
|
2933
|
-
salt
|
|
2932
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
2933
|
+
salt: ""
|
|
2934
2934
|
});
|
|
2935
2935
|
Auth2AuthProvider.navigate(url);
|
|
2936
2936
|
}
|
|
@@ -2965,24 +2965,21 @@ var Auth2AuthProvider = class {
|
|
|
2965
2965
|
const description = this.urlParamsAccessor.getParam("error_description");
|
|
2966
2966
|
throw new Error(`Auth2 callback error: ${description ?? error}`);
|
|
2967
2967
|
}
|
|
2968
|
-
const { idToken, bearerToken, authUserId, expiresInMs } = await (0, import_auth2.exchangeAuthCode)({
|
|
2968
|
+
const { idToken, bearerToken, authUserId, expiresInMs, refreshToken } = await (0, import_auth2.exchangeAuthCode)({
|
|
2969
2969
|
authApiBaseUrl: this.auth2ProviderOptions.authApiBaseUrl,
|
|
2970
2970
|
clientId: this.auth2ProviderOptions.clientId,
|
|
2971
2971
|
redirectUri: this.auth2ProviderOptions.redirectUri,
|
|
2972
2972
|
code,
|
|
2973
2973
|
codeVerifier
|
|
2974
2974
|
});
|
|
2975
|
-
this.stamper.idToken
|
|
2976
|
-
this.stamper.salt = session?.salt;
|
|
2975
|
+
await this.stamper.setTokens({ idToken, bearerToken, refreshToken, expiresInMs });
|
|
2977
2976
|
await this.storage.saveSession({
|
|
2978
2977
|
...session,
|
|
2979
2978
|
status: "completed",
|
|
2980
2979
|
bearerToken,
|
|
2981
2980
|
authUserId,
|
|
2982
|
-
pkceCodeVerifier: void 0
|
|
2981
|
+
pkceCodeVerifier: void 0
|
|
2983
2982
|
// no longer needed after code exchange
|
|
2984
|
-
salt: void 0
|
|
2985
|
-
// no longer needed after nonce binding is complete
|
|
2986
2983
|
});
|
|
2987
2984
|
const { organizationId, walletId } = await this.kms.discoverOrganizationAndWalletId(bearerToken, authUserId);
|
|
2988
2985
|
return {
|
|
@@ -3002,27 +2999,48 @@ var Auth2AuthProvider = class {
|
|
|
3002
2999
|
var import_bs582 = __toESM(require("bs58"));
|
|
3003
3000
|
var import_base64url = require("@phantom/base64url");
|
|
3004
3001
|
var import_sdk_types = require("@phantom/sdk-types");
|
|
3002
|
+
var import_auth22 = require("@phantom/auth2");
|
|
3003
|
+
var import_constants4 = require("@phantom/constants");
|
|
3005
3004
|
var STORE_NAME = "crypto-keys";
|
|
3006
3005
|
var ACTIVE_KEY = "auth2-p256-signing-key";
|
|
3007
3006
|
var Auth2Stamper = class {
|
|
3008
3007
|
/**
|
|
3009
3008
|
* @param dbName - IndexedDB database name (use a unique name per app to
|
|
3010
3009
|
* avoid key collisions with other stampers, e.g. `phantom-auth2-<appId>`).
|
|
3010
|
+
* @param refreshConfig - When provided, the stamper will automatically refresh
|
|
3011
|
+
* the id_token using the refresh_token before it expires.
|
|
3011
3012
|
*/
|
|
3012
|
-
constructor(dbName) {
|
|
3013
|
+
constructor(dbName, refreshConfig) {
|
|
3013
3014
|
this.dbName = dbName;
|
|
3015
|
+
this.refreshConfig = refreshConfig;
|
|
3014
3016
|
this.db = null;
|
|
3015
|
-
this.
|
|
3017
|
+
this._keyPair = null;
|
|
3016
3018
|
this._keyInfo = null;
|
|
3019
|
+
this._idToken = null;
|
|
3020
|
+
this._bearerToken = null;
|
|
3021
|
+
this._refreshToken = null;
|
|
3022
|
+
this._tokenExpiresAt = null;
|
|
3017
3023
|
this.algorithm = import_sdk_types.Algorithm.secp256r1;
|
|
3018
|
-
this.type = "
|
|
3024
|
+
this.type = "OIDC";
|
|
3019
3025
|
}
|
|
3020
3026
|
async init() {
|
|
3021
3027
|
await this.openDB();
|
|
3022
|
-
const stored = await this.
|
|
3028
|
+
const stored = await this.loadRecord();
|
|
3023
3029
|
if (stored) {
|
|
3024
|
-
this.
|
|
3030
|
+
this._keyPair = stored.keyPair;
|
|
3025
3031
|
this._keyInfo = stored.keyInfo;
|
|
3032
|
+
if (stored.idToken) {
|
|
3033
|
+
this._idToken = stored.idToken;
|
|
3034
|
+
}
|
|
3035
|
+
if (stored.bearerToken) {
|
|
3036
|
+
this._bearerToken = stored.bearerToken;
|
|
3037
|
+
}
|
|
3038
|
+
if (stored.refreshToken) {
|
|
3039
|
+
this._refreshToken = stored.refreshToken;
|
|
3040
|
+
}
|
|
3041
|
+
if (stored.tokenExpiresAt) {
|
|
3042
|
+
this._tokenExpiresAt = stored.tokenExpiresAt;
|
|
3043
|
+
}
|
|
3026
3044
|
return this._keyInfo;
|
|
3027
3045
|
}
|
|
3028
3046
|
return this.generateAndStore();
|
|
@@ -3031,41 +3049,99 @@ var Auth2Stamper = class {
|
|
|
3031
3049
|
return this._keyInfo;
|
|
3032
3050
|
}
|
|
3033
3051
|
getCryptoKeyPair() {
|
|
3034
|
-
return this.
|
|
3052
|
+
return this._keyPair;
|
|
3053
|
+
}
|
|
3054
|
+
/**
|
|
3055
|
+
* Returns the current token state (refreshing proactively if near expiry),
|
|
3056
|
+
* or null if no token has been set yet.
|
|
3057
|
+
*/
|
|
3058
|
+
async getTokens() {
|
|
3059
|
+
if (this.refreshConfig && this._refreshToken && this._tokenExpiresAt !== null && Date.now() >= this._tokenExpiresAt - import_constants4.TOKEN_REFRESH_BUFFER_MS) {
|
|
3060
|
+
const refreshed = await (0, import_auth22.refreshToken)({
|
|
3061
|
+
authApiBaseUrl: this.refreshConfig.authApiBaseUrl,
|
|
3062
|
+
clientId: this.refreshConfig.clientId,
|
|
3063
|
+
redirectUri: this.refreshConfig.redirectUri,
|
|
3064
|
+
refreshToken: this._refreshToken
|
|
3065
|
+
});
|
|
3066
|
+
await this.setTokens(refreshed);
|
|
3067
|
+
}
|
|
3068
|
+
if (!this._idToken || !this._bearerToken) {
|
|
3069
|
+
return null;
|
|
3070
|
+
}
|
|
3071
|
+
return {
|
|
3072
|
+
idToken: this._idToken,
|
|
3073
|
+
bearerToken: this._bearerToken,
|
|
3074
|
+
refreshToken: this._refreshToken ?? void 0
|
|
3075
|
+
};
|
|
3076
|
+
}
|
|
3077
|
+
/**
|
|
3078
|
+
* Arms the stamper with the OIDC token data for subsequent KMS stamp() calls.
|
|
3079
|
+
*
|
|
3080
|
+
* Persists the tokens to IndexedDB alongside the key pair so that
|
|
3081
|
+
* auto-connect can restore them on the next page load without a new login.
|
|
3082
|
+
*
|
|
3083
|
+
* @param refreshToken - When provided alongside a `refreshConfig`, enables
|
|
3084
|
+
* silent token refresh before the token expires.
|
|
3085
|
+
* @param expiresInMs - Token lifetime in milliseconds (from `expires_in * 1000`).
|
|
3086
|
+
* Used to compute the absolute expiry time for proactive refresh.
|
|
3087
|
+
*/
|
|
3088
|
+
async setTokens({
|
|
3089
|
+
idToken,
|
|
3090
|
+
bearerToken,
|
|
3091
|
+
refreshToken,
|
|
3092
|
+
expiresInMs
|
|
3093
|
+
}) {
|
|
3094
|
+
if (!this.db) {
|
|
3095
|
+
await this.openDB();
|
|
3096
|
+
}
|
|
3097
|
+
this._idToken = idToken;
|
|
3098
|
+
this._bearerToken = bearerToken;
|
|
3099
|
+
this._refreshToken = refreshToken ?? null;
|
|
3100
|
+
this._tokenExpiresAt = expiresInMs != null ? Date.now() + expiresInMs : null;
|
|
3101
|
+
const existing = await this.loadRecord();
|
|
3102
|
+
if (existing) {
|
|
3103
|
+
await this.storeRecord({
|
|
3104
|
+
...existing,
|
|
3105
|
+
idToken,
|
|
3106
|
+
bearerToken,
|
|
3107
|
+
refreshToken,
|
|
3108
|
+
tokenExpiresAt: this._tokenExpiresAt ?? void 0
|
|
3109
|
+
});
|
|
3110
|
+
}
|
|
3035
3111
|
}
|
|
3036
3112
|
async stamp(params) {
|
|
3037
|
-
if (!this.
|
|
3113
|
+
if (!this._keyPair || !this._keyInfo || this._idToken === null) {
|
|
3038
3114
|
throw new Error("Auth2Stamper not initialized. Call init() first.");
|
|
3039
3115
|
}
|
|
3040
3116
|
const signatureRaw = await crypto.subtle.sign(
|
|
3041
3117
|
{ name: "ECDSA", hash: "SHA-256" },
|
|
3042
|
-
this.
|
|
3118
|
+
this._keyPair.privateKey,
|
|
3043
3119
|
new Uint8Array(params.data)
|
|
3044
3120
|
);
|
|
3045
3121
|
const rawPublicKey = import_bs582.default.decode(this._keyInfo.publicKey);
|
|
3046
|
-
if (this.idToken === void 0 || this.salt === void 0) {
|
|
3047
|
-
throw new Error("Auth2Stamper not initialized with idToken or salt.");
|
|
3048
|
-
}
|
|
3049
3122
|
const stampData = {
|
|
3050
|
-
kind:
|
|
3051
|
-
idToken: this.
|
|
3123
|
+
kind: this.type,
|
|
3124
|
+
idToken: this._idToken,
|
|
3052
3125
|
publicKey: (0, import_base64url.base64urlEncode)(rawPublicKey),
|
|
3053
|
-
algorithm:
|
|
3054
|
-
salt
|
|
3126
|
+
algorithm: this.algorithm,
|
|
3127
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
3128
|
+
salt: "",
|
|
3055
3129
|
signature: (0, import_base64url.base64urlEncode)(new Uint8Array(signatureRaw))
|
|
3056
3130
|
};
|
|
3057
3131
|
return (0, import_base64url.base64urlEncode)(new TextEncoder().encode(JSON.stringify(stampData)));
|
|
3058
3132
|
}
|
|
3059
3133
|
async resetKeyPair() {
|
|
3060
|
-
await this.
|
|
3061
|
-
this.keyPair = null;
|
|
3062
|
-
this._keyInfo = null;
|
|
3134
|
+
await this.clear();
|
|
3063
3135
|
return this.generateAndStore();
|
|
3064
3136
|
}
|
|
3065
3137
|
async clear() {
|
|
3066
|
-
await this.
|
|
3067
|
-
this.
|
|
3138
|
+
await this.clearStoredRecord();
|
|
3139
|
+
this._keyPair = null;
|
|
3068
3140
|
this._keyInfo = null;
|
|
3141
|
+
this._idToken = null;
|
|
3142
|
+
this._bearerToken = null;
|
|
3143
|
+
this._refreshToken = null;
|
|
3144
|
+
this._tokenExpiresAt = null;
|
|
3069
3145
|
}
|
|
3070
3146
|
// Auth2 doesn't use key rotation; provide minimal no-op implementations.
|
|
3071
3147
|
async rotateKeyPair() {
|
|
@@ -3090,13 +3166,13 @@ var Auth2Stamper = class {
|
|
|
3090
3166
|
const publicKeyBase58 = import_bs582.default.encode(rawPublicKey);
|
|
3091
3167
|
const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKey.buffer);
|
|
3092
3168
|
const keyId = (0, import_base64url.base64urlEncode)(new Uint8Array(keyIdBuffer)).substring(0, 16);
|
|
3093
|
-
this.
|
|
3169
|
+
this._keyPair = keyPair;
|
|
3094
3170
|
this._keyInfo = {
|
|
3095
3171
|
keyId,
|
|
3096
3172
|
publicKey: publicKeyBase58,
|
|
3097
3173
|
createdAt: Date.now()
|
|
3098
3174
|
};
|
|
3099
|
-
await this.
|
|
3175
|
+
await this.storeRecord({ keyPair, keyInfo: this._keyInfo });
|
|
3100
3176
|
return this._keyInfo;
|
|
3101
3177
|
}
|
|
3102
3178
|
async openDB() {
|
|
@@ -3115,7 +3191,7 @@ var Auth2Stamper = class {
|
|
|
3115
3191
|
};
|
|
3116
3192
|
});
|
|
3117
3193
|
}
|
|
3118
|
-
async
|
|
3194
|
+
async loadRecord() {
|
|
3119
3195
|
return new Promise((resolve, reject) => {
|
|
3120
3196
|
if (!this.db) {
|
|
3121
3197
|
throw new Error("Database not initialized");
|
|
@@ -3129,12 +3205,12 @@ var Auth2Stamper = class {
|
|
|
3129
3205
|
};
|
|
3130
3206
|
});
|
|
3131
3207
|
}
|
|
3132
|
-
async
|
|
3208
|
+
async storeRecord(record) {
|
|
3133
3209
|
return new Promise((resolve, reject) => {
|
|
3134
3210
|
if (!this.db) {
|
|
3135
3211
|
throw new Error("Database not initialized");
|
|
3136
3212
|
}
|
|
3137
|
-
const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).put(
|
|
3213
|
+
const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).put(record, ACTIVE_KEY);
|
|
3138
3214
|
request.onsuccess = () => {
|
|
3139
3215
|
resolve();
|
|
3140
3216
|
};
|
|
@@ -3143,7 +3219,7 @@ var Auth2Stamper = class {
|
|
|
3143
3219
|
};
|
|
3144
3220
|
});
|
|
3145
3221
|
}
|
|
3146
|
-
async
|
|
3222
|
+
async clearStoredRecord() {
|
|
3147
3223
|
return new Promise((resolve, reject) => {
|
|
3148
3224
|
if (!this.db) {
|
|
3149
3225
|
throw new Error("Database not initialized");
|
|
@@ -3262,28 +3338,32 @@ var BrowserPhantomAppProvider = class {
|
|
|
3262
3338
|
|
|
3263
3339
|
// src/providers/embedded/adapters/logger.ts
|
|
3264
3340
|
var BrowserLogger = class {
|
|
3265
|
-
info(
|
|
3266
|
-
debug.info(
|
|
3341
|
+
info(message, ...args) {
|
|
3342
|
+
debug.info(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3267
3343
|
}
|
|
3268
|
-
warn(
|
|
3269
|
-
debug.warn(
|
|
3344
|
+
warn(message, ...args) {
|
|
3345
|
+
debug.warn(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3270
3346
|
}
|
|
3271
|
-
error(
|
|
3272
|
-
debug.error(
|
|
3347
|
+
error(message, ...args) {
|
|
3348
|
+
debug.error(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3273
3349
|
}
|
|
3274
|
-
|
|
3275
|
-
debug.log(
|
|
3350
|
+
debug(message, ...args) {
|
|
3351
|
+
debug.log(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3276
3352
|
}
|
|
3277
3353
|
};
|
|
3278
3354
|
|
|
3279
3355
|
// src/providers/embedded/index.ts
|
|
3280
|
-
var
|
|
3356
|
+
var import_constants5 = require("@phantom/constants");
|
|
3281
3357
|
var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvider {
|
|
3282
3358
|
constructor(config) {
|
|
3283
3359
|
debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
|
|
3284
3360
|
const urlParamsAccessor = new BrowserURLParamsAccessor();
|
|
3285
3361
|
const storage = new BrowserStorage();
|
|
3286
|
-
const stamper = config.unstable__auth2Options ? new Auth2Stamper(`phantom-auth2-${config.appId}
|
|
3362
|
+
const stamper = config.unstable__auth2Options ? new Auth2Stamper(`phantom-auth2-${config.appId}`, {
|
|
3363
|
+
authApiBaseUrl: config.unstable__auth2Options.authApiBaseUrl,
|
|
3364
|
+
clientId: config.unstable__auth2Options.clientId,
|
|
3365
|
+
redirectUri: config.authOptions?.redirectUrl ?? ""
|
|
3366
|
+
}) : new import_indexed_db_stamper.IndexedDbStamper({
|
|
3287
3367
|
dbName: `phantom-embedded-sdk-${config.appId}`,
|
|
3288
3368
|
storeName: "crypto-keys",
|
|
3289
3369
|
keyName: "signing-key"
|
|
@@ -3314,13 +3394,13 @@ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvi
|
|
|
3314
3394
|
name: platformName,
|
|
3315
3395
|
// Use detected browser name and version for identification
|
|
3316
3396
|
analyticsHeaders: {
|
|
3317
|
-
[
|
|
3318
|
-
[
|
|
3319
|
-
[
|
|
3320
|
-
[
|
|
3321
|
-
[
|
|
3322
|
-
[
|
|
3323
|
-
[
|
|
3397
|
+
[import_constants5.ANALYTICS_HEADERS.SDK_TYPE]: "browser",
|
|
3398
|
+
[import_constants5.ANALYTICS_HEADERS.PLATFORM]: "ext-sdk",
|
|
3399
|
+
[import_constants5.ANALYTICS_HEADERS.PLATFORM_VERSION]: version,
|
|
3400
|
+
[import_constants5.ANALYTICS_HEADERS.CLIENT]: browserName,
|
|
3401
|
+
[import_constants5.ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
3402
|
+
[import_constants5.ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
3403
|
+
[import_constants5.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.6"
|
|
3324
3404
|
// Replaced at build time
|
|
3325
3405
|
}
|
|
3326
3406
|
};
|
|
@@ -3337,7 +3417,7 @@ var EmbeddedProvider = class extends import_embedded_provider_core.EmbeddedProvi
|
|
|
3337
3417
|
|
|
3338
3418
|
// src/ProviderManager.ts
|
|
3339
3419
|
var import_embedded_provider_core2 = require("@phantom/embedded-provider-core");
|
|
3340
|
-
var
|
|
3420
|
+
var import_constants6 = require("@phantom/constants");
|
|
3341
3421
|
|
|
3342
3422
|
// src/utils/auth-callback.ts
|
|
3343
3423
|
function isAuthFailureCallback(searchParams) {
|
|
@@ -3728,8 +3808,8 @@ var ProviderManager = class {
|
|
|
3728
3808
|
if (!this.config.appId) {
|
|
3729
3809
|
throw new Error("appId is required for embedded provider");
|
|
3730
3810
|
}
|
|
3731
|
-
const apiBaseUrl = this.config.apiBaseUrl ||
|
|
3732
|
-
const authUrl = this.config.authOptions?.authUrl ||
|
|
3811
|
+
const apiBaseUrl = this.config.apiBaseUrl || import_constants6.DEFAULT_WALLET_API_URL;
|
|
3812
|
+
const authUrl = this.config.authOptions?.authUrl || import_constants6.DEFAULT_AUTH_URL;
|
|
3733
3813
|
provider = new EmbeddedProvider({
|
|
3734
3814
|
apiBaseUrl,
|
|
3735
3815
|
appId: this.config.appId,
|
|
@@ -3739,7 +3819,7 @@ var ProviderManager = class {
|
|
|
3739
3819
|
redirectUrl: this.config.authOptions?.redirectUrl || this.getValidatedCurrentUrl()
|
|
3740
3820
|
},
|
|
3741
3821
|
unstable__auth2Options: this.config.unstable__auth2Options,
|
|
3742
|
-
embeddedWalletType: embeddedWalletType ||
|
|
3822
|
+
embeddedWalletType: embeddedWalletType || import_constants6.DEFAULT_EMBEDDED_WALLET_TYPE,
|
|
3743
3823
|
addressTypes: this.config.addressTypes || [import_client.AddressType.solana]
|
|
3744
3824
|
});
|
|
3745
3825
|
} else {
|
|
@@ -3775,7 +3855,7 @@ var ProviderManager = class {
|
|
|
3775
3855
|
|
|
3776
3856
|
// src/BrowserSDK.ts
|
|
3777
3857
|
var import_embedded_provider_core3 = require("@phantom/embedded-provider-core");
|
|
3778
|
-
var
|
|
3858
|
+
var import_constants7 = require("@phantom/constants");
|
|
3779
3859
|
var BROWSER_SDK_PROVIDER_TYPES = [
|
|
3780
3860
|
...import_embedded_provider_core3.EMBEDDED_PROVIDER_AUTH_TYPES,
|
|
3781
3861
|
"injected",
|
|
@@ -3811,7 +3891,7 @@ var BrowserSDK = class {
|
|
|
3811
3891
|
});
|
|
3812
3892
|
throw new Error("appId is required when using embedded providers (google, apple, phantom, etc.)");
|
|
3813
3893
|
}
|
|
3814
|
-
const embeddedWalletType = config.embeddedWalletType ||
|
|
3894
|
+
const embeddedWalletType = config.embeddedWalletType || import_constants7.DEFAULT_EMBEDDED_WALLET_TYPE;
|
|
3815
3895
|
if (!["app-wallet", "user-wallet"].includes(embeddedWalletType)) {
|
|
3816
3896
|
debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType", {
|
|
3817
3897
|
embeddedWalletType: config.embeddedWalletType
|
|
@@ -4086,6 +4166,6 @@ var BrowserSDK = class {
|
|
|
4086
4166
|
};
|
|
4087
4167
|
|
|
4088
4168
|
// src/index.ts
|
|
4089
|
-
var import_constants7 = require("@phantom/constants");
|
|
4090
|
-
var import_client5 = require("@phantom/client");
|
|
4091
4169
|
var import_constants8 = require("@phantom/constants");
|
|
4170
|
+
var import_client5 = require("@phantom/client");
|
|
4171
|
+
var import_constants9 = require("@phantom/constants");
|
package/dist/index.mjs
CHANGED
|
@@ -2714,7 +2714,7 @@ var BrowserAuthProvider = class {
|
|
|
2714
2714
|
// OAuth session management - defaults to allow refresh unless explicitly clearing after logout
|
|
2715
2715
|
clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
|
|
2716
2716
|
allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
|
|
2717
|
-
sdk_version: "1.0.
|
|
2717
|
+
sdk_version: "1.0.6",
|
|
2718
2718
|
sdk_type: "browser",
|
|
2719
2719
|
platform: detectBrowser().name,
|
|
2720
2720
|
algorithm: phantomOptions.algorithm || DEFAULT_AUTHENTICATOR_ALGORITHM
|
|
@@ -2838,7 +2838,6 @@ var BrowserAuthProvider = class {
|
|
|
2838
2838
|
// src/providers/embedded/adapters/Auth2AuthProvider.ts
|
|
2839
2839
|
import {
|
|
2840
2840
|
createCodeVerifier,
|
|
2841
|
-
createSalt,
|
|
2842
2841
|
createConnectStartUrl,
|
|
2843
2842
|
exchangeAuthCode,
|
|
2844
2843
|
Auth2KmsRpcClient
|
|
@@ -2860,8 +2859,8 @@ var Auth2AuthProvider = class {
|
|
|
2860
2859
|
*
|
|
2861
2860
|
* Called by EmbeddedProvider.handleRedirectAuth() after the stamper has
|
|
2862
2861
|
* already been initialized and a pending Session has been saved to storage.
|
|
2863
|
-
* We store the PKCE code_verifier
|
|
2864
|
-
*
|
|
2862
|
+
* We store the PKCE code_verifier into that session so it survives the page
|
|
2863
|
+
* redirect without ever touching sessionStorage.
|
|
2865
2864
|
*/
|
|
2866
2865
|
async authenticate(options) {
|
|
2867
2866
|
if (!this.stamper.getKeyInfo()) {
|
|
@@ -2872,12 +2871,11 @@ var Auth2AuthProvider = class {
|
|
|
2872
2871
|
throw new Error("Stamper key pair not found.");
|
|
2873
2872
|
}
|
|
2874
2873
|
const codeVerifier = createCodeVerifier();
|
|
2875
|
-
const salt = createSalt();
|
|
2876
2874
|
const session = await this.storage.getSession();
|
|
2877
2875
|
if (!session) {
|
|
2878
2876
|
throw new Error("Session not found.");
|
|
2879
2877
|
}
|
|
2880
|
-
await this.storage.saveSession({ ...session, pkceCodeVerifier: codeVerifier
|
|
2878
|
+
await this.storage.saveSession({ ...session, pkceCodeVerifier: codeVerifier });
|
|
2881
2879
|
const url = await createConnectStartUrl({
|
|
2882
2880
|
keyPair,
|
|
2883
2881
|
connectLoginUrl: this.auth2ProviderOptions.connectLoginUrl,
|
|
@@ -2886,7 +2884,8 @@ var Auth2AuthProvider = class {
|
|
|
2886
2884
|
sessionId: options.sessionId,
|
|
2887
2885
|
provider: options.provider,
|
|
2888
2886
|
codeVerifier,
|
|
2889
|
-
salt
|
|
2887
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
2888
|
+
salt: ""
|
|
2890
2889
|
});
|
|
2891
2890
|
Auth2AuthProvider.navigate(url);
|
|
2892
2891
|
}
|
|
@@ -2921,24 +2920,21 @@ var Auth2AuthProvider = class {
|
|
|
2921
2920
|
const description = this.urlParamsAccessor.getParam("error_description");
|
|
2922
2921
|
throw new Error(`Auth2 callback error: ${description ?? error}`);
|
|
2923
2922
|
}
|
|
2924
|
-
const { idToken, bearerToken, authUserId, expiresInMs } = await exchangeAuthCode({
|
|
2923
|
+
const { idToken, bearerToken, authUserId, expiresInMs, refreshToken } = await exchangeAuthCode({
|
|
2925
2924
|
authApiBaseUrl: this.auth2ProviderOptions.authApiBaseUrl,
|
|
2926
2925
|
clientId: this.auth2ProviderOptions.clientId,
|
|
2927
2926
|
redirectUri: this.auth2ProviderOptions.redirectUri,
|
|
2928
2927
|
code,
|
|
2929
2928
|
codeVerifier
|
|
2930
2929
|
});
|
|
2931
|
-
this.stamper.idToken
|
|
2932
|
-
this.stamper.salt = session?.salt;
|
|
2930
|
+
await this.stamper.setTokens({ idToken, bearerToken, refreshToken, expiresInMs });
|
|
2933
2931
|
await this.storage.saveSession({
|
|
2934
2932
|
...session,
|
|
2935
2933
|
status: "completed",
|
|
2936
2934
|
bearerToken,
|
|
2937
2935
|
authUserId,
|
|
2938
|
-
pkceCodeVerifier: void 0
|
|
2936
|
+
pkceCodeVerifier: void 0
|
|
2939
2937
|
// no longer needed after code exchange
|
|
2940
|
-
salt: void 0
|
|
2941
|
-
// no longer needed after nonce binding is complete
|
|
2942
2938
|
});
|
|
2943
2939
|
const { organizationId, walletId } = await this.kms.discoverOrganizationAndWalletId(bearerToken, authUserId);
|
|
2944
2940
|
return {
|
|
@@ -2958,27 +2954,48 @@ var Auth2AuthProvider = class {
|
|
|
2958
2954
|
import bs582 from "bs58";
|
|
2959
2955
|
import { base64urlEncode } from "@phantom/base64url";
|
|
2960
2956
|
import { Algorithm } from "@phantom/sdk-types";
|
|
2957
|
+
import { refreshToken as refreshTokenRequest } from "@phantom/auth2";
|
|
2958
|
+
import { TOKEN_REFRESH_BUFFER_MS } from "@phantom/constants";
|
|
2961
2959
|
var STORE_NAME = "crypto-keys";
|
|
2962
2960
|
var ACTIVE_KEY = "auth2-p256-signing-key";
|
|
2963
2961
|
var Auth2Stamper = class {
|
|
2964
2962
|
/**
|
|
2965
2963
|
* @param dbName - IndexedDB database name (use a unique name per app to
|
|
2966
2964
|
* avoid key collisions with other stampers, e.g. `phantom-auth2-<appId>`).
|
|
2965
|
+
* @param refreshConfig - When provided, the stamper will automatically refresh
|
|
2966
|
+
* the id_token using the refresh_token before it expires.
|
|
2967
2967
|
*/
|
|
2968
|
-
constructor(dbName) {
|
|
2968
|
+
constructor(dbName, refreshConfig) {
|
|
2969
2969
|
this.dbName = dbName;
|
|
2970
|
+
this.refreshConfig = refreshConfig;
|
|
2970
2971
|
this.db = null;
|
|
2971
|
-
this.
|
|
2972
|
+
this._keyPair = null;
|
|
2972
2973
|
this._keyInfo = null;
|
|
2974
|
+
this._idToken = null;
|
|
2975
|
+
this._bearerToken = null;
|
|
2976
|
+
this._refreshToken = null;
|
|
2977
|
+
this._tokenExpiresAt = null;
|
|
2973
2978
|
this.algorithm = Algorithm.secp256r1;
|
|
2974
|
-
this.type = "
|
|
2979
|
+
this.type = "OIDC";
|
|
2975
2980
|
}
|
|
2976
2981
|
async init() {
|
|
2977
2982
|
await this.openDB();
|
|
2978
|
-
const stored = await this.
|
|
2983
|
+
const stored = await this.loadRecord();
|
|
2979
2984
|
if (stored) {
|
|
2980
|
-
this.
|
|
2985
|
+
this._keyPair = stored.keyPair;
|
|
2981
2986
|
this._keyInfo = stored.keyInfo;
|
|
2987
|
+
if (stored.idToken) {
|
|
2988
|
+
this._idToken = stored.idToken;
|
|
2989
|
+
}
|
|
2990
|
+
if (stored.bearerToken) {
|
|
2991
|
+
this._bearerToken = stored.bearerToken;
|
|
2992
|
+
}
|
|
2993
|
+
if (stored.refreshToken) {
|
|
2994
|
+
this._refreshToken = stored.refreshToken;
|
|
2995
|
+
}
|
|
2996
|
+
if (stored.tokenExpiresAt) {
|
|
2997
|
+
this._tokenExpiresAt = stored.tokenExpiresAt;
|
|
2998
|
+
}
|
|
2982
2999
|
return this._keyInfo;
|
|
2983
3000
|
}
|
|
2984
3001
|
return this.generateAndStore();
|
|
@@ -2987,41 +3004,99 @@ var Auth2Stamper = class {
|
|
|
2987
3004
|
return this._keyInfo;
|
|
2988
3005
|
}
|
|
2989
3006
|
getCryptoKeyPair() {
|
|
2990
|
-
return this.
|
|
3007
|
+
return this._keyPair;
|
|
3008
|
+
}
|
|
3009
|
+
/**
|
|
3010
|
+
* Returns the current token state (refreshing proactively if near expiry),
|
|
3011
|
+
* or null if no token has been set yet.
|
|
3012
|
+
*/
|
|
3013
|
+
async getTokens() {
|
|
3014
|
+
if (this.refreshConfig && this._refreshToken && this._tokenExpiresAt !== null && Date.now() >= this._tokenExpiresAt - TOKEN_REFRESH_BUFFER_MS) {
|
|
3015
|
+
const refreshed = await refreshTokenRequest({
|
|
3016
|
+
authApiBaseUrl: this.refreshConfig.authApiBaseUrl,
|
|
3017
|
+
clientId: this.refreshConfig.clientId,
|
|
3018
|
+
redirectUri: this.refreshConfig.redirectUri,
|
|
3019
|
+
refreshToken: this._refreshToken
|
|
3020
|
+
});
|
|
3021
|
+
await this.setTokens(refreshed);
|
|
3022
|
+
}
|
|
3023
|
+
if (!this._idToken || !this._bearerToken) {
|
|
3024
|
+
return null;
|
|
3025
|
+
}
|
|
3026
|
+
return {
|
|
3027
|
+
idToken: this._idToken,
|
|
3028
|
+
bearerToken: this._bearerToken,
|
|
3029
|
+
refreshToken: this._refreshToken ?? void 0
|
|
3030
|
+
};
|
|
3031
|
+
}
|
|
3032
|
+
/**
|
|
3033
|
+
* Arms the stamper with the OIDC token data for subsequent KMS stamp() calls.
|
|
3034
|
+
*
|
|
3035
|
+
* Persists the tokens to IndexedDB alongside the key pair so that
|
|
3036
|
+
* auto-connect can restore them on the next page load without a new login.
|
|
3037
|
+
*
|
|
3038
|
+
* @param refreshToken - When provided alongside a `refreshConfig`, enables
|
|
3039
|
+
* silent token refresh before the token expires.
|
|
3040
|
+
* @param expiresInMs - Token lifetime in milliseconds (from `expires_in * 1000`).
|
|
3041
|
+
* Used to compute the absolute expiry time for proactive refresh.
|
|
3042
|
+
*/
|
|
3043
|
+
async setTokens({
|
|
3044
|
+
idToken,
|
|
3045
|
+
bearerToken,
|
|
3046
|
+
refreshToken,
|
|
3047
|
+
expiresInMs
|
|
3048
|
+
}) {
|
|
3049
|
+
if (!this.db) {
|
|
3050
|
+
await this.openDB();
|
|
3051
|
+
}
|
|
3052
|
+
this._idToken = idToken;
|
|
3053
|
+
this._bearerToken = bearerToken;
|
|
3054
|
+
this._refreshToken = refreshToken ?? null;
|
|
3055
|
+
this._tokenExpiresAt = expiresInMs != null ? Date.now() + expiresInMs : null;
|
|
3056
|
+
const existing = await this.loadRecord();
|
|
3057
|
+
if (existing) {
|
|
3058
|
+
await this.storeRecord({
|
|
3059
|
+
...existing,
|
|
3060
|
+
idToken,
|
|
3061
|
+
bearerToken,
|
|
3062
|
+
refreshToken,
|
|
3063
|
+
tokenExpiresAt: this._tokenExpiresAt ?? void 0
|
|
3064
|
+
});
|
|
3065
|
+
}
|
|
2991
3066
|
}
|
|
2992
3067
|
async stamp(params) {
|
|
2993
|
-
if (!this.
|
|
3068
|
+
if (!this._keyPair || !this._keyInfo || this._idToken === null) {
|
|
2994
3069
|
throw new Error("Auth2Stamper not initialized. Call init() first.");
|
|
2995
3070
|
}
|
|
2996
3071
|
const signatureRaw = await crypto.subtle.sign(
|
|
2997
3072
|
{ name: "ECDSA", hash: "SHA-256" },
|
|
2998
|
-
this.
|
|
3073
|
+
this._keyPair.privateKey,
|
|
2999
3074
|
new Uint8Array(params.data)
|
|
3000
3075
|
);
|
|
3001
3076
|
const rawPublicKey = bs582.decode(this._keyInfo.publicKey);
|
|
3002
|
-
if (this.idToken === void 0 || this.salt === void 0) {
|
|
3003
|
-
throw new Error("Auth2Stamper not initialized with idToken or salt.");
|
|
3004
|
-
}
|
|
3005
3077
|
const stampData = {
|
|
3006
|
-
kind:
|
|
3007
|
-
idToken: this.
|
|
3078
|
+
kind: this.type,
|
|
3079
|
+
idToken: this._idToken,
|
|
3008
3080
|
publicKey: base64urlEncode(rawPublicKey),
|
|
3009
|
-
algorithm:
|
|
3010
|
-
salt
|
|
3081
|
+
algorithm: this.algorithm,
|
|
3082
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
3083
|
+
salt: "",
|
|
3011
3084
|
signature: base64urlEncode(new Uint8Array(signatureRaw))
|
|
3012
3085
|
};
|
|
3013
3086
|
return base64urlEncode(new TextEncoder().encode(JSON.stringify(stampData)));
|
|
3014
3087
|
}
|
|
3015
3088
|
async resetKeyPair() {
|
|
3016
|
-
await this.
|
|
3017
|
-
this.keyPair = null;
|
|
3018
|
-
this._keyInfo = null;
|
|
3089
|
+
await this.clear();
|
|
3019
3090
|
return this.generateAndStore();
|
|
3020
3091
|
}
|
|
3021
3092
|
async clear() {
|
|
3022
|
-
await this.
|
|
3023
|
-
this.
|
|
3093
|
+
await this.clearStoredRecord();
|
|
3094
|
+
this._keyPair = null;
|
|
3024
3095
|
this._keyInfo = null;
|
|
3096
|
+
this._idToken = null;
|
|
3097
|
+
this._bearerToken = null;
|
|
3098
|
+
this._refreshToken = null;
|
|
3099
|
+
this._tokenExpiresAt = null;
|
|
3025
3100
|
}
|
|
3026
3101
|
// Auth2 doesn't use key rotation; provide minimal no-op implementations.
|
|
3027
3102
|
async rotateKeyPair() {
|
|
@@ -3046,13 +3121,13 @@ var Auth2Stamper = class {
|
|
|
3046
3121
|
const publicKeyBase58 = bs582.encode(rawPublicKey);
|
|
3047
3122
|
const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKey.buffer);
|
|
3048
3123
|
const keyId = base64urlEncode(new Uint8Array(keyIdBuffer)).substring(0, 16);
|
|
3049
|
-
this.
|
|
3124
|
+
this._keyPair = keyPair;
|
|
3050
3125
|
this._keyInfo = {
|
|
3051
3126
|
keyId,
|
|
3052
3127
|
publicKey: publicKeyBase58,
|
|
3053
3128
|
createdAt: Date.now()
|
|
3054
3129
|
};
|
|
3055
|
-
await this.
|
|
3130
|
+
await this.storeRecord({ keyPair, keyInfo: this._keyInfo });
|
|
3056
3131
|
return this._keyInfo;
|
|
3057
3132
|
}
|
|
3058
3133
|
async openDB() {
|
|
@@ -3071,7 +3146,7 @@ var Auth2Stamper = class {
|
|
|
3071
3146
|
};
|
|
3072
3147
|
});
|
|
3073
3148
|
}
|
|
3074
|
-
async
|
|
3149
|
+
async loadRecord() {
|
|
3075
3150
|
return new Promise((resolve, reject) => {
|
|
3076
3151
|
if (!this.db) {
|
|
3077
3152
|
throw new Error("Database not initialized");
|
|
@@ -3085,12 +3160,12 @@ var Auth2Stamper = class {
|
|
|
3085
3160
|
};
|
|
3086
3161
|
});
|
|
3087
3162
|
}
|
|
3088
|
-
async
|
|
3163
|
+
async storeRecord(record) {
|
|
3089
3164
|
return new Promise((resolve, reject) => {
|
|
3090
3165
|
if (!this.db) {
|
|
3091
3166
|
throw new Error("Database not initialized");
|
|
3092
3167
|
}
|
|
3093
|
-
const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).put(
|
|
3168
|
+
const request = this.db.transaction([STORE_NAME], "readwrite").objectStore(STORE_NAME).put(record, ACTIVE_KEY);
|
|
3094
3169
|
request.onsuccess = () => {
|
|
3095
3170
|
resolve();
|
|
3096
3171
|
};
|
|
@@ -3099,7 +3174,7 @@ var Auth2Stamper = class {
|
|
|
3099
3174
|
};
|
|
3100
3175
|
});
|
|
3101
3176
|
}
|
|
3102
|
-
async
|
|
3177
|
+
async clearStoredRecord() {
|
|
3103
3178
|
return new Promise((resolve, reject) => {
|
|
3104
3179
|
if (!this.db) {
|
|
3105
3180
|
throw new Error("Database not initialized");
|
|
@@ -3218,17 +3293,17 @@ var BrowserPhantomAppProvider = class {
|
|
|
3218
3293
|
|
|
3219
3294
|
// src/providers/embedded/adapters/logger.ts
|
|
3220
3295
|
var BrowserLogger = class {
|
|
3221
|
-
info(
|
|
3222
|
-
debug.info(
|
|
3296
|
+
info(message, ...args) {
|
|
3297
|
+
debug.info(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3223
3298
|
}
|
|
3224
|
-
warn(
|
|
3225
|
-
debug.warn(
|
|
3299
|
+
warn(message, ...args) {
|
|
3300
|
+
debug.warn(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3226
3301
|
}
|
|
3227
|
-
error(
|
|
3228
|
-
debug.error(
|
|
3302
|
+
error(message, ...args) {
|
|
3303
|
+
debug.error(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3229
3304
|
}
|
|
3230
|
-
|
|
3231
|
-
debug.log(
|
|
3305
|
+
debug(message, ...args) {
|
|
3306
|
+
debug.log(message, args.length > 0 ? String(args[0]) : "", args[1]);
|
|
3232
3307
|
}
|
|
3233
3308
|
};
|
|
3234
3309
|
|
|
@@ -3239,7 +3314,11 @@ var EmbeddedProvider = class extends CoreEmbeddedProvider {
|
|
|
3239
3314
|
debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
|
|
3240
3315
|
const urlParamsAccessor = new BrowserURLParamsAccessor();
|
|
3241
3316
|
const storage = new BrowserStorage();
|
|
3242
|
-
const stamper = config.unstable__auth2Options ? new Auth2Stamper(`phantom-auth2-${config.appId}
|
|
3317
|
+
const stamper = config.unstable__auth2Options ? new Auth2Stamper(`phantom-auth2-${config.appId}`, {
|
|
3318
|
+
authApiBaseUrl: config.unstable__auth2Options.authApiBaseUrl,
|
|
3319
|
+
clientId: config.unstable__auth2Options.clientId,
|
|
3320
|
+
redirectUri: config.authOptions?.redirectUrl ?? ""
|
|
3321
|
+
}) : new IndexedDbStamper({
|
|
3243
3322
|
dbName: `phantom-embedded-sdk-${config.appId}`,
|
|
3244
3323
|
storeName: "crypto-keys",
|
|
3245
3324
|
keyName: "signing-key"
|
|
@@ -3276,7 +3355,7 @@ var EmbeddedProvider = class extends CoreEmbeddedProvider {
|
|
|
3276
3355
|
[ANALYTICS_HEADERS.CLIENT]: browserName,
|
|
3277
3356
|
[ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
3278
3357
|
[ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
3279
|
-
[ANALYTICS_HEADERS.SDK_VERSION]: "1.0.
|
|
3358
|
+
[ANALYTICS_HEADERS.SDK_VERSION]: "1.0.6"
|
|
3280
3359
|
// Replaced at build time
|
|
3281
3360
|
}
|
|
3282
3361
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/browser-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Browser SDK for Phantom Wallet",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
"prettier": "prettier --write \"src/**/*.{ts,tsx}\""
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@phantom/auth2": "^1.0.
|
|
37
|
-
"@phantom/base64url": "^1.0.
|
|
38
|
-
"@phantom/browser-injected-sdk": "^1.0.
|
|
39
|
-
"@phantom/chain-interfaces": "^1.0.
|
|
40
|
-
"@phantom/client": "^1.0.
|
|
41
|
-
"@phantom/constants": "^1.0.
|
|
42
|
-
"@phantom/embedded-provider-core": "^1.0.
|
|
43
|
-
"@phantom/indexed-db-stamper": "^1.0.
|
|
44
|
-
"@phantom/parsers": "^1.0.
|
|
45
|
-
"@phantom/sdk-types": "^1.0.
|
|
36
|
+
"@phantom/auth2": "^1.0.2",
|
|
37
|
+
"@phantom/base64url": "^1.0.6",
|
|
38
|
+
"@phantom/browser-injected-sdk": "^1.0.6",
|
|
39
|
+
"@phantom/chain-interfaces": "^1.0.6",
|
|
40
|
+
"@phantom/client": "^1.0.6",
|
|
41
|
+
"@phantom/constants": "^1.0.6",
|
|
42
|
+
"@phantom/embedded-provider-core": "^1.0.6",
|
|
43
|
+
"@phantom/indexed-db-stamper": "^1.0.6",
|
|
44
|
+
"@phantom/parsers": "^1.0.6",
|
|
45
|
+
"@phantom/sdk-types": "^1.0.6",
|
|
46
46
|
"axios": "^1.10.0",
|
|
47
47
|
"bs58": "^6.0.0",
|
|
48
48
|
"buffer": "^6.0.3",
|