@phantom/embedded-provider-core 1.0.0-beta.9 → 1.0.0

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 CHANGED
@@ -32,146 +32,33 @@ var src_exports = {};
32
32
  __export(src_exports, {
33
33
  AUTHENTICATOR_EXPIRATION_TIME_MS: () => AUTHENTICATOR_EXPIRATION_TIME_MS,
34
34
  AUTHENTICATOR_RENEWAL_WINDOW_MS: () => AUTHENTICATOR_RENEWAL_WINDOW_MS,
35
+ EMBEDDED_PROVIDER_AUTH_TYPES: () => EMBEDDED_PROVIDER_AUTH_TYPES,
35
36
  EmbeddedEthereumChain: () => EmbeddedEthereumChain,
36
37
  EmbeddedProvider: () => EmbeddedProvider,
37
38
  EmbeddedSolanaChain: () => EmbeddedSolanaChain,
38
- JWTAuth: () => JWTAuth,
39
39
  generateSessionId: () => generateSessionId,
40
40
  retryWithBackoff: () => retryWithBackoff
41
41
  });
42
42
  module.exports = __toCommonJS(src_exports);
43
43
 
44
44
  // src/embedded-provider.ts
45
+ var import_base64url = require("@phantom/base64url");
45
46
  var import_client = require("@phantom/client");
47
+ var import_parsers2 = require("@phantom/parsers");
46
48
  var import_utils = require("@phantom/utils");
47
- var import_base64url2 = require("@phantom/base64url");
49
+ var import_buffer = require("buffer");
48
50
  var import_bs582 = __toESM(require("bs58"));
49
- var import_parsers = require("@phantom/parsers");
50
51
 
51
52
  // src/constants.ts
52
53
  var AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1e3;
53
54
  var AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
54
-
55
- // src/auth/jwt-auth.ts
56
- var JWTAuth = class {
57
- async authenticate(options) {
58
- if (!options.jwtToken || typeof options.jwtToken !== "string") {
59
- throw new Error("Invalid JWT token: token must be a non-empty string");
60
- }
61
- const jwtParts = options.jwtToken.split(".");
62
- if (jwtParts.length !== 3) {
63
- throw new Error("Invalid JWT token format: token must have 3 parts separated by dots");
64
- }
65
- try {
66
- const response = await fetch("/api/auth/jwt", {
67
- method: "POST",
68
- headers: {
69
- "Content-Type": "application/json",
70
- Authorization: `Bearer ${options.jwtToken}`,
71
- "X-PHANTOM-APPID": options.appId
72
- },
73
- body: JSON.stringify({
74
- appId: options.appId,
75
- customAuthData: options.customAuthData
76
- })
77
- });
78
- if (!response.ok) {
79
- let errorMessage = `HTTP ${response.status}`;
80
- try {
81
- const errorData = await response.json();
82
- errorMessage = errorData.message || errorData.error || errorMessage;
83
- } catch {
84
- errorMessage = response.statusText || errorMessage;
85
- }
86
- switch (response.status) {
87
- case 400:
88
- throw new Error(`Invalid JWT authentication request: ${errorMessage}`);
89
- case 401:
90
- throw new Error(`JWT token is invalid or expired: ${errorMessage}`);
91
- case 403:
92
- throw new Error(`JWT authentication forbidden: ${errorMessage}`);
93
- case 404:
94
- throw new Error(`JWT authentication endpoint not found: ${errorMessage}`);
95
- case 429:
96
- throw new Error(`Too many JWT authentication requests: ${errorMessage}`);
97
- case 500:
98
- case 502:
99
- case 503:
100
- case 504:
101
- throw new Error(`JWT authentication server error: ${errorMessage}`);
102
- default:
103
- throw new Error(`JWT authentication failed: ${errorMessage}`);
104
- }
105
- }
106
- let result;
107
- try {
108
- result = await response.json();
109
- } catch (parseError) {
110
- throw new Error("Invalid response from JWT authentication server: response is not valid JSON");
111
- }
112
- if (!result.walletId) {
113
- throw new Error("Invalid JWT authentication response: missing walletId");
114
- }
115
- return {
116
- walletId: result.walletId,
117
- provider: "jwt",
118
- userInfo: result.userInfo || {}
119
- };
120
- } catch (error) {
121
- if (error instanceof TypeError && error.message.includes("fetch")) {
122
- throw new Error("JWT authentication failed: network error or invalid endpoint");
123
- }
124
- if (error instanceof Error) {
125
- throw error;
126
- }
127
- throw new Error(`JWT authentication error: ${String(error)}`);
128
- }
129
- }
130
- };
131
-
132
- // src/utils/session.ts
133
- function generateSessionId() {
134
- return "session_" + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + "_" + Date.now();
135
- }
136
-
137
- // src/utils/retry.ts
138
- async function retryWithBackoff(operation, operationName, logger, maxRetries = 3, baseDelay = 1e3) {
139
- let lastError;
140
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
141
- try {
142
- logger.log("EMBEDDED_PROVIDER", `Attempting ${operationName}`, {
143
- attempt,
144
- maxRetries
145
- });
146
- return await operation();
147
- } catch (error) {
148
- lastError = error;
149
- logger.warn("EMBEDDED_PROVIDER", `${operationName} failed`, {
150
- attempt,
151
- maxRetries,
152
- error: error instanceof Error ? error.message : String(error)
153
- });
154
- if (attempt === maxRetries) {
155
- logger.error("EMBEDDED_PROVIDER", `${operationName} failed after ${maxRetries} attempts`, {
156
- finalError: error instanceof Error ? error.message : String(error)
157
- });
158
- break;
159
- }
160
- const delay = baseDelay * Math.pow(2, attempt - 1);
161
- logger.log("EMBEDDED_PROVIDER", `Retrying ${operationName} in ${delay}ms`, {
162
- attempt: attempt + 1,
163
- delay
164
- });
165
- await new Promise((resolve) => setTimeout(resolve, delay));
166
- }
167
- }
168
- throw lastError;
169
- }
55
+ var EMBEDDED_PROVIDER_AUTH_TYPES = ["google", "apple", "phantom"];
170
56
 
171
57
  // src/chains/SolanaChain.ts
172
58
  var import_eventemitter3 = require("eventemitter3");
173
59
  var import_constants = require("@phantom/constants");
174
60
  var import_bs58 = __toESM(require("bs58"));
