@phantom/embedded-provider-core 1.0.0-beta.2 → 1.0.0-beta.4

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.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/embedded-provider.ts
2
2
  import { PhantomClient } from "@phantom/client";
3
+ import { randomUUID } from "@phantom/utils";
3
4
  import { base64urlEncode } from "@phantom/base64url";
4
5
  import bs582 from "bs58";
5
6
  import {
@@ -134,7 +135,7 @@ async function retryWithBackoff(operation, operationName, logger, maxRetries = 3
134
135
  import { EventEmitter } from "eventemitter3";
135
136
  import { NetworkId } from "@phantom/constants";
136
137
  import bs58 from "bs58";
137
- import { parseSolanaTransactionSignature } from "@phantom/parsers";
138
+ import { parseSolanaSignedTransaction } from "@phantom/parsers";
138
139
  var EmbeddedSolanaChain = class {
139
140
  constructor(provider) {
140
141
  this.provider = provider;
@@ -177,8 +178,12 @@ var EmbeddedSolanaChain = class {
177
178
  transaction,
178
179
  networkId: this.currentNetworkId
179
180
  });
180
- const signatureResult = parseSolanaTransactionSignature(result.rawTransaction);
181
- return signatureResult.signature;
181
+ const signedResult = parseSolanaSignedTransaction(result.rawTransaction);
182
+ if (signedResult.transaction && !signedResult.fallback) {
183
+ return signedResult.transaction;
184
+ } else {
185
+ throw new Error("Failed to parse signed transaction");
186
+ }
182
187
  }
183
188
  async signAndSendTransaction(transaction) {
184
189
  this.ensureConnected();
@@ -195,6 +200,10 @@ var EmbeddedSolanaChain = class {
195
200
  const results = await Promise.all(transactions.map((tx) => this.signTransaction(tx)));
196
201
  return results;
197
202
  }
203
+ async signAndSendAllTransactions(transactions) {
204
+ const results = await Promise.all(transactions.map((tx) => this.signAndSendTransaction(tx)));
205
+ return { signatures: results.map((result) => result.signature) };
206
+ }
198
207
  connect(_options) {
199
208
  if (!this.provider.isConnected()) {
200
209
  throw new Error("Provider not connected. Call provider connect first.");
@@ -466,6 +475,9 @@ var EmbeddedProvider = class {
466
475
  this.eventListeners = /* @__PURE__ */ new Map();
467
476
  this.logger = logger;
468
477
  this.logger.log("EMBEDDED_PROVIDER", "Initializing EmbeddedProvider", { config });
478
+ if (config.embeddedWalletType === "app-wallet") {
479
+ throw new Error("app-wallet type is not currently supported. Please use 'user-wallet' instead.");
480
+ }
469
481
  this.config = config;
470
482
  this.platform = platform;
471
483
  this.storage = platform.storage;
@@ -473,7 +485,6 @@ var EmbeddedProvider = class {
473
485
  this.urlParamsAccessor = platform.urlParamsAccessor;
474
486
  this.stamper = platform.stamper;
475
487
  this.jwtAuth = new JWTAuth();
476
- config.solanaProvider;
477
488
  this.solana = new EmbeddedSolanaChain(this);
478
489
  this.ethereum = new EmbeddedEthereumChain(this);
479
490
  this.logger.info("EMBEDDED_PROVIDER", "EmbeddedProvider initialized");
@@ -740,21 +751,24 @@ var EmbeddedProvider = class {
740
751
  this.logger.log("EMBEDDED_PROVIDER", "Creating temporary PhantomClient");
741
752
  const tempClient = new PhantomClient(
742
753
  {
743
- apiBaseUrl: this.config.apiBaseUrl
754
+ apiBaseUrl: this.config.apiBaseUrl,
755
+ headers: {
756
+ ...this.platform.analyticsHeaders || {}
757
+ }
744
758
  },
745
759
  this.stamper
746
760
  );
747
761
  const platformName = this.platform.name || "unknown";
748
762
  const shortPubKey = stamperInfo.publicKey.slice(0, 8);
749
- const organizationName = `${this.config.organizationId}-${platformName}-${shortPubKey}`;
763
+ const organizationName = `${this.config.organizationId.substring(0, 8)}-${platformName}-${shortPubKey}`;
750
764
  this.logger.log("EMBEDDED_PROVIDER", "Creating organization", {
751
765
  organizationName,
752
766
  publicKey: stamperInfo.publicKey,
753
767
  platform: platformName
754
768
  });
755
769
  const base64urlPublicKey = base64urlEncode(bs582.decode(stamperInfo.publicKey));
756
- const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;
757
- const username = `user-${shortPubKey}`;
770
+ const expiresInMs = AUTHENTICATOR_EXPIRATION_TIME_MS;
771
+ const username = `user-${randomUUID()}`;
758
772
  const { organizationId } = await tempClient.createOrganization(organizationName, [
759
773
  {
760
774
  username,
@@ -766,13 +780,13 @@ var EmbeddedProvider = class {
766
780
  publicKey: base64urlPublicKey,
767
781
  algorithm: "Ed25519"
768
782
  // Commented for now until KMS supports fully expirable organizations
769
- // expiresAtMs: expiresAtMs,
783
+ // expiresInMs: expiresInMs,
770
784
  }
771
785
  ]
772
786
  }
773
787
  ]);
774
788
  this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId });
775
- return { organizationId, stamperInfo, expiresAtMs, username };
789
+ return { organizationId, stamperInfo, expiresInMs, username };
776
790
  }
777
791
  async connect(authOptions) {
778
792
  try {
@@ -801,8 +815,8 @@ var EmbeddedProvider = class {
801
815
  }
802
816
  this.validateAuthOptions(authOptions);
803
817
  this.logger.info("EMBEDDED_PROVIDER", "No existing connection, creating new auth flow");
804
- const { organizationId, stamperInfo, expiresAtMs, username } = await this.createOrganizationAndStamper();
805
- const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username);
818
+ const { organizationId, stamperInfo, expiresInMs, username } = await this.createOrganizationAndStamper();
819
+ const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresInMs, username);
806
820
  if (!session) {
807
821
  return {
808
822
  addresses: [],
@@ -972,13 +986,13 @@ var EmbeddedProvider = class {
972
986
  * It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.
973
987
  * Returns null for redirect flows since they don't complete synchronously.
974
988
  */
975
- async handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username) {
989
+ async handleAuthFlow(organizationId, stamperInfo, authOptions, expiresInMs, username) {
976
990
  if (this.config.embeddedWalletType === "user-wallet") {
977
991
  this.logger.info("EMBEDDED_PROVIDER", "Creating user-wallet, routing authentication", {
978
992
  authProvider: authOptions?.provider || "phantom-connect"
979
993
  });
980
994
  if (authOptions?.provider === "jwt") {
981
- return await this.handleJWTAuth(organizationId, stamperInfo, authOptions, expiresAtMs, username);
995
+ return await this.handleJWTAuth(organizationId, stamperInfo, authOptions, expiresInMs, username);
982
996
  } else {
983
997
  this.logger.info("EMBEDDED_PROVIDER", "Starting redirect-based authentication flow", {
984
998
  organizationId,
@@ -994,7 +1008,10 @@ var EmbeddedProvider = class {
994
1008
  const tempClient = new PhantomClient(
995
1009
  {
996
1010
  apiBaseUrl: this.config.apiBaseUrl,
997
- organizationId
1011
+ organizationId,
1012
+ headers: {
1013
+ ...this.platform.analyticsHeaders || {}
1014
+ }
998
1015
  },
999
1016
  this.stamper
1000
1017
  );
@@ -1015,7 +1032,7 @@ var EmbeddedProvider = class {
1015
1032
  createdAt: now,
1016
1033
  lastUsed: now,
1017
1034
  authenticatorCreatedAt: now,
1018
- authenticatorExpiresAt: expiresAtMs,
1035
+ authenticatorExpiresAt: Date.now() + expiresInMs,
1019
1036
  lastRenewalAttempt: void 0,
1020
1037
  username
1021
1038
  };
@@ -1028,7 +1045,7 @@ var EmbeddedProvider = class {
1028
1045
  * We use this method to handle JWT-based authentication for user-wallets.
1029
1046
  * It authenticates using the provided JWT token and creates a completed session.
1030
1047
  */
1031
- async handleJWTAuth(organizationId, stamperInfo, authOptions, expiresAtMs, username) {
1048
+ async handleJWTAuth(organizationId, stamperInfo, authOptions, expiresInMs, username) {
1032
1049
  this.logger.info("EMBEDDED_PROVIDER", "Using JWT authentication flow");
1033
1050
  if (!authOptions.jwtToken) {
1034
1051
  this.logger.error("EMBEDDED_PROVIDER", "JWT token missing for JWT authentication");
@@ -1058,7 +1075,7 @@ var EmbeddedProvider = class {
1058
1075
  createdAt: now,
1059
1076
  lastUsed: now,
1060
1077
  authenticatorCreatedAt: now,
1061
- authenticatorExpiresAt: expiresAtMs,
1078
+ authenticatorExpiresAt: Date.now() + expiresInMs,
1062
1079
  lastRenewalAttempt: void 0,
1063
1080
  username
1064
1081
  };
@@ -1074,8 +1091,8 @@ var EmbeddedProvider = class {
1074
1091
  async handleRedirectAuth(organizationId, stamperInfo, authOptions, username) {
1075
1092
  this.logger.info("EMBEDDED_PROVIDER", "Using Phantom Connect authentication flow (redirect-based)", {
1076
1093
  provider: authOptions?.provider,
1077
- hasRedirectUrl: !!this.config.authOptions?.redirectUrl,
1078
- authUrl: this.config.authOptions?.authUrl
1094
+ hasRedirectUrl: !!this.config.authOptions.redirectUrl,
1095
+ authUrl: this.config.authOptions.authUrl
1079
1096
  });
1080
1097
  const now = Date.now();
1081
1098
  const sessionId = generateSessionId();
@@ -1096,7 +1113,7 @@ var EmbeddedProvider = class {
1096
1113
  authenticatorCreatedAt: now,
1097
1114
  authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,
1098
1115
  lastRenewalAttempt: void 0,
1099
- username: username || `user-${stamperInfo.keyId.substring(0, 8)}`
1116
+ username: username || `user-${randomUUID()}`
1100
1117
  };
1101
1118
  this.logger.log("EMBEDDED_PROVIDER", "Saving temporary session before redirect", {
1102
1119
  sessionId: tempSession.sessionId,
@@ -1109,16 +1126,16 @@ var EmbeddedProvider = class {
1109
1126
  parentOrganizationId: this.config.organizationId,
1110
1127
  appId: this.config.appId,
1111
1128
  provider: authOptions?.provider,
1112
- authUrl: this.config.authOptions?.authUrl
1129
+ authUrl: this.config.authOptions.authUrl
1113
1130
  });
1114
1131
  const authResult = await this.authProvider.authenticate({
1115
1132
  organizationId,
1116
1133
  appId: this.config.appId,
1117
1134
  parentOrganizationId: this.config.organizationId,
1118
1135
  provider: authOptions?.provider,
1119
- redirectUrl: this.config.authOptions?.redirectUrl,
1136
+ redirectUrl: this.config.authOptions.redirectUrl,
1120
1137
  customAuthData: authOptions?.customAuthData,
1121
- authUrl: this.config.authOptions?.authUrl,
1138
+ authUrl: this.config.authOptions.authUrl,
1122
1139
  sessionId
1123
1140
  });
1124
1141
  if (authResult && "walletId" in authResult) {
@@ -1214,7 +1231,7 @@ var EmbeddedProvider = class {
1214
1231
  newPublicKey: newKeyInfo.publicKey
1215
1232
  });
1216
1233
  const base64urlPublicKey = base64urlEncode(bs582.decode(newKeyInfo.publicKey));
1217
- const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;
1234
+ const expiresInMs = AUTHENTICATOR_EXPIRATION_TIME_MS;
1218
1235
  let authenticatorResult;
1219
1236
  try {
1220
1237
  authenticatorResult = await this.client.createAuthenticator({
@@ -1227,7 +1244,7 @@ var EmbeddedProvider = class {
1227
1244
  publicKey: base64urlPublicKey,
1228
1245
  algorithm: "Ed25519"
1229
1246
  // Commented for now until KMS supports fully expiring organizations
1230
- // expiresAtMs: expiresAtMs,
1247
+ // expiresInMs: expiresInMs,
1231
1248
  },
1232
1249
  replaceExpirable: true
1233
1250
  });
@@ -1247,12 +1264,12 @@ var EmbeddedProvider = class {
1247
1264
  const now = Date.now();
1248
1265
  session.stamperInfo = newKeyInfo;
1249
1266
  session.authenticatorCreatedAt = now;
1250
- session.authenticatorExpiresAt = expiresAtMs;
1267
+ session.authenticatorExpiresAt = Date.now() + expiresInMs;
1251
1268
  session.lastRenewalAttempt = now;
1252
1269
  await this.storage.saveSession(session);
1253
1270
  this.logger.info("EMBEDDED_PROVIDER", "Authenticator renewal completed successfully", {
1254
1271
  newKeyId: newKeyInfo.keyId,
1255
- expiresAt: new Date(expiresAtMs).toISOString()
1272
+ expiresAt: new Date(Date.now() + expiresInMs).toISOString()
1256
1273
  });
1257
1274
  } catch (error) {
1258
1275
  await this.stamper.rollbackRotation();
@@ -1275,7 +1292,10 @@ var EmbeddedProvider = class {
1275
1292
  this.client = new PhantomClient(
1276
1293
  {
1277
1294
  apiBaseUrl: this.config.apiBaseUrl,
1278
- organizationId: session.organizationId
1295
+ organizationId: session.organizationId,
1296
+ headers: {
1297
+ ...this.platform.analyticsHeaders || {}
1298
+ }
1279
1299
  },
1280
1300
  this.stamper
1281
1301
  );