@phantom/embedded-provider-core 1.0.0-beta.2 → 1.0.0-beta.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/README.md CHANGED
@@ -60,7 +60,6 @@ const config: EmbeddedProviderConfig = {
60
60
  appId: "your-app-id",
61
61
  embeddedWalletType: "user-wallet", // or 'app-wallet'
62
62
  addressTypes: ["solana", "ethereum"],
63
- solanaProvider: "web3js",
64
63
  authOptions: {
65
64
  authUrl: "https://auth.phantom.app",
66
65
  redirectUrl: "https://your-app.com/callback",
@@ -276,7 +275,6 @@ interface EmbeddedProviderConfig {
276
275
  addressTypes: [AddressType, ...AddressType[]]; // Supported blockchain addresses
277
276
 
278
277
  // Optional
279
- solanaProvider?: "web3js" | "kit"; // Solana library preference
280
278
  authOptions?: {
281
279
  authUrl?: string; // Custom auth URL
282
280
  redirectUrl?: string; // OAuth redirect URL
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { StamperWithKeyManagement } from '@phantom/sdk-types';
2
+ import { ClientSideSdkHeaders, NetworkId } from '@phantom/constants';
2
3
  import { AddressType } from '@phantom/client';
3
- import { NetworkId } from '@phantom/constants';
4
4
  import { ParsedSignatureResult, ParsedTransactionResult } from '@phantom/parsers';
5
5
  import { ISolanaChain, IEthereumChain, EthTransactionRequest } from '@phantom/chains';
6
6
 
@@ -92,6 +92,7 @@ interface PlatformAdapter {
92
92
  authProvider: AuthProvider;
93
93
  urlParamsAccessor: URLParamsAccessor;
94
94
  stamper: StamperWithKeyManagement;
95
+ analyticsHeaders?: Partial<ClientSideSdkHeaders>;
95
96
  }
96
97
  interface DebugLogger {
97
98
  info(category: string, message: string, data?: any): void;
@@ -134,13 +135,12 @@ interface EmbeddedProviderConfig {
134
135
  apiBaseUrl: string;
135
136
  appId: string;
136
137
  organizationId: string;
137
- authOptions?: {
138
- authUrl?: string;
139
- redirectUrl?: string;
138
+ authOptions: {
139
+ authUrl: string;
140
+ redirectUrl: string;
140
141
  };
141
142
  embeddedWalletType: "app-wallet" | "user-wallet" | (string & Record<never, never>);
142
143
  addressTypes: [AddressType, ...AddressType[]];
143
- solanaProvider: "web3js" | "kit" | (string & Record<never, never>);
144
144
  }
145
145
 
146
146
  type EmbeddedProviderEvent = "connect" | "connect_start" | "connect_error" | "disconnect" | "error";
@@ -217,6 +217,9 @@ declare class EmbeddedSolanaChain implements ISolanaChain {
217
217
  signature: string;
218
218
  }>;
219
219
  signAllTransactions<T>(transactions: T[]): Promise<T[]>;
220
+ signAndSendAllTransactions<T>(transactions: T[]): Promise<{
221
+ signatures: string[];
222
+ }>;
220
223
  connect(_options?: {
221
224
  onlyIfTrusted?: boolean;
222
225
  }): Promise<{
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { StamperWithKeyManagement } from '@phantom/sdk-types';
2
+ import { ClientSideSdkHeaders, NetworkId } from '@phantom/constants';
2
3
  import { AddressType } from '@phantom/client';
3
- import { NetworkId } from '@phantom/constants';
4
4
  import { ParsedSignatureResult, ParsedTransactionResult } from '@phantom/parsers';
5
5
  import { ISolanaChain, IEthereumChain, EthTransactionRequest } from '@phantom/chains';
6
6
 
@@ -92,6 +92,7 @@ interface PlatformAdapter {
92
92
  authProvider: AuthProvider;
93
93
  urlParamsAccessor: URLParamsAccessor;
94
94
  stamper: StamperWithKeyManagement;
95
+ analyticsHeaders?: Partial<ClientSideSdkHeaders>;
95
96
  }
96
97
  interface DebugLogger {
97
98
  info(category: string, message: string, data?: any): void;
@@ -134,13 +135,12 @@ interface EmbeddedProviderConfig {
134
135
  apiBaseUrl: string;
135
136
  appId: string;
136
137
  organizationId: string;
137
- authOptions?: {
138
- authUrl?: string;
139
- redirectUrl?: string;
138
+ authOptions: {
139
+ authUrl: string;
140
+ redirectUrl: string;
140
141
  };
141
142
  embeddedWalletType: "app-wallet" | "user-wallet" | (string & Record<never, never>);
142
143
  addressTypes: [AddressType, ...AddressType[]];
143
- solanaProvider: "web3js" | "kit" | (string & Record<never, never>);
144
144
  }
145
145
 
146
146
  type EmbeddedProviderEvent = "connect" | "connect_start" | "connect_error" | "disconnect" | "error";
@@ -217,6 +217,9 @@ declare class EmbeddedSolanaChain implements ISolanaChain {
217
217
  signature: string;
218
218
  }>;
219
219
  signAllTransactions<T>(transactions: T[]): Promise<T[]>;
220
+ signAndSendAllTransactions<T>(transactions: T[]): Promise<{
221
+ signatures: string[];
222
+ }>;
220
223
  connect(_options?: {
221
224
  onlyIfTrusted?: boolean;
222
225
  }): Promise<{
package/dist/index.js CHANGED
@@ -233,6 +233,10 @@ var EmbeddedSolanaChain = class {
233
233
  const results = await Promise.all(transactions.map((tx) => this.signTransaction(tx)));
234
234
  return results;
235
235
  }
236
+ async signAndSendAllTransactions(transactions) {
237
+ const results = await Promise.all(transactions.map((tx) => this.signAndSendTransaction(tx)));
238
+ return { signatures: results.map((result) => result.signature) };
239
+ }
236
240
  connect(_options) {
237
241
  if (!this.provider.isConnected()) {
238
242
  throw new Error("Provider not connected. Call provider connect first.");
@@ -504,6 +508,9 @@ var EmbeddedProvider = class {
504
508
  this.eventListeners = /* @__PURE__ */ new Map();
505
509
  this.logger = logger;
506
510
  this.logger.log("EMBEDDED_PROVIDER", "Initializing EmbeddedProvider", { config });
511
+ if (config.embeddedWalletType === "app-wallet") {
512
+ throw new Error("app-wallet type is not currently supported. Please use 'user-wallet' instead.");
513
+ }
507
514
  this.config = config;
508
515
  this.platform = platform;
509
516
  this.storage = platform.storage;
@@ -511,7 +518,6 @@ var EmbeddedProvider = class {
511
518
  this.urlParamsAccessor = platform.urlParamsAccessor;
512
519
  this.stamper = platform.stamper;
513
520
  this.jwtAuth = new JWTAuth();
514
- config.solanaProvider;
515
521
  this.solana = new EmbeddedSolanaChain(this);
516
522
  this.ethereum = new EmbeddedEthereumChain(this);
517
523
  this.logger.info("EMBEDDED_PROVIDER", "EmbeddedProvider initialized");
@@ -778,7 +784,10 @@ var EmbeddedProvider = class {
778
784
  this.logger.log("EMBEDDED_PROVIDER", "Creating temporary PhantomClient");
779
785
  const tempClient = new import_client.PhantomClient(
780
786
  {
781
- apiBaseUrl: this.config.apiBaseUrl
787
+ apiBaseUrl: this.config.apiBaseUrl,
788
+ headers: {
789
+ ...this.platform.analyticsHeaders || {}
790
+ }
782
791
  },
783
792
  this.stamper
784
793
  );
@@ -791,7 +800,7 @@ var EmbeddedProvider = class {
791
800
  platform: platformName
792
801
  });
793
802
  const base64urlPublicKey = (0, import_base64url2.base64urlEncode)(import_bs582.default.decode(stamperInfo.publicKey));
794
- const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;
803
+ const expiresInMs = AUTHENTICATOR_EXPIRATION_TIME_MS;
795
804
  const username = `user-${shortPubKey}`;
796
805
  const { organizationId } = await tempClient.createOrganization(organizationName, [
797
806
  {
@@ -804,13 +813,13 @@ var EmbeddedProvider = class {
804
813
  publicKey: base64urlPublicKey,
805
814
  algorithm: "Ed25519"
806
815
  // Commented for now until KMS supports fully expirable organizations
807
- // expiresAtMs: expiresAtMs,
816
+ // expiresInMs: expiresInMs,
808
817
  }
809
818
  ]
810
819
  }
811
820
  ]);
812
821
  this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId });
813
- return { organizationId, stamperInfo, expiresAtMs, username };
822
+ return { organizationId, stamperInfo, expiresInMs, username };
814
823
  }
815
824
  async connect(authOptions) {
816
825
  try {
@@ -839,8 +848,8 @@ var EmbeddedProvider = class {
839
848
  }
840
849
  this.validateAuthOptions(authOptions);
841
850
  this.logger.info("EMBEDDED_PROVIDER", "No existing connection, creating new auth flow");
842
- const { organizationId, stamperInfo, expiresAtMs, username } = await this.createOrganizationAndStamper();
843
- const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username);
851
+ const { organizationId, stamperInfo, expiresInMs, username } = await this.createOrganizationAndStamper();
852
+ const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresInMs, username);
844
853
  if (!session) {
845
854
  return {
846
855
  addresses: [],
@@ -1010,13 +1019,13 @@ var EmbeddedProvider = class {
1010
1019
  * It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.
1011
1020
  * Returns null for redirect flows since they don't complete synchronously.
1012
1021
  */
1013
- async handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username) {
1022
+ async handleAuthFlow(organizationId, stamperInfo, authOptions, expiresInMs, username) {
1014
1023
  if (this.config.embeddedWalletType === "user-wallet") {
1015
1024
  this.logger.info("EMBEDDED_PROVIDER", "Creating user-wallet, routing authentication", {
1016
1025
  authProvider: authOptions?.provider || "phantom-connect"
1017
1026
  });
1018
1027
  if (authOptions?.provider === "jwt") {
1019
- return await this.handleJWTAuth(organizationId, stamperInfo, authOptions, expiresAtMs, username);
1028
+ return await this.handleJWTAuth(organizationId, stamperInfo, authOptions, expiresInMs, username);
1020
1029
  } else {
1021
1030
  this.logger.info("EMBEDDED_PROVIDER", "Starting redirect-based authentication flow", {
1022
1031
  organizationId,
@@ -1032,7 +1041,10 @@ var EmbeddedProvider = class {
1032
1041
  const tempClient = new import_client.PhantomClient(
1033
1042
  {
1034
1043
  apiBaseUrl: this.config.apiBaseUrl,
1035
- organizationId
1044
+ organizationId,
1045
+ headers: {
1046
+ ...this.platform.analyticsHeaders || {}
1047
+ }
1036
1048
  },
1037
1049
  this.stamper
1038
1050
  );
@@ -1053,7 +1065,7 @@ var EmbeddedProvider = class {
1053
1065
  createdAt: now,
1054
1066
  lastUsed: now,
1055
1067
  authenticatorCreatedAt: now,
1056
- authenticatorExpiresAt: expiresAtMs,
1068
+ authenticatorExpiresAt: Date.now() + expiresInMs,
1057
1069
  lastRenewalAttempt: void 0,
1058
1070
  username
1059
1071
  };
@@ -1066,7 +1078,7 @@ var EmbeddedProvider = class {
1066
1078
  * We use this method to handle JWT-based authentication for user-wallets.
1067
1079
  * It authenticates using the provided JWT token and creates a completed session.
1068
1080
  */
1069
- async handleJWTAuth(organizationId, stamperInfo, authOptions, expiresAtMs, username) {
1081
+ async handleJWTAuth(organizationId, stamperInfo, authOptions, expiresInMs, username) {
1070
1082
  this.logger.info("EMBEDDED_PROVIDER", "Using JWT authentication flow");
1071
1083
  if (!authOptions.jwtToken) {
1072
1084
  this.logger.error("EMBEDDED_PROVIDER", "JWT token missing for JWT authentication");
@@ -1096,7 +1108,7 @@ var EmbeddedProvider = class {
1096
1108
  createdAt: now,
1097
1109
  lastUsed: now,
1098
1110
  authenticatorCreatedAt: now,
1099
- authenticatorExpiresAt: expiresAtMs,
1111
+ authenticatorExpiresAt: Date.now() + expiresInMs,
1100
1112
  lastRenewalAttempt: void 0,
1101
1113
  username
1102
1114
  };
@@ -1112,8 +1124,8 @@ var EmbeddedProvider = class {
1112
1124
  async handleRedirectAuth(organizationId, stamperInfo, authOptions, username) {
1113
1125
  this.logger.info("EMBEDDED_PROVIDER", "Using Phantom Connect authentication flow (redirect-based)", {
1114
1126
  provider: authOptions?.provider,
1115
- hasRedirectUrl: !!this.config.authOptions?.redirectUrl,
1116
- authUrl: this.config.authOptions?.authUrl
1127
+ hasRedirectUrl: !!this.config.authOptions.redirectUrl,
1128
+ authUrl: this.config.authOptions.authUrl
1117
1129
  });
1118
1130
  const now = Date.now();
1119
1131
  const sessionId = generateSessionId();
@@ -1147,16 +1159,16 @@ var EmbeddedProvider = class {
1147
1159
  parentOrganizationId: this.config.organizationId,
1148
1160
  appId: this.config.appId,
1149
1161
  provider: authOptions?.provider,
1150
- authUrl: this.config.authOptions?.authUrl
1162
+ authUrl: this.config.authOptions.authUrl
1151
1163
  });
1152
1164
  const authResult = await this.authProvider.authenticate({
1153
1165
  organizationId,
1154
1166
  appId: this.config.appId,
1155
1167
  parentOrganizationId: this.config.organizationId,
1156
1168
  provider: authOptions?.provider,
1157
- redirectUrl: this.config.authOptions?.redirectUrl,
1169
+ redirectUrl: this.config.authOptions.redirectUrl,
1158
1170
  customAuthData: authOptions?.customAuthData,
1159
- authUrl: this.config.authOptions?.authUrl,
1171
+ authUrl: this.config.authOptions.authUrl,
1160
1172
  sessionId
1161
1173
  });
1162
1174
  if (authResult && "walletId" in authResult) {
@@ -1252,7 +1264,7 @@ var EmbeddedProvider = class {
1252
1264
  newPublicKey: newKeyInfo.publicKey
1253
1265
  });
1254
1266
  const base64urlPublicKey = (0, import_base64url2.base64urlEncode)(import_bs582.default.decode(newKeyInfo.publicKey));
1255
- const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;
1267
+ const expiresInMs = AUTHENTICATOR_EXPIRATION_TIME_MS;
1256
1268
  let authenticatorResult;
1257
1269
  try {
1258
1270
  authenticatorResult = await this.client.createAuthenticator({
@@ -1265,7 +1277,7 @@ var EmbeddedProvider = class {
1265
1277
  publicKey: base64urlPublicKey,
1266
1278
  algorithm: "Ed25519"
1267
1279
  // Commented for now until KMS supports fully expiring organizations
1268
- // expiresAtMs: expiresAtMs,
1280
+ // expiresInMs: expiresInMs,
1269
1281
  },
1270
1282
  replaceExpirable: true
1271
1283
  });
@@ -1285,12 +1297,12 @@ var EmbeddedProvider = class {
1285
1297
  const now = Date.now();
1286
1298
  session.stamperInfo = newKeyInfo;
1287
1299
  session.authenticatorCreatedAt = now;
1288
- session.authenticatorExpiresAt = expiresAtMs;
1300
+ session.authenticatorExpiresAt = Date.now() + expiresInMs;
1289
1301
  session.lastRenewalAttempt = now;
1290
1302
  await this.storage.saveSession(session);
1291
1303
  this.logger.info("EMBEDDED_PROVIDER", "Authenticator renewal completed successfully", {
1292
1304
  newKeyId: newKeyInfo.keyId,
1293
- expiresAt: new Date(expiresAtMs).toISOString()
1305
+ expiresAt: new Date(Date.now() + expiresInMs).toISOString()
1294
1306
  });
1295
1307
  } catch (error) {
1296
1308
  await this.stamper.rollbackRotation();
@@ -1313,7 +1325,10 @@ var EmbeddedProvider = class {
1313
1325
  this.client = new import_client.PhantomClient(
1314
1326
  {
1315
1327
  apiBaseUrl: this.config.apiBaseUrl,
1316
- organizationId: session.organizationId
1328
+ organizationId: session.organizationId,
1329
+ headers: {
1330
+ ...this.platform.analyticsHeaders || {}
1331
+ }
1317
1332
  },
1318
1333
  this.stamper
1319
1334
  );