@phantom/embedded-provider-core 1.0.3 → 1.0.5

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.d.mts CHANGED
@@ -44,8 +44,13 @@ interface EmbeddedProviderConfig {
44
44
  apiBaseUrl: string;
45
45
  appId: string;
46
46
  authOptions: {
47
- authUrl: string;
48
- redirectUrl: string;
47
+ authUrl?: string;
48
+ redirectUrl?: string;
49
+ };
50
+ /** When also provided, the Auth2 PKCE flow is used instead of the legacy Phantom Connect flow. */
51
+ unstable__auth2Options?: {
52
+ authApiBaseUrl: string;
53
+ clientId: string;
49
54
  };
50
55
  embeddedWalletType: "app-wallet" | "user-wallet" | (string & Record<never, never>);
51
56
  addressTypes: AddressType[];
@@ -77,6 +82,9 @@ interface Session {
77
82
  lastRenewalAttempt?: number;
78
83
  accountDerivationIndex?: number;
79
84
  authUserId?: string;
85
+ pkceCodeVerifier?: string;
86
+ salt?: string;
87
+ bearerToken?: string;
80
88
  }
81
89
  interface EmbeddedStorage {
82
90
  getSession(): Promise<Session | null>;
@@ -113,6 +121,7 @@ interface AuthResult {
113
121
  accountDerivationIndex: number;
114
122
  expiresInMs: number;
115
123
  authUserId?: string;
124
+ bearerToken?: string;
116
125
  }
117
126
  interface PhantomConnectOptions {
118
127
  publicKey: string;
@@ -127,7 +136,7 @@ interface PhantomConnectOptions {
127
136
  }
128
137
  interface AuthProvider {
129
138
  authenticate(options: PhantomConnectOptions): Promise<void | AuthResult>;
130
- resumeAuthFromRedirect?(provider: EmbeddedProviderAuthType): AuthResult | null;
139
+ resumeAuthFromRedirect?(provider: EmbeddedProviderAuthType): Promise<AuthResult | null>;
131
140
  }
132
141
  interface PhantomAppAuthOptions {
133
142
  publicKey: string;
@@ -217,6 +226,11 @@ declare class EmbeddedProvider {
217
226
  private createOrganizationForAppWallet;
218
227
  connect(authOptions: AuthOptions): Promise<ConnectResult>;
219
228
  disconnect(shouldClearPreviousSession?: boolean): Promise<void>;
229
+ /**
230
+ * Handles errors from signing operations.
231
+ * Disconnects the user if the server returns a 401/403 (revoked or expired authenticator).
232
+ */
233
+ private handleSigningError;
220
234
  signMessage(params: SignMessageParams): Promise<ParsedSignatureResult>;
221
235
  signEthereumMessage(params: SignMessageParams): Promise<ParsedSignatureResult>;
222
236
  signTypedDataV4(params: SignTypedDataV4Params): Promise<ParsedSignatureResult>;
package/dist/index.d.ts CHANGED
@@ -44,8 +44,13 @@ interface EmbeddedProviderConfig {
44
44
  apiBaseUrl: string;
45
45
  appId: string;
46
46
  authOptions: {
47
- authUrl: string;
48
- redirectUrl: string;
47
+ authUrl?: string;
48
+ redirectUrl?: string;
49
+ };
50
+ /** When also provided, the Auth2 PKCE flow is used instead of the legacy Phantom Connect flow. */
51
+ unstable__auth2Options?: {
52
+ authApiBaseUrl: string;
53
+ clientId: string;
49
54
  };
50
55
  embeddedWalletType: "app-wallet" | "user-wallet" | (string & Record<never, never>);
51
56
  addressTypes: AddressType[];
@@ -77,6 +82,9 @@ interface Session {
77
82
  lastRenewalAttempt?: number;
78
83
  accountDerivationIndex?: number;
79
84
  authUserId?: string;
85
+ pkceCodeVerifier?: string;
86
+ salt?: string;
87
+ bearerToken?: string;
80
88
  }
81
89
  interface EmbeddedStorage {
82
90
  getSession(): Promise<Session | null>;
@@ -113,6 +121,7 @@ interface AuthResult {
113
121
  accountDerivationIndex: number;
114
122
  expiresInMs: number;
115
123
  authUserId?: string;
124
+ bearerToken?: string;
116
125
  }
117
126
  interface PhantomConnectOptions {
118
127
  publicKey: string;
@@ -127,7 +136,7 @@ interface PhantomConnectOptions {
127
136
  }
128
137
  interface AuthProvider {
129
138
  authenticate(options: PhantomConnectOptions): Promise<void | AuthResult>;
130
- resumeAuthFromRedirect?(provider: EmbeddedProviderAuthType): AuthResult | null;
139
+ resumeAuthFromRedirect?(provider: EmbeddedProviderAuthType): Promise<AuthResult | null>;
131
140
  }
132
141
  interface PhantomAppAuthOptions {
133
142
  publicKey: string;
@@ -217,6 +226,11 @@ declare class EmbeddedProvider {
217
226
  private createOrganizationForAppWallet;
218
227
  connect(authOptions: AuthOptions): Promise<ConnectResult>;
219
228
  disconnect(shouldClearPreviousSession?: boolean): Promise<void>;
229
+ /**
230
+ * Handles errors from signing operations.
231
+ * Disconnects the user if the server returns a 401/403 (revoked or expired authenticator).
232
+ */
233
+ private handleSigningError;
220
234
  signMessage(params: SignMessageParams): Promise<ParsedSignatureResult>;
221
235
  signEthereumMessage(params: SignMessageParams): Promise<ParsedSignatureResult>;
222
236
  signTypedDataV4(params: SignTypedDataV4Params): Promise<ParsedSignatureResult>;
package/dist/index.js CHANGED
@@ -527,7 +527,8 @@ var EmbeddedProvider = class {
527
527
  });
528
528
  if (session.status !== "completed") {
529
529
  const urlSessionId = this.urlParamsAccessor.getParam("session_id");
530
- if (session.status === "pending" && !urlSessionId) {
530
+ const urlCode = this.urlParamsAccessor.getParam("code");
531
+ if (session.status === "pending" && !urlSessionId && !urlCode) {
531
532
  this.logger.warn("EMBEDDED_PROVIDER", "Session mismatch detected - pending session without redirect context", {
532
533
  sessionId: session.sessionId,
533
534
  status: session.status
@@ -600,7 +601,7 @@ var EmbeddedProvider = class {
600
601
  }
601
602
  this.logger.log("EMBEDDED_PROVIDER", "No completed session found, checking for redirect resume");
602
603
  if (this.authProvider.resumeAuthFromRedirect) {
603
- const authResult = this.authProvider.resumeAuthFromRedirect(session.authProvider);
604
+ const authResult = await this.authProvider.resumeAuthFromRedirect(session.authProvider);
604
605
  if (authResult) {
605
606
  this.logger.info("EMBEDDED_PROVIDER", "Resuming from redirect", {
606
607
  walletId: authResult.walletId,
@@ -879,6 +880,21 @@ var EmbeddedProvider = class {
879
880
  });
880
881
  }
881
882
  }
883
+ /**
884
+ * Handles errors from signing operations.
885
+ * Disconnects the user if the server returns a 401/403 (revoked or expired authenticator).
886
+ */
887
+ async handleSigningError(error) {
888
+ if ((0, import_client.isAuthenticationError)(error)) {
889
+ this.logger.warn("EMBEDDED_PROVIDER", "Authenticator rejected by server (401/403), disconnecting", { error });
890
+ await this.disconnect(false);
891
+ throw new Error("Authenticator revoked");
892
+ }
893
+ if (error instanceof import_client.SpendingLimitError) {
894
+ this.emit("spending_limit_reached", { error });
895
+ }
896
+ throw error;
897
+ }
882
898
  async signMessage(params) {
883
899
  if (!this.client || !this.walletId) {
884
900
  throw new Error("Not connected");
@@ -895,7 +911,7 @@ var EmbeddedProvider = class {
895
911
  message: params.message,
896
912
  networkId: params.networkId,
897
913
  derivationIndex
898
- });
914
+ }).catch((error) => this.handleSigningError(error));
899
915
  this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
900
916
  walletId: this.walletId,
901
917
  message: params.message
@@ -928,7 +944,7 @@ var EmbeddedProvider = class {
928
944
  message: base64UrlMessage,
929
945
  networkId: params.networkId,
930
946
  derivationIndex
931
- });
947
+ }).catch((error) => this.handleSigningError(error));
932
948
  this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
933
949
  walletId: this.walletId,
934
950
  message: params.message
@@ -951,7 +967,7 @@ var EmbeddedProvider = class {
951
967
  typedData: params.typedData,
952
968
  networkId: params.networkId,
953
969
  derivationIndex
954
- });
970
+ }).catch((error) => this.handleSigningError(error));
955
971
  this.logger.info("EMBEDDED_PROVIDER", "Typed data signed successfully", {
956
972
  walletId: this.walletId
957
973
  });
@@ -988,7 +1004,7 @@ var EmbeddedProvider = class {
988
1004
  networkId: params.networkId,
989
1005
  derivationIndex,
990
1006
  account
991
- });
1007
+ }).catch((error) => this.handleSigningError(error));
992
1008
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed successfully", {
993
1009
  walletId: this.walletId,
994
1010
  networkId: params.networkId,
@@ -1021,21 +1037,13 @@ var EmbeddedProvider = class {
1021
1037
  if (!account) {
1022
1038
  throw new Error(`No address found for network ${params.networkId}`);
1023
1039
  }
1024
- let rawResponse;
1025
- try {
1026
- rawResponse = await this.client.signAndSendTransaction({
1027
- walletId: this.walletId,
1028
- transaction: transactionPayload,
1029
- networkId: params.networkId,
1030
- derivationIndex,
1031
- account
1032
- });
1033
- } catch (error) {
1034
- if (error instanceof import_client.SpendingLimitError) {
1035
- this.emit("spending_limit_reached", { error });
1036
- }
1037
- throw error;
1038
- }
1040
+ const rawResponse = await this.client.signAndSendTransaction({
1041
+ walletId: this.walletId,
1042
+ transaction: transactionPayload,
1043
+ networkId: params.networkId,
1044
+ derivationIndex,
1045
+ account
1046
+ }).catch((error) => this.handleSigningError(error));
1039
1047
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
1040
1048
  walletId: this.walletId,
1041
1049
  networkId: params.networkId,
@@ -1234,6 +1242,7 @@ var EmbeddedProvider = class {
1234
1242
  tempSession.authProvider = authResult.provider || tempSession.authProvider;
1235
1243
  tempSession.accountDerivationIndex = authResult.accountDerivationIndex;
1236
1244
  tempSession.authUserId = authResult.authUserId;
1245
+ tempSession.bearerToken = authResult.bearerToken;
1237
1246
  tempSession.status = "completed";
1238
1247
  tempSession.lastUsed = Date.now();
1239
1248
  if (authResult.expiresInMs > 0) {
@@ -1263,6 +1272,7 @@ var EmbeddedProvider = class {
1263
1272
  session.organizationId = authResult.organizationId;
1264
1273
  session.accountDerivationIndex = authResult.accountDerivationIndex;
1265
1274
  session.authUserId = authResult.authUserId;
1275
+ session.bearerToken = authResult.bearerToken;
1266
1276
  session.status = "completed";
1267
1277
  session.lastUsed = Date.now();
1268
1278
  if (authResult.expiresInMs > 0) {
@@ -1332,7 +1342,8 @@ var EmbeddedProvider = class {
1332
1342
  organizationId: session.organizationId,
1333
1343
  headers: {
1334
1344
  ...this.platform.analyticsHeaders || {},
1335
- ...session.authUserId ? { "x-auth-user-id": session.authUserId } : {}
1345
+ ...session.authUserId ? { "x-auth-user-id": session.authUserId } : {},
1346
+ ...session.bearerToken ? { Authorization: session.bearerToken } : {}
1336
1347
  }
1337
1348
  },
1338
1349
  this.stamper