61
+ var import_parsers = require("@phantom/parsers");
175
62
  var EmbeddedSolanaChain = class {
176
63
  constructor(provider) {
177
64
  this.provider = provider;
@@ -208,8 +95,17 @@ var EmbeddedSolanaChain = class {
208
95
  publicKey: this._publicKey || ""
209
96
  };
210
97
  }
211
- signTransaction(_transaction) {
212
- return Promise.reject(new Error("signTransaction is not supported in embedded provider. Use signAndSendTransaction instead."));
98
+ async signTransaction(transaction) {
99
+ this.ensureConnected();
100
+ const result = await this.provider.signTransaction({
101
+ transaction,
102
+ networkId: this.currentNetworkId
103
+ });
104
+ const signedTransaction = (0, import_parsers.parseSolanaSignedTransaction)(result.rawTransaction);
105
+ if (!signedTransaction) {
106
+ throw new Error("Failed to parse signed transaction");
107
+ }
108
+ return signedTransaction;
213
109
  }
214
110
  async signAndSendTransaction(transaction) {
215
111
  this.ensureConnected();
@@ -222,8 +118,10 @@ var EmbeddedSolanaChain = class {
222
118
  }
223
119
  return { signature: result.hash };
224
120
  }
225
- signAllTransactions(_transactions) {
226
- return Promise.reject(new Error("signAllTransactions is not supported in embedded provider. Use signAndSendAllTransactions instead."));
121
+ async signAllTransactions(transactions) {
122
+ this.ensureConnected();
123
+ const results = await Promise.all(transactions.map((tx) => this.signTransaction(tx)));
124
+ return results;
227
125
  }
228
126
  async signAndSendAllTransactions(transactions) {
229
127
  const results = await Promise.all(transactions.map((tx) => this.signAndSendTransaction(tx)));
@@ -293,10 +191,8 @@ var EmbeddedSolanaChain = class {
293
191
  };
294
192
 
295
193
  // src/chains/EthereumChain.ts
296
- var import_eventemitter32 = require("eventemitter3");
297
194
  var import_constants2 = require("@phantom/constants");
298
- var import_base64url = require("@phantom/base64url");
299
- var import_buffer = require("buffer");
195
+ var import_eventemitter32 = require("eventemitter3");
300
196
  var EmbeddedEthereumChain = class {
301
197
  constructor(provider) {
302
198
  this.provider = provider;
@@ -354,18 +250,25 @@ var EmbeddedEthereumChain = class {
354
250
  });
355
251
  }
356
252
  async signTransaction(transaction) {
253
+ let networkId = this.currentNetworkId;
254
+ if (transaction.chainId) {
255
+ const numericChainId = typeof transaction.chainId === "number" ? transaction.chainId : parseInt(transaction.chainId, 16);
256
+ const txNetworkId = (0, import_constants2.chainIdToNetworkId)(numericChainId);
257
+ if (txNetworkId) {
258
+ networkId = txNetworkId;
259
+ }
260
+ }
357
261
  const result = await this.provider.signTransaction({
358
262
  transaction,
359
- networkId: this.currentNetworkId
263
+ networkId
360
264
  });
361
- try {
362
- const signatureBytes = (0, import_base64url.base64urlDecode)(result.rawTransaction);
363
- return "0x" + import_buffer.Buffer.from(signatureBytes).toString("hex");
364
- } catch (error) {
365
- return result.rawTransaction.startsWith("0x") ? result.rawTransaction : "0x" + result.rawTransaction;
366
- }
265
+ return result.rawTransaction;
367
266
  }
368
267
  async sendTransaction(transaction) {
268
+ if (transaction.chainId) {
269
+ const numericChainId = typeof transaction.chainId === "number" ? transaction.chainId : parseInt(transaction.chainId, 16);
270
+ await this.switchChain(numericChainId);
271
+ }
369
272
  const result = await this.provider.signAndSendTransaction({
370
273
  transaction,
371
274
  networkId: this.currentNetworkId
@@ -376,12 +279,13 @@ var EmbeddedEthereumChain = class {
376
279
  return result.hash;
377
280
  }
378
281
  switchChain(chainId) {
379
- const networkId = (0, import_constants2.chainIdToNetworkId)(chainId);
282
+ const numericChainId = typeof chainId === "string" ? chainId.toLowerCase().startsWith("0x") ? parseInt(chainId, 16) : parseInt(chainId, 10) : chainId;
283
+ const networkId = (0, import_constants2.chainIdToNetworkId)(numericChainId);
380
284
  if (!networkId) {
381
285
  throw new Error(`Unsupported chainId: ${chainId}`);
382
286
  }
383
287
  this.currentNetworkId = networkId;
384
- this.eventEmitter.emit("chainChanged", `0x${chainId.toString(16)}`);
288
+ this.eventEmitter.emit("chainChanged", `0x${numericChainId.toString(16)}`);
385
289
  return Promise.resolve();
386
290
  }
387
291
  getChainId() {
@@ -426,7 +330,7 @@ var EmbeddedEthereumChain = class {
426
330
  switch (args.method) {
427
331
  case "personal_sign": {
428
332
  const [message, _address] = args.params;
429
- const result = await this.provider.signMessage({
333
+ const result = await this.provider.signEthereumMessage({
430
334
  message,
431
335
  networkId: this.currentNetworkId
432
336
  });
@@ -434,10 +338,9 @@ var EmbeddedEthereumChain = class {
434
338
  }
435
339
  case "eth_signTypedData_v4": {
436
340
  const [_typedDataAddress, typedDataStr] = args.params;
437
- const _typedData = JSON.parse(typedDataStr);
438
- const typedDataResult = await this.provider.signMessage({
439
- message: typedDataStr,
440
- // Pass the stringified typed data as message
341
+ const typedData = JSON.parse(typedDataStr);
342
+ const typedDataResult = await this.provider.signTypedDataV4({
343
+ typedData,
441
344
  networkId: this.currentNetworkId
442
345
  });
443
346
  return typedDataResult.signature;
@@ -491,6 +394,45 @@ var EmbeddedEthereumChain = class {
491
394
  }
492
395
  };
493
396
 
397
+ // src/utils/retry.ts
398
+ async function retryWithBackoff(operation, operationName, logger, maxRetries = 3, baseDelay = 1e3) {
399
+ let lastError;
400
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
401
+ try {
402
+ logger.log("EMBEDDED_PROVIDER", `Attempting ${operationName}`, {
403
+ attempt,
404
+ maxRetries
405
+ });
406
+ return await operation();
407
+ } catch (error) {
408
+ lastError = error;
409
+ logger.warn("EMBEDDED_PROVIDER", `${operationName} failed`, {
410
+ attempt,
411
+ maxRetries,
412
+ error: error instanceof Error ? error.message : String(error)
413
+ });
414
+ if (attempt === maxRetries) {
415
+ logger.error("EMBEDDED_PROVIDER", `${operationName} failed after ${maxRetries} attempts`, {
416
+ finalError: error instanceof Error ? error.message : String(error)
417
+ });
418
+ break;
419
+ }
420
+ const delay = baseDelay * Math.pow(2, attempt - 1);
421
+ logger.log("EMBEDDED_PROVIDER", `Retrying ${operationName} in ${delay}ms`, {
422
+ attempt: attempt + 1,
423
+ delay
424
+ });
425
+ await new Promise((resolve) => setTimeout(resolve, delay));
426
+ }
427
+ }
428
+ throw lastError;
429
+ }
430
+
431
+ // src/utils/session.ts
432
+ function generateSessionId() {
433
+ return "session_" + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + "_" + Date.now();
434
+ }
435
+
494
436
  // src/embedded-provider.ts
495
437
  var EmbeddedProvider = class {
496
438
  constructor(config, platform, logger) {
@@ -507,9 +449,9 @@ var EmbeddedProvider = class {
507
449
  this.platform = platform;
508
450
  this.storage = platform.storage;
509
451
  this.authProvider = platform.authProvider;
452
+ this.phantomAppProvider = platform.phantomAppProvider;
510
453
  this.urlParamsAccessor = platform.urlParamsAccessor;
511
454
  this.stamper = platform.stamper;
512
- this.jwtAuth = new JWTAuth();
513
455
  this.solana = new EmbeddedSolanaChain(this);
514
456
  this.ethereum = new EmbeddedEthereumChain(this);
515
457
  this.logger.info("EMBEDDED_PROVIDER", "EmbeddedProvider initialized");
@@ -626,10 +568,16 @@ var EmbeddedProvider = class {
626
568
  }
627
569
  }
628
570
  if (session.status === "completed" && !this.isSessionValid(session)) {
629
- this.logger.warn("EMBEDDED_PROVIDER", "Session invalid due to authenticator expiration", {
630
- sessionId: session.sessionId,
631
- authenticatorExpiresAt: session.authenticatorExpiresAt
632
- });
571
+ this.logger.warn(
572
+ "EMBEDDED_PROVIDER",
573
+ "Session invalid due to authenticator expiration, will regenerate keypair",
574
+ {
575
+ sessionId: session.sessionId,
576
+ authenticatorExpiresAt: session.authenticatorExpiresAt,
577
+ currentTime: Date.now(),
578
+ expired: session.authenticatorExpiresAt < Date.now()
579
+ }
580
+ );
633
581
  await this.storage.clearSession();
634
582
  return null;
635
583
  }
@@ -644,7 +592,11 @@ var EmbeddedProvider = class {
644
592
  this.logger.log("EMBEDDED_PROVIDER", "Getting existing session");
645
593
  let session = await this.storage.getSession();
646
594
  session = await this.validateAndCleanSession(session);
647
- if (session && session.status === "completed") {
595
+ if (!session) {
596
+ this.logger.log("EMBEDDED_PROVIDER", "No existing session found");
597
+ return null;
598
+ }
599
+ if (session.status === "completed") {
648
600
  this.logger.info("EMBEDDED_PROVIDER", "Using existing completed session", {
649
601
  sessionId: session.sessionId,
650
602
  walletId: session.walletId
@@ -660,18 +612,19 @@ var EmbeddedProvider = class {
660
612
  const result = {
661
613
  walletId: this.walletId,
662
614
  addresses: this.addresses,
663
- status: "completed"
615
+ status: "completed",
616
+ authUserId: session.authUserId,
617
+ authProvider: session.authProvider
664
618
  };
665
619
  this.emit("connect", {
666
- walletId: this.walletId,
667
- addresses: this.addresses,
620
+ ...result,
668
621
  source: "existing-session"
669
622
  });
670
623
  return result;
671
624
  }
672
625
  this.logger.log("EMBEDDED_PROVIDER", "No completed session found, checking for redirect resume");
673
626
  if (this.authProvider.resumeAuthFromRedirect) {
674
- const authResult = this.authProvider.resumeAuthFromRedirect();
627
+ const authResult = this.authProvider.resumeAuthFromRedirect(session.authProvider);
675
628
  if (authResult) {
676
629
  this.logger.info("EMBEDDED_PROVIDER", "Resuming from redirect", {
677
630
  walletId: authResult.walletId,
@@ -703,13 +656,10 @@ var EmbeddedProvider = class {
703
656
  * This ensures only supported auth providers are used and required tokens are present.
704
657
  */
705
658
  validateAuthOptions(authOptions) {
706
- if (!authOptions)
707
- return;
708
- if (authOptions.provider && !["google", "apple", "jwt"].includes(authOptions.provider)) {
709
- throw new Error(`Invalid auth provider: ${authOptions.provider}. Must be "google", "apple", or "jwt"`);
710
- }
711
- if (authOptions.provider === "jwt" && !authOptions.jwtToken) {
712
- throw new Error("JWT token is required when using JWT authentication");
659
+ if (!EMBEDDED_PROVIDER_AUTH_TYPES.includes(authOptions.provider)) {
660
+ throw new Error(
661
+ `Invalid auth provider: ${authOptions.provider}. Must be ${EMBEDDED_PROVIDER_AUTH_TYPES.join(", ")}`
662
+ );
713
663
  }
714
664
  }
715
665
  /*
@@ -769,8 +719,7 @@ var EmbeddedProvider = class {
769
719
  addressCount: result.addresses.length
770
720
  });
771
721
  this.emit("connect", {
772
- walletId: result.walletId,
773
- addresses: result.addresses,
722
+ ...result,
774
723
  source: "auto-connect"
775
724
  });
776
725
  return;
@@ -788,40 +737,46 @@ var EmbeddedProvider = class {
788
737
  error: error instanceof Error ? error.message : "Auto-connect failed",
789
738
  source: "auto-connect"
790
739
  });
740
+ await this.storage.setShouldClearPreviousSession(true);
791
741
  }
792
742
  }
793
743
  /*
794
744
  * We use this method to initialize the stamper and create an organization for new sessions.
795
745
  * This is the first step when no existing session is found and we need to set up a new wallet.
796
746
  */
797
- async createOrganizationAndStamper() {
747
+ async initializeStamper() {
798
748
  this.logger.log("EMBEDDED_PROVIDER", "Initializing stamper");
799
- const stamperInfo = await this.stamper.init();
800
- this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized", {
749
+ await this.stamper.init();
750
+ this.logger.log("EMBEDDED_PROVIDER", "Resetting keypair to avoid conflicts with existing keypairs");
751
+ const stamperInfo = await this.stamper.resetKeyPair();
752
+ this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized with fresh keypair", {
801
753
  publicKey: stamperInfo.publicKey,
802
754
  keyId: stamperInfo.keyId,
803
755
  algorithm: this.stamper.algorithm
804
756
  });
805
- this.logger.log("EMBEDDED_PROVIDER", "Creating temporary PhantomClient");
806
- const tempClient = new import_client.PhantomClient(
807
- {
808
- apiBaseUrl: this.config.apiBaseUrl,
809
- headers: {
810
- ...this.platform.analyticsHeaders || {}
811
- }
812
- },
813
- this.stamper
814
- );
757
+ const expiresInMs = AUTHENTICATOR_EXPIRATION_TIME_MS;
758
+ this.logger.info("EMBEDDED_PROVIDER", "Stamper ready for auth flow with fresh keypair", {
759
+ publicKey: stamperInfo.publicKey,
760
+ keyId: stamperInfo.keyId
761
+ });
762
+ return { stamperInfo, expiresInMs };
763
+ }
764
+ async createOrganizationForAppWallet(stamperInfo, expiresInMs) {
765
+ const tempClient = new import_client.PhantomClient({
766
+ apiBaseUrl: this.config.apiBaseUrl,
767
+ headers: {
768
+ ...this.platform.analyticsHeaders || {}
769
+ }
770
+ });
815
771
  const platformName = this.platform.name || "unknown";
816
772
  const shortPubKey = stamperInfo.publicKey.slice(0, 8);
817
773
  const organizationName = `${this.config.appId.substring(0, 8)}-${platformName}-${shortPubKey}`;
818
- this.logger.log("EMBEDDED_PROVIDER", "Creating organization", {
774
+ this.logger.log("EMBEDDED_PROVIDER", "Creating organization for app-wallet", {
819
775
  organizationName,
820
776
  publicKey: stamperInfo.publicKey,
821
777
  platform: platformName
822
778
  });
823
- const base64urlPublicKey = (0, import_base64url2.base64urlEncode)(import_bs582.default.decode(stamperInfo.publicKey));
824
- const expiresInMs = AUTHENTICATOR_EXPIRATION_TIME_MS;
779
+ const base64urlPublicKey = (0, import_base64url.base64urlEncode)(import_bs582.default.decode(stamperInfo.publicKey));
825
780
  const username = `user-${(0, import_utils.randomUUID)()}`;
826
781
  const { organizationId } = await tempClient.createOrganization(organizationName, [
827
782
  {
@@ -832,27 +787,25 @@ var EmbeddedProvider = class {
832
787
  authenticatorName: `auth-${shortPubKey}`,
833
788
  authenticatorKind: "keypair",
834
789
  publicKey: base64urlPublicKey,
835
- algorithm: "Ed25519"
836
- // Commented for now until KMS supports fully expirable organizations
837
- // expiresInMs: expiresInMs,
790
+ algorithm: "Ed25519",
791
+ expiresInMs
838
792
  }
839
793
  ]
840
794
  }
841
795
  ]);
842
- this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId });
843
- return { organizationId, stamperInfo, expiresInMs, username };
796
+ this.logger.info("EMBEDDED_PROVIDER", "Organization created for app-wallet", { organizationId });
797
+ return organizationId;
844
798
  }
845
799
  async connect(authOptions) {
846
800
  try {
847
801
  this.logger.info("EMBEDDED_PROVIDER", "Starting embedded provider connect", {
848
- authOptions: authOptions ? {
849
- provider: authOptions.provider,
850
- hasJwtToken: !!authOptions.jwtToken
851
- } : void 0
802
+ authOptions: {
803
+ provider: authOptions.provider
804
+ }
852
805
  });
853
806
  this.emit("connect_start", {
854
807
  source: "manual-connect",
855
- authOptions: authOptions ? { provider: authOptions.provider } : void 0
808
+ authOptions: { provider: authOptions.provider }
856
809
  });
857
810
  const existingResult = await this.tryExistingConnection(false);
858
811
  if (existingResult) {
@@ -861,23 +814,26 @@ var EmbeddedProvider = class {
861
814
  addressCount: existingResult.addresses.length
862
815
  });
863
816
  this.emit("connect", {
864
- walletId: existingResult.walletId,
865
- addresses: existingResult.addresses,
817
+ ...existingResult,
866
818
  source: "manual-existing"
867
819
  });
868
820
  return existingResult;
869
821
  }
870
822
  this.validateAuthOptions(authOptions);
871
- this.logger.info("EMBEDDED_PROVIDER", "No existing connection, creating new auth flow");
872
- const { organizationId, stamperInfo, expiresInMs, username } = await this.createOrganizationAndStamper();
873
- const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresInMs, username);
823
+ this.logger.info(
824
+ "EMBEDDED_PROVIDER",
825
+ "No existing connection available, creating new auth flow with fresh keypair"
826
+ );
827
+ const { stamperInfo, expiresInMs } = await this.initializeStamper();
828
+ const session = await this.handleAuthFlow(stamperInfo.publicKey, stamperInfo, authOptions, expiresInMs);
874
829
  if (!session) {
875
830
  return {
876
831
  addresses: [],
877
- status: "pending"
832
+ status: "pending",
833
+ authProvider: authOptions.provider
878
834
  };
879
835
  }
880
- if (!authOptions || authOptions.provider === "jwt" || this.config.embeddedWalletType === "app-wallet") {
836
+ if (this.config.embeddedWalletType === "app-wallet") {
881
837
  session.lastUsed = Date.now();
882
838
  await this.storage.saveSession(session);
883
839
  }
@@ -886,11 +842,12 @@ var EmbeddedProvider = class {
886
842
  const result = {
887
843
  walletId: this.walletId,
888
844
  addresses: this.addresses,
889
- status: "completed"
845
+ status: "completed",
846
+ authUserId: session?.authUserId,
847
+ authProvider: session?.authProvider
890
848
  };
891
849
  this.emit("connect", {
892
- walletId: this.walletId,
893
- addresses: this.addresses,
850
+ ...result,
894
851
  source: "manual"
895
852
  });
896
853
  return result;
@@ -931,8 +888,10 @@ var EmbeddedProvider = class {
931
888
  throw new Error(`Embedded wallet connection failed: ${String(error)}`);
932
889
  }
933
890
  }
934
- async disconnect() {
891
+ async disconnect(shouldClearPreviousSession = true) {
935
892
  const wasConnected = this.client !== null;
893
+ await this.storage.setShouldClearPreviousSession(shouldClearPreviousSession);
894
+ this.logger.log("EMBEDDED_PROVIDER", "Set flag to clear previous session on next login");
936
895
  await this.storage.clearSession();
937
896
  this.client = null;
938
897
  this.walletId = null;
@@ -953,12 +912,11 @@ var EmbeddedProvider = class {
953
912
  walletId: this.walletId,
954
913
  message: params.message
955
914
  });
956
- const parsedMessage = (0, import_parsers.parseMessage)(params.message);
957
915
  const session = await this.storage.getSession();
958
916
  const derivationIndex = session?.accountDerivationIndex ?? 0;
959
- const rawResponse = await this.client.signMessage({
917
+ const rawResponse = await this.client.signUtf8Message({
960
918
  walletId: this.walletId,
961
- message: parsedMessage.base64url,
919
+ message: params.message,
962
920
  networkId: params.networkId,
963
921
  derivationIndex
964
922
  });
@@ -966,7 +924,62 @@ var EmbeddedProvider = class {
966
924
  walletId: this.walletId,
967
925
  message: params.message
968
926
  });
969
- return (0, import_parsers.parseSignMessageResponse)(rawResponse, params.networkId);
927
+ return (0, import_parsers2.parseSignMessageResponse)(rawResponse, params.networkId);
928
+ }
929
+ async signEthereumMessage(params) {
930
+ if (!this.client || !this.walletId) {
931
+ throw new Error("Not connected");
932
+ }
933
+ await this.ensureValidAuthenticator();
934
+ this.logger.info("EMBEDDED_PROVIDER", "Signing message", {
935
+ walletId: this.walletId,
936
+ message: params.message
937
+ });
938
+ const looksLikeHex = (str) => /^0x[0-9a-fA-F]+$/.test(str);
939
+ const normalizedMessage = (() => {
940
+ if (looksLikeHex(params.message)) {
941
+ const hexPayload = params.message.slice(2);
942
+ const normalizedHex = hexPayload.length % 2 === 0 ? hexPayload : `0${hexPayload}`;
943
+ return import_buffer.Buffer.from(normalizedHex, "hex").toString("utf8");
944
+ }
945
+ return params.message;
946
+ })();
947
+ const base64UrlMessage = (0, import_base64url.stringToBase64url)(normalizedMessage);
948
+ const session = await this.storage.getSession();
949
+ const derivationIndex = session?.accountDerivationIndex ?? 0;
950
+ const rawResponse = await this.client.ethereumSignMessage({
951
+ walletId: this.walletId,
952
+ message: base64UrlMessage,
953
+ networkId: params.networkId,
954
+ derivationIndex
955
+ });
956
+ this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
957
+ walletId: this.walletId,
958
+ message: params.message
959
+ });
960
+ return (0, import_parsers2.parseSignMessageResponse)(rawResponse, params.networkId);
961
+ }
962
+ async signTypedDataV4(params) {
963
+ if (!this.client || !this.walletId) {
964
+ throw new Error("Not connected");
965
+ }
966
+ await this.ensureValidAuthenticator();
967
+ this.logger.info("EMBEDDED_PROVIDER", "Signing typed data", {
968
+ walletId: this.walletId,
969
+ typedData: params.typedData
970
+ });
971
+ const session = await this.storage.getSession();
972
+ const derivationIndex = session?.accountDerivationIndex ?? 0;
973
+ const rawResponse = await this.client.ethereumSignTypedData({
974
+ walletId: this.walletId,
975
+ typedData: params.typedData,
976
+ networkId: params.networkId,
977
+ derivationIndex
978
+ });
979
+ this.logger.info("EMBEDDED_PROVIDER", "Typed data signed successfully", {
980
+ walletId: this.walletId
981
+ });
982
+ return (0, import_parsers2.parseSignMessageResponse)(rawResponse, params.networkId);
970
983
  }
971
984
  async signTransaction(params) {
972
985
  if (!this.client || !this.walletId) {
@@ -977,7 +990,7 @@ var EmbeddedProvider = class {
977
990
  walletId: this.walletId,
978
991
  networkId: params.networkId
979
992
  });
980
- const parsedTransaction = await (0, import_parsers.parseTransactionToBase64Url)(params.transaction, params.networkId);
993
+ const parsedTransaction = await (0, import_parsers2.parseToKmsTransaction)(params.transaction, params.networkId);
981
994
  const session = await this.storage.getSession();
982
995
  const derivationIndex = session?.accountDerivationIndex ?? 0;
983
996
  this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
@@ -985,19 +998,27 @@ var EmbeddedProvider = class {
985
998
  transaction: parsedTransaction,
986
999
  derivationIndex
987
1000
  });
1001
+ const transactionPayload = parsedTransaction.parsed;
1002
+ if (!transactionPayload) {
1003
+ throw new Error("Failed to parse transaction: no valid encoding found");
1004
+ }
1005
+ const account = this.getAddressForNetwork(params.networkId);
1006
+ if (!account) {
1007
+ throw new Error(`No address found for network ${params.networkId}`);
1008
+ }
988
1009
  const rawResponse = await this.client.signTransaction({
989
1010
  walletId: this.walletId,
990
- transaction: parsedTransaction.base64url,
1011
+ transaction: transactionPayload,
991
1012
  networkId: params.networkId,
992
1013
  derivationIndex,
993
- account: this.getAddressForNetwork(params.networkId)
1014
+ account
994
1015
  });
995
1016
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed successfully", {
996
1017
  walletId: this.walletId,
997
1018
  networkId: params.networkId,
998
1019
  rawTransaction: rawResponse.rawTransaction
999
1020
  });
1000
- return await (0, import_parsers.parseTransactionResponse)(rawResponse.rawTransaction, params.networkId);
1021
+ return await (0, import_parsers2.parseTransactionResponse)(rawResponse.rawTransaction, params.networkId);
1001
1022
  }
1002
1023
  async signAndSendTransaction(params) {
1003
1024
  if (!this.client || !this.walletId) {
@@ -1008,7 +1029,7 @@ var EmbeddedProvider = class {
1008
1029
  walletId: this.walletId,
1009
1030
  networkId: params.networkId
1010
1031
  });
1011
- const parsedTransaction = await (0, import_parsers.parseTransactionToBase64Url)(params.transaction, params.networkId);
1032
+ const parsedTransaction = await (0, import_parsers2.parseToKmsTransaction)(params.transaction, params.networkId);
1012
1033
  const session = await this.storage.getSession();
1013
1034
  const derivationIndex = session?.accountDerivationIndex ?? 0;
1014
1035
  this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
@@ -1016,20 +1037,36 @@ var EmbeddedProvider = class {
1016
1037
  transaction: parsedTransaction,
1017
1038
  derivationIndex
1018
1039
  });
1019
- const rawResponse = await this.client.signAndSendTransaction({
1020
- walletId: this.walletId,
1021
- transaction: parsedTransaction.base64url,
1022
- networkId: params.networkId,
1023
- derivationIndex,
1024
- account: this.getAddressForNetwork(params.networkId)
1025
- });
1040
+ const transactionPayload = parsedTransaction.parsed;
1041
+ if (!transactionPayload) {
1042
+ throw new Error("Failed to parse transaction: no valid encoding found");
1043
+ }
1044
+ const account = this.getAddressForNetwork(params.networkId);
1045
+ if (!account) {
1046
+ throw new Error(`No address found for network ${params.networkId}`);
1047
+ }
1048
+ let rawResponse;
1049
+ try {
1050
+ rawResponse = await this.client.signAndSendTransaction({
1051
+ walletId: this.walletId,
1052
+ transaction: transactionPayload,
1053
+ networkId: params.networkId,
1054
+ derivationIndex,
1055
+ account
1056
+ });
1057
+ } catch (error) {
1058
+ if (error instanceof import_client.SpendingLimitError) {
1059
+ this.emit("spending_limit_reached", { error });
1060
+ }
1061
+ throw error;
1062
+ }
1026
1063
  this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
1027
1064
  walletId: this.walletId,
1028
1065
  networkId: params.networkId,
1029
1066
  hash: rawResponse.hash,
1030
1067
  rawTransaction: rawResponse.rawTransaction
1031
1068
  });
1032
- return await (0, import_parsers.parseTransactionResponse)(rawResponse.rawTransaction, params.networkId, rawResponse.hash);
1069
+ return await (0, import_parsers2.parseTransactionResponse)(rawResponse.rawTransaction, params.networkId, rawResponse.hash);
1033
1070
  }
1034
1071
  getAddresses() {
1035
1072
  return this.addresses;
@@ -1042,24 +1079,25 @@ var EmbeddedProvider = class {
1042
1079
  * It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.
1043
1080
  * Returns null for redirect flows since they don't complete synchronously.
1044
1081
  */
1045
- async handleAuthFlow(organizationId, stamperInfo, authOptions, expiresInMs, username) {
1082
+ async handleAuthFlow(publicKey, stamperInfo, authOptions, expiresInMs) {
1046
1083
  if (this.config.embeddedWalletType === "user-wallet") {
1047
1084
  this.logger.info("EMBEDDED_PROVIDER", "Creating user-wallet, routing authentication", {
1048
- authProvider: authOptions?.provider || "phantom-connect"
1085
+ authProvider: authOptions.provider
1049
1086
  });
1050
- if (authOptions?.provider === "jwt") {
1051
- return await this.handleJWTAuth(organizationId, stamperInfo, authOptions, expiresInMs, username);
1087
+ if (authOptions.provider === "phantom") {
1088
+ return await this.handlePhantomAuth(publicKey, stamperInfo, expiresInMs);
1052
1089
  } else {
1053
1090
  this.logger.info("EMBEDDED_PROVIDER", "Starting redirect-based authentication flow", {
1054
- organizationId,
1091
+ publicKey,
1055
1092
  provider: authOptions?.provider
1056
1093
  });
1057
- return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions, username);
1094
+ return await this.handleRedirectAuth(publicKey, stamperInfo, authOptions);
1058
1095
  }
1059
1096
  } else {
1060
1097
  this.logger.info("EMBEDDED_PROVIDER", "Creating app-wallet", {
1061
- organizationId
1098
+ publicKey
1062
1099
  });
1100
+ const organizationId = await this.createOrganizationForAppWallet(stamperInfo, expiresInMs);
1063
1101
  const tempClient = new import_client.PhantomClient(
1064
1102
  {
1065
1103
  apiBaseUrl: this.config.apiBaseUrl,
@@ -1079,8 +1117,8 @@ var EmbeddedProvider = class {
1079
1117
  organizationId,
1080
1118
  appId: this.config.appId,
1081
1119
  stamperInfo,
1082
- authProvider: "app-wallet",
1083
- userInfo: { embeddedWalletType: this.config.embeddedWalletType },
1120
+ authProvider: "device",
1121
+ // For now app wallets have no auth provider.
1084
1122
  accountDerivationIndex: 0,
1085
1123
  // App wallets default to index 0
1086
1124
  status: "completed",
@@ -1088,8 +1126,7 @@ var EmbeddedProvider = class {
1088
1126
  lastUsed: now,
1089
1127
  authenticatorCreatedAt: now,
1090
1128
  authenticatorExpiresAt: Date.now() + expiresInMs,
1091
- lastRenewalAttempt: void 0,
1092
- username
1129
+ lastRenewalAttempt: void 0
1093
1130
  };
1094
1131
  await this.storage.saveSession(session);
1095
1132
  this.logger.info("EMBEDDED_PROVIDER", "App-wallet created successfully", { walletId, organizationId });
@@ -1097,43 +1134,56 @@ var EmbeddedProvider = class {
1097
1134
  }
1098
1135
  }
1099
1136
  /*
1100
- * We use this method to handle JWT-based authentication for user-wallets.
1101
- * It authenticates using the provided JWT token and creates a completed session.
1137
+ * We use this method to handle Phantom app-based authentication for user-wallets.
1138
+ * This method uses the PhantomAppProvider to authenticate via the browser extension or mobile app.
1139
+ *
1140
+ * NOTE: Mobile deeplink support is not yet implemented. If we wanted to support mobile deeplinks,
1141
+ * we would:
1142
+ * 1. Check if the app provider is available using phantomAppProvider.isAvailable()
1143
+ * 2. If not available, generate a deeplink (phantom://auth?...)
1144
+ * 3. Save a pending session before opening the deeplink
1145
+ * 4. Start a polling mechanism to check for auth completion
1146
+ * 5. Update the session when the mobile app completes the auth
1102
1147
  */
1103
- async handleJWTAuth(organizationId, stamperInfo, authOptions, expiresInMs, username) {
1104
- this.logger.info("EMBEDDED_PROVIDER", "Using JWT authentication flow");
1105
- if (!authOptions.jwtToken) {
1106
- this.logger.error("EMBEDDED_PROVIDER", "JWT token missing for JWT authentication");
1107
- throw new Error("JWT token is required for JWT authentication");
1148
+ async handlePhantomAuth(publicKey, stamperInfo, expiresInMs) {
1149
+ this.logger.info("EMBEDDED_PROVIDER", "Starting Phantom authentication flow");
1150
+ const isAvailable = this.phantomAppProvider.isAvailable();
1151
+ if (!isAvailable) {
1152
+ this.logger.error("EMBEDDED_PROVIDER", "Phantom app not available");
1153
+ throw new Error(
1154
+ "Phantom app is not available. Please install the Phantom browser extension or mobile app to use this authentication method."
1155
+ );
1108
1156
  }
1109
- this.logger.log("EMBEDDED_PROVIDER", "Starting JWT authentication");
1110
- const authResult = await this.jwtAuth.authenticate({
1111
- organizationId,
1157
+ this.logger.info("EMBEDDED_PROVIDER", "Phantom app detected, proceeding with authentication");
1158
+ const sessionId = generateSessionId();
1159
+ const authResult = await this.phantomAppProvider.authenticate({
1160
+ publicKey,
1112
1161
  appId: this.config.appId,
1113
- jwtToken: authOptions.jwtToken,
1114
- customAuthData: authOptions.customAuthData
1162
+ sessionId
1115
1163
  });
1116
- const walletId = authResult.walletId;
1117
- this.logger.info("EMBEDDED_PROVIDER", "JWT authentication completed", { walletId });
1164
+ this.logger.info("EMBEDDED_PROVIDER", "Phantom authentication completed", {
1165
+ walletId: authResult.walletId,
1166
+ organizationId: authResult.organizationId
1167
+ });
1168
+ const effectiveExpiresInMs = authResult.expiresInMs > 0 ? authResult.expiresInMs : expiresInMs;
1118
1169
  const now = Date.now();
1119
1170
  const session = {
1120
- sessionId: generateSessionId(),
1121
- walletId,
1122
- organizationId,
1171
+ sessionId,
1172
+ walletId: authResult.walletId,
1173
+ organizationId: authResult.organizationId,
1123
1174
  appId: this.config.appId,
1124
1175
  stamperInfo,
1125
- authProvider: authResult.provider,
1126
- userInfo: authResult.userInfo,
1176
+ authProvider: "phantom",
1127
1177
  accountDerivationIndex: authResult.accountDerivationIndex,
1128
1178
  status: "completed",
1129
1179
  createdAt: now,
1130
1180
  lastUsed: now,
1131
1181
  authenticatorCreatedAt: now,
1132
- authenticatorExpiresAt: Date.now() + expiresInMs,
1182
+ authenticatorExpiresAt: now + effectiveExpiresInMs,
1133
1183
  lastRenewalAttempt: void 0,
1134
- username
1184
+ authUserId: authResult.authUserId
1135
1185
  };
1136
- this.logger.log("EMBEDDED_PROVIDER", "Saving JWT session");
1186
+ this.logger.log("EMBEDDED_PROVIDER", "Saving Phantom session");
1137
1187
  await this.storage.saveSession(session);
1138
1188
  return session;
1139
1189
  }
@@ -1142,9 +1192,9 @@ var EmbeddedProvider = class {
1142
1192
  * It saves a temporary session before redirecting to prevent losing state during the redirect flow.
1143
1193
  * Session timestamp is updated before redirect to prevent race conditions.
1144
1194
  */
1145
- async handleRedirectAuth(organizationId, stamperInfo, authOptions, username) {
1195
+ async handleRedirectAuth(publicKey, stamperInfo, authOptions) {
1146
1196
  this.logger.info("EMBEDDED_PROVIDER", "Using Phantom Connect authentication flow (redirect-based)", {
1147
- provider: authOptions?.provider,
1197
+ provider: authOptions.provider,
1148
1198
  hasRedirectUrl: !!this.config.authOptions.redirectUrl,
1149
1199
  authUrl: this.config.authOptions.authUrl
1150
1200
  });
@@ -1152,13 +1202,13 @@ var EmbeddedProvider = class {
1152
1202
  const sessionId = generateSessionId();
1153
1203
  const tempSession = {
1154
1204
  sessionId,
1155
- walletId: `temp-${now}`,
1205
+ walletId: `temp-wallet-${now}`,
1206
+ // Temporary ID, will be updated after redirect
1207
+ organizationId: `temp-org-${now}`,
1156
1208
  // Temporary ID, will be updated after redirect
1157
- organizationId,
1158
1209
  appId: this.config.appId,
1159
1210
  stamperInfo,
1160
- authProvider: "phantom-connect",
1161
- userInfo: { provider: authOptions?.provider },
1211
+ authProvider: authOptions.provider,
1162
1212
  accountDerivationIndex: void 0,
1163
1213
  // Will be set when redirect completes
1164
1214
  status: "pending",
@@ -1166,8 +1216,7 @@ var EmbeddedProvider = class {
1166
1216
  lastUsed: now,
1167
1217
  authenticatorCreatedAt: now,
1168
1218
  authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,
1169
- lastRenewalAttempt: void 0,
1170
- username: username || `user-${(0, import_utils.randomUUID)()}`
1219
+ lastRenewalAttempt: void 0
1171
1220
  };
1172
1221
  this.logger.log("EMBEDDED_PROVIDER", "Saving temporary session before redirect", {
1173
1222
  sessionId: tempSession.sessionId,
@@ -1175,32 +1224,53 @@ var EmbeddedProvider = class {
1175
1224
  });
1176
1225
  tempSession.lastUsed = Date.now();
1177
1226
  await this.storage.saveSession(tempSession);
1227
+ const shouldClearPreviousSession = await this.storage.getShouldClearPreviousSession();
1178
1228
  this.logger.info("EMBEDDED_PROVIDER", "Starting Phantom Connect redirect", {
1179
- organizationId,
1229
+ publicKey,
1180
1230
  appId: this.config.appId,
1181
1231
  provider: authOptions?.provider,
1182
- authUrl: this.config.authOptions.authUrl
1232
+ authUrl: this.config.authOptions.authUrl,
1233
+ clearPreviousSession: shouldClearPreviousSession,
1234
+ allowRefresh: !shouldClearPreviousSession
1183
1235
  });
1184
1236
  const authResult = await this.authProvider.authenticate({
1185
- organizationId,
1237
+ publicKey,
1186
1238
  appId: this.config.appId,
1187
1239
  provider: authOptions?.provider,
1188
1240
  redirectUrl: this.config.authOptions.redirectUrl,
1189
- customAuthData: authOptions?.customAuthData,
1190
1241
  authUrl: this.config.authOptions.authUrl,
1191
- sessionId
1242
+ sessionId,
1243
+ // OAuth session management - defaults to allowing refresh unless user explicitly logged out
1244
+ clearPreviousSession: shouldClearPreviousSession,
1245
+ // true only after logout
1246
+ allowRefresh: !shouldClearPreviousSession
1247
+ // false only after logout
1192
1248
  });
1193
1249
  if (authResult && "walletId" in authResult) {
1194
1250
  this.logger.info("EMBEDDED_PROVIDER", "Authentication completed after redirect", {
1195
1251
  walletId: authResult.walletId,
1252
+ organizationId: authResult.organizationId,
1196
1253
  provider: authResult.provider
1197
1254
  });
1198
1255
  tempSession.walletId = authResult.walletId;
1256
+ tempSession.organizationId = authResult.organizationId;
1199
1257
  tempSession.authProvider = authResult.provider || tempSession.authProvider;
1200
1258
  tempSession.accountDerivationIndex = authResult.accountDerivationIndex;
1259
+ tempSession.authUserId = authResult.authUserId;
1201
1260
  tempSession.status = "completed";
1202
1261
  tempSession.lastUsed = Date.now();
1262
+ if (authResult.expiresInMs > 0) {
1263
+ const now2 = Date.now();
1264
+ tempSession.authenticatorCreatedAt = now2;
1265
+ tempSession.authenticatorExpiresAt = now2 + authResult.expiresInMs;
1266
+ this.logger.log("EMBEDDED_PROVIDER", "Updated authenticator expiration from immediate auth response", {
1267
+ expiresInMs: authResult.expiresInMs,
1268
+ expiresAt: new Date(tempSession.authenticatorExpiresAt).toISOString()
1269
+ });
1270
+ }
1203
1271
  await this.storage.saveSession(tempSession);
1272
+ await this.storage.setShouldClearPreviousSession(false);
1273
+ this.logger.log("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
1204
1274
  return tempSession;
1205
1275
  }
1206
1276
  this.logger.info("EMBEDDED_PROVIDER", "Redirect authentication initiated, waiting for redirect completion");
@@ -1213,16 +1283,31 @@ var EmbeddedProvider = class {
1213
1283
  }
1214
1284
  session.walletId = authResult.walletId;
1215
1285
  session.authProvider = authResult.provider || session.authProvider;
1286
+ session.organizationId = authResult.organizationId;
1216
1287
  session.accountDerivationIndex = authResult.accountDerivationIndex;
1288
+ session.authUserId = authResult.authUserId;
1217
1289
  session.status = "completed";
1218
1290
  session.lastUsed = Date.now();
1291
+ if (authResult.expiresInMs > 0) {
1292
+ const now = Date.now();
1293
+ session.authenticatorCreatedAt = now;
1294
+ session.authenticatorExpiresAt = now + authResult.expiresInMs;
1295
+ this.logger.log("EMBEDDED_PROVIDER", "Updated authenticator expiration from auth response", {
1296
+ expiresInMs: authResult.expiresInMs,
1297
+ expiresAt: new Date(session.authenticatorExpiresAt).toISOString()
1298
+ });
1299
+ }
1219
1300
  await this.storage.saveSession(session);
1301
+ await this.storage.setShouldClearPreviousSession(false);
1302
+ this.logger.log("EMBEDDED_PROVIDER", "Cleared logout flag after successful authentication");
1220
1303
  await this.initializeClientFromSession(session);
1221
1304
  await this.ensureValidAuthenticator();
1222
1305
  return {
1223
1306
  walletId: this.walletId,
1224
1307
  addresses: this.addresses,
1225
- status: "completed"
1308
+ status: "completed",
1309
+ authUserId: session.authUserId,
1310
+ authProvider: session.authProvider
1226
1311
  };
1227
1312
  }
1228
1313
  /*
@@ -1237,7 +1322,7 @@ var EmbeddedProvider = class {
1237
1322
  const now = Date.now();
1238
1323
  if (!session.authenticatorExpiresAt) {
1239
1324
  this.logger.warn("EMBEDDED_PROVIDER", "Session missing authenticator timing - treating as invalid session");
1240
- await this.disconnect();
1325
+ await this.disconnect(false);
1241
1326
  throw new Error("Invalid session - missing authenticator timing");
1242
1327
  }
1243
1328
  const timeUntilExpiry = session.authenticatorExpiresAt - now;
@@ -1247,86 +1332,9 @@ var EmbeddedProvider = class {
1247
1332
  });
1248
1333
  if (timeUntilExpiry <= 0) {
1249
1334
  this.logger.error("EMBEDDED_PROVIDER", "Authenticator has expired, disconnecting");
1250
- await this.disconnect();
1335
+ await this.disconnect(false);
1251
1336
  throw new Error("Authenticator expired");
1252
1337
  }
1253
- const renewalWindow = AUTHENTICATOR_RENEWAL_WINDOW_MS;
1254
- if (timeUntilExpiry <= renewalWindow) {
1255
- this.logger.info("EMBEDDED_PROVIDER", "Authenticator needs renewal", {
1256
- expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
1257
- timeUntilExpiry,
1258
- renewalWindow
1259
- });
1260
- try {
1261
- await this.renewAuthenticator(session);
1262
- this.logger.info("EMBEDDED_PROVIDER", "Authenticator renewed successfully");
1263
- } catch (error) {
1264
- this.logger.error("EMBEDDED_PROVIDER", "Failed to renew authenticator", {
1265
- error: error instanceof Error ? error.message : String(error)
1266
- });
1267
- }
1268
- }
1269
- }
1270
- /*
1271
- * We use this method to perform silent authenticator renewal.
1272
- * It generates a new keypair, creates a new authenticator, and switches to it.
1273
- */
1274
- async renewAuthenticator(session) {
1275
- if (!this.client) {
1276
- throw new Error("Client not initialized");
1277
- }
1278
- this.logger.info("EMBEDDED_PROVIDER", "Starting authenticator renewal");
1279
- try {
1280
- const newKeyInfo = await this.stamper.rotateKeyPair();
1281
- this.logger.log("EMBEDDED_PROVIDER", "Generated new keypair for renewal", {
1282
- newKeyId: newKeyInfo.keyId,
1283
- newPublicKey: newKeyInfo.publicKey
1284
- });
1285
- const base64urlPublicKey = (0, import_base64url2.base64urlEncode)(import_bs582.default.decode(newKeyInfo.publicKey));
1286
- const expiresInMs = AUTHENTICATOR_EXPIRATION_TIME_MS;
1287
- let authenticatorResult;
1288
- try {
1289
- authenticatorResult = await this.client.createAuthenticator({
1290
- organizationId: session.organizationId,
1291
- username: session.username,
1292
- authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,
1293
- authenticator: {
1294
- authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,
1295
- authenticatorKind: "keypair",
1296
- publicKey: base64urlPublicKey,
1297
- algorithm: "Ed25519"
1298
- // Commented for now until KMS supports fully expiring organizations
1299
- // expiresInMs: expiresInMs,
1300
- },
1301
- replaceExpirable: true
1302
- });
1303
- } catch (error) {
1304
- this.logger.error("EMBEDDED_PROVIDER", "Failed to create new authenticator", {
1305
- error: error instanceof Error ? error.message : String(error)
1306
- });
1307
- await this.stamper.rollbackRotation();
1308
- throw new Error(
1309
- `Failed to create new authenticator: ${error instanceof Error ? error.message : String(error)}`
1310
- );
1311
- }
1312
- this.logger.info("EMBEDDED_PROVIDER", "Created new authenticator", {
1313
- authenticatorId: authenticatorResult.id
1314
- });
1315
- await this.stamper.commitRotation(authenticatorResult.id || "unknown");
1316
- const now = Date.now();
1317
- session.stamperInfo = newKeyInfo;
1318
- session.authenticatorCreatedAt = now;
1319
- session.authenticatorExpiresAt = Date.now() + expiresInMs;
1320
- session.lastRenewalAttempt = now;
1321
- await this.storage.saveSession(session);
1322
- this.logger.info("EMBEDDED_PROVIDER", "Authenticator renewal completed successfully", {
1323
- newKeyId: newKeyInfo.keyId,
1324
- expiresAt: new Date(Date.now() + expiresInMs).toISOString()
1325
- });
1326
- } catch (error) {
1327
- await this.stamper.rollbackRotation();
1328
- throw error;
1329
- }
1330
1338
  }
1331
1339
  /*
1332
1340
  * We use this method to initialize the PhantomClient and fetch wallet addresses from a completed session.
@@ -1359,10 +1367,10 @@ var EmbeddedProvider = class {
1359
1367
  0 && (module.exports = {
1360
1368
  AUTHENTICATOR_EXPIRATION_TIME_MS,
1361
1369
  AUTHENTICATOR_RENEWAL_WINDOW_MS,
1370
+ EMBEDDED_PROVIDER_AUTH_TYPES,
1362
1371
  EmbeddedEthereumChain,
1363
1372
  EmbeddedProvider,
1364
1373
  EmbeddedSolanaChain,
1365
- JWTAuth,
1366
1374
  generateSessionId,
1367
1375
  retryWithBackoff
1368
1376
  });