@phantom/embedded-provider-core 1.0.0-beta.21 → 1.0.0-beta.22
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/README.md +3 -3
- package/dist/index.d.mts +56 -69
- package/dist/index.d.ts +56 -69
- package/dist/index.js +25 -154
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -153
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/index.mjs
CHANGED
|
@@ -13,91 +13,7 @@ import bs582 from "bs58";
|
|
|
13
13
|
// src/constants.ts
|
|
14
14
|
var AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
15
15
|
var AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
16
|
-
|
|
17
|
-
// src/auth/jwt-auth.ts
|
|
18
|
-
var JWTAuth = class {
|
|
19
|
-
async authenticate(options) {
|
|
20
|
-
if (!options.jwtToken || typeof options.jwtToken !== "string") {
|
|
21
|
-
throw new Error("Invalid JWT token: token must be a non-empty string");
|
|
22
|
-
}
|
|
23
|
-
const jwtParts = options.jwtToken.split(".");
|
|
24
|
-
if (jwtParts.length !== 3) {
|
|
25
|
-
throw new Error("Invalid JWT token format: token must have 3 parts separated by dots");
|
|
26
|
-
}
|
|
27
|
-
try {
|
|
28
|
-
const response = await fetch("/api/auth/jwt", {
|
|
29
|
-
method: "POST",
|
|
30
|
-
headers: {
|
|
31
|
-
"Content-Type": "application/json",
|
|
32
|
-
Authorization: `Bearer ${options.jwtToken}`,
|
|
33
|
-
"X-PHANTOM-APPID": options.appId
|
|
34
|
-
},
|
|
35
|
-
body: JSON.stringify({
|
|
36
|
-
appId: options.appId,
|
|
37
|
-
publicKey: options.publicKey
|
|
38
|
-
})
|
|
39
|
-
});
|
|
40
|
-
if (!response.ok) {
|
|
41
|
-
let errorMessage = `HTTP ${response.status}`;
|
|
42
|
-
try {
|
|
43
|
-
const errorData = await response.json();
|
|
44
|
-
errorMessage = errorData.message || errorData.error || errorMessage;
|
|
45
|
-
} catch {
|
|
46
|
-
errorMessage = response.statusText || errorMessage;
|
|
47
|
-
}
|
|
48
|
-
switch (response.status) {
|
|
49
|
-
case 400:
|
|
50
|
-
throw new Error(`Invalid JWT authentication request: ${errorMessage}`);
|
|
51
|
-
case 401:
|
|
52
|
-
throw new Error(`JWT token is invalid or expired: ${errorMessage}`);
|
|
53
|
-
case 403:
|
|
54
|
-
throw new Error(`JWT authentication forbidden: ${errorMessage}`);
|
|
55
|
-
case 404:
|
|
56
|
-
throw new Error(`JWT authentication endpoint not found: ${errorMessage}`);
|
|
57
|
-
case 429:
|
|
58
|
-
throw new Error(`Too many JWT authentication requests: ${errorMessage}`);
|
|
59
|
-
case 500:
|
|
60
|
-
case 502:
|
|
61
|
-
case 503:
|
|
62
|
-
case 504:
|
|
63
|
-
throw new Error(`JWT authentication server error: ${errorMessage}`);
|
|
64
|
-
default:
|
|
65
|
-
throw new Error(`JWT authentication failed: ${errorMessage}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
let result;
|
|
69
|
-
try {
|
|
70
|
-
result = await response.json();
|
|
71
|
-
} catch (parseError) {
|
|
72
|
-
throw new Error("Invalid response from JWT authentication server: response is not valid JSON");
|
|
73
|
-
}
|
|
74
|
-
if (!result.walletId) {
|
|
75
|
-
throw new Error("Invalid JWT authentication response: missing walletId");
|
|
76
|
-
}
|
|
77
|
-
if (!result.organizationId) {
|
|
78
|
-
throw new Error("Invalid JWT authentication response: missing organizationId");
|
|
79
|
-
}
|
|
80
|
-
if (!result.expiresInMs) {
|
|
81
|
-
throw new Error("Invalid JWT authentication response: missing expiresInMs");
|
|
82
|
-
}
|
|
83
|
-
return {
|
|
84
|
-
walletId: result.walletId,
|
|
85
|
-
organizationId: result.organizationId,
|
|
86
|
-
provider: "jwt",
|
|
87
|
-
expiresInMs: result.expiresInMs,
|
|
88
|
-
accountDerivationIndex: result.accountDerivationIndex || 0
|
|
89
|
-
};
|
|
90
|
-
} catch (error) {
|
|
91
|
-
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
92
|
-
throw new Error("JWT authentication failed: network error or invalid endpoint");
|
|
93
|
-
}
|
|
94
|
-
if (error instanceof Error) {
|
|
95
|
-
throw error;
|
|
96
|
-
}
|
|
97
|
-
throw new Error(`JWT authentication error: ${String(error)}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
16
|
+
var EMBEDDED_PROVIDER_AUTH_TYPES = ["google", "apple", "x", "phantom", "tiktok"];
|
|
101
17
|
|
|
102
18
|
// src/chains/SolanaChain.ts
|
|
103
19
|
import { EventEmitter } from "eventemitter3";
|
|
@@ -497,7 +413,6 @@ var EmbeddedProvider = class {
|
|
|
497
413
|
this.phantomAppProvider = platform.phantomAppProvider;
|
|
498
414
|
this.urlParamsAccessor = platform.urlParamsAccessor;
|
|
499
415
|
this.stamper = platform.stamper;
|
|
500
|
-
this.jwtAuth = new JWTAuth();
|
|
501
416
|
this.solana = new EmbeddedSolanaChain(this);
|
|
502
417
|
this.ethereum = new EmbeddedEthereumChain(this);
|
|
503
418
|
this.logger.info("EMBEDDED_PROVIDER", "EmbeddedProvider initialized");
|
|
@@ -638,7 +553,11 @@ var EmbeddedProvider = class {
|
|
|
638
553
|
this.logger.log("EMBEDDED_PROVIDER", "Getting existing session");
|
|
639
554
|
let session = await this.storage.getSession();
|
|
640
555
|
session = await this.validateAndCleanSession(session);
|
|
641
|
-
if (session
|
|
556
|
+
if (!session) {
|
|
557
|
+
this.logger.log("EMBEDDED_PROVIDER", "No existing session found");
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
if (session.status === "completed") {
|
|
642
561
|
this.logger.info("EMBEDDED_PROVIDER", "Using existing completed session", {
|
|
643
562
|
sessionId: session.sessionId,
|
|
644
563
|
walletId: session.walletId
|
|
@@ -655,8 +574,8 @@ var EmbeddedProvider = class {
|
|
|
655
574
|
walletId: this.walletId,
|
|
656
575
|
addresses: this.addresses,
|
|
657
576
|
status: "completed",
|
|
658
|
-
|
|
659
|
-
|
|
577
|
+
authUserId: session.authUserId,
|
|
578
|
+
authProvider: session.authProvider
|
|
660
579
|
};
|
|
661
580
|
this.emit("connect", {
|
|
662
581
|
...result,
|
|
@@ -666,7 +585,7 @@ var EmbeddedProvider = class {
|
|
|
666
585
|
}
|
|
667
586
|
this.logger.log("EMBEDDED_PROVIDER", "No completed session found, checking for redirect resume");
|
|
668
587
|
if (this.authProvider.resumeAuthFromRedirect) {
|
|
669
|
-
const authResult = this.authProvider.resumeAuthFromRedirect();
|
|
588
|
+
const authResult = this.authProvider.resumeAuthFromRedirect(session.authProvider);
|
|
670
589
|
if (authResult) {
|
|
671
590
|
this.logger.info("EMBEDDED_PROVIDER", "Resuming from redirect", {
|
|
672
591
|
walletId: authResult.walletId,
|
|
@@ -698,11 +617,10 @@ var EmbeddedProvider = class {
|
|
|
698
617
|
* This ensures only supported auth providers are used and required tokens are present.
|
|
699
618
|
*/
|
|
700
619
|
validateAuthOptions(authOptions) {
|
|
701
|
-
if (!
|
|
702
|
-
throw new Error(
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
throw new Error("JWT token is required when using JWT authentication");
|
|
620
|
+
if (!EMBEDDED_PROVIDER_AUTH_TYPES.includes(authOptions.provider)) {
|
|
621
|
+
throw new Error(
|
|
622
|
+
`Invalid auth provider: ${authOptions.provider}. Must be "google", "apple", "phantom", "tiktok", or "x"`
|
|
623
|
+
);
|
|
706
624
|
}
|
|
707
625
|
}
|
|
708
626
|
/*
|
|
@@ -842,8 +760,7 @@ var EmbeddedProvider = class {
|
|
|
842
760
|
try {
|
|
843
761
|
this.logger.info("EMBEDDED_PROVIDER", "Starting embedded provider connect", {
|
|
844
762
|
authOptions: {
|
|
845
|
-
provider: authOptions.provider
|
|
846
|
-
hasJwtToken: !!authOptions.jwtToken
|
|
763
|
+
provider: authOptions.provider
|
|
847
764
|
}
|
|
848
765
|
});
|
|
849
766
|
this.emit("connect_start", {
|
|
@@ -873,10 +790,10 @@ var EmbeddedProvider = class {
|
|
|
873
790
|
return {
|
|
874
791
|
addresses: [],
|
|
875
792
|
status: "pending",
|
|
876
|
-
|
|
793
|
+
authProvider: authOptions.provider
|
|
877
794
|
};
|
|
878
795
|
}
|
|
879
|
-
if (
|
|
796
|
+
if (this.config.embeddedWalletType === "app-wallet") {
|
|
880
797
|
session.lastUsed = Date.now();
|
|
881
798
|
await this.storage.saveSession(session);
|
|
882
799
|
}
|
|
@@ -886,8 +803,8 @@ var EmbeddedProvider = class {
|
|
|
886
803
|
walletId: this.walletId,
|
|
887
804
|
addresses: this.addresses,
|
|
888
805
|
status: "completed",
|
|
889
|
-
|
|
890
|
-
|
|
806
|
+
authUserId: session?.authUserId,
|
|
807
|
+
authProvider: session?.authProvider
|
|
891
808
|
};
|
|
892
809
|
this.emit("connect", {
|
|
893
810
|
...result,
|
|
@@ -1112,9 +1029,7 @@ var EmbeddedProvider = class {
|
|
|
1112
1029
|
this.logger.info("EMBEDDED_PROVIDER", "Creating user-wallet, routing authentication", {
|
|
1113
1030
|
authProvider: authOptions.provider
|
|
1114
1031
|
});
|
|
1115
|
-
if (authOptions.provider === "
|
|
1116
|
-
return await this.handleJWTAuth(publicKey, stamperInfo, authOptions, expiresInMs);
|
|
1117
|
-
} else if (authOptions.provider === "phantom") {
|
|
1032
|
+
if (authOptions.provider === "phantom") {
|
|
1118
1033
|
return await this.handlePhantomAuth(publicKey, stamperInfo, expiresInMs);
|
|
1119
1034
|
} else {
|
|
1120
1035
|
this.logger.info("EMBEDDED_PROVIDER", "Starting redirect-based authentication flow", {
|
|
@@ -1147,7 +1062,8 @@ var EmbeddedProvider = class {
|
|
|
1147
1062
|
organizationId,
|
|
1148
1063
|
appId: this.config.appId,
|
|
1149
1064
|
stamperInfo,
|
|
1150
|
-
authProvider: "
|
|
1065
|
+
authProvider: "device",
|
|
1066
|
+
// For now app wallets have no auth provider.
|
|
1151
1067
|
accountDerivationIndex: 0,
|
|
1152
1068
|
// App wallets default to index 0
|
|
1153
1069
|
status: "completed",
|
|
@@ -1162,51 +1078,6 @@ var EmbeddedProvider = class {
|
|
|
1162
1078
|
return session;
|
|
1163
1079
|
}
|
|
1164
1080
|
}
|
|
1165
|
-
/*
|
|
1166
|
-
* We use this method to handle JWT-based authentication for user-wallets.
|
|
1167
|
-
* It authenticates using the provided JWT token and creates a completed session.
|
|
1168
|
-
*/
|
|
1169
|
-
async handleJWTAuth(publicKey, stamperInfo, authOptions, localExpiresInMs) {
|
|
1170
|
-
this.logger.info("EMBEDDED_PROVIDER", "Using JWT authentication flow");
|
|
1171
|
-
if (!authOptions.jwtToken) {
|
|
1172
|
-
this.logger.error("EMBEDDED_PROVIDER", "JWT token missing for JWT authentication");
|
|
1173
|
-
throw new Error("JWT token is required for JWT authentication");
|
|
1174
|
-
}
|
|
1175
|
-
this.logger.log("EMBEDDED_PROVIDER", "Starting JWT authentication");
|
|
1176
|
-
const authResult = await this.jwtAuth.authenticate({
|
|
1177
|
-
publicKey,
|
|
1178
|
-
appId: this.config.appId,
|
|
1179
|
-
jwtToken: authOptions.jwtToken
|
|
1180
|
-
});
|
|
1181
|
-
const walletId = authResult.walletId;
|
|
1182
|
-
const organizationId = authResult.organizationId;
|
|
1183
|
-
const expiresInMs = authResult.expiresInMs > 0 ? authResult.expiresInMs : localExpiresInMs;
|
|
1184
|
-
this.logger.info("EMBEDDED_PROVIDER", "JWT authentication completed", {
|
|
1185
|
-
walletId,
|
|
1186
|
-
organizationId,
|
|
1187
|
-
expiresInMs,
|
|
1188
|
-
source: authResult.expiresInMs ? "server" : "local"
|
|
1189
|
-
});
|
|
1190
|
-
const now = Date.now();
|
|
1191
|
-
const session = {
|
|
1192
|
-
sessionId: generateSessionId(),
|
|
1193
|
-
walletId,
|
|
1194
|
-
organizationId,
|
|
1195
|
-
appId: this.config.appId,
|
|
1196
|
-
stamperInfo,
|
|
1197
|
-
authProvider: authResult.provider,
|
|
1198
|
-
accountDerivationIndex: authResult.accountDerivationIndex,
|
|
1199
|
-
status: "completed",
|
|
1200
|
-
createdAt: now,
|
|
1201
|
-
lastUsed: now,
|
|
1202
|
-
authenticatorCreatedAt: now,
|
|
1203
|
-
authenticatorExpiresAt: Date.now() + expiresInMs,
|
|
1204
|
-
lastRenewalAttempt: void 0
|
|
1205
|
-
};
|
|
1206
|
-
this.logger.log("EMBEDDED_PROVIDER", "Saving JWT session");
|
|
1207
|
-
await this.storage.saveSession(session);
|
|
1208
|
-
return session;
|
|
1209
|
-
}
|
|
1210
1081
|
/*
|
|
1211
1082
|
* We use this method to handle Phantom app-based authentication for user-wallets.
|
|
1212
1083
|
* This method uses the PhantomAppProvider to authenticate via the browser extension or mobile app.
|
|
@@ -1380,8 +1251,8 @@ var EmbeddedProvider = class {
|
|
|
1380
1251
|
walletId: this.walletId,
|
|
1381
1252
|
addresses: this.addresses,
|
|
1382
1253
|
status: "completed",
|
|
1383
|
-
|
|
1384
|
-
|
|
1254
|
+
authUserId: session.authUserId,
|
|
1255
|
+
authProvider: session.authProvider
|
|
1385
1256
|
};
|
|
1386
1257
|
}
|
|
1387
1258
|
/*
|
|
@@ -1440,10 +1311,10 @@ var EmbeddedProvider = class {
|
|
|
1440
1311
|
export {
|
|
1441
1312
|
AUTHENTICATOR_EXPIRATION_TIME_MS,
|
|
1442
1313
|
AUTHENTICATOR_RENEWAL_WINDOW_MS,
|
|
1314
|
+
EMBEDDED_PROVIDER_AUTH_TYPES,
|
|
1443
1315
|
EmbeddedEthereumChain,
|
|
1444
1316
|
EmbeddedProvider,
|
|
1445
1317
|
EmbeddedSolanaChain,
|
|
1446
|
-
JWTAuth,
|
|
1447
1318
|
generateSessionId,
|
|
1448
1319
|
retryWithBackoff
|
|
1449
1320
|
};
|