@phantom/embedded-provider-core 0.1.8 → 0.1.10
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 +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +186 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +184 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
parseTransactionResponse
|
|
10
10
|
} from "@phantom/parsers";
|
|
11
11
|
|
|
12
|
+
// src/constants.ts
|
|
13
|
+
var AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
14
|
+
var AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
15
|
+
|
|
12
16
|
// src/auth/jwt-auth.ts
|
|
13
17
|
var JWTAuth = class {
|
|
14
18
|
async authenticate(options) {
|
|
@@ -175,14 +179,17 @@ var EmbeddedProvider = class {
|
|
|
175
179
|
}
|
|
176
180
|
}
|
|
177
181
|
async getAndFilterWalletAddresses(walletId) {
|
|
182
|
+
const session = await this.storage.getSession();
|
|
183
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
178
184
|
const addresses = await retryWithBackoff(
|
|
179
|
-
() => this.client.getWalletAddresses(walletId),
|
|
185
|
+
() => this.client.getWalletAddresses(walletId, void 0, derivationIndex),
|
|
180
186
|
"getWalletAddresses",
|
|
181
187
|
this.logger
|
|
182
188
|
).catch(async (error) => {
|
|
183
189
|
this.logger.error("EMBEDDED_PROVIDER", "getWalletAddresses failed after retries, disconnecting", {
|
|
184
190
|
walletId,
|
|
185
|
-
error: error.message
|
|
191
|
+
error: error.message,
|
|
192
|
+
derivationIndex
|
|
186
193
|
});
|
|
187
194
|
await this.storage.clearSession();
|
|
188
195
|
this.client = null;
|
|
@@ -223,6 +230,14 @@ var EmbeddedProvider = class {
|
|
|
223
230
|
return null;
|
|
224
231
|
}
|
|
225
232
|
}
|
|
233
|
+
if (session.status === "completed" && !this.isSessionValid(session)) {
|
|
234
|
+
this.logger.warn("EMBEDDED_PROVIDER", "Session invalid due to authenticator expiration", {
|
|
235
|
+
sessionId: session.sessionId,
|
|
236
|
+
authenticatorExpiresAt: session.authenticatorExpiresAt
|
|
237
|
+
});
|
|
238
|
+
await this.storage.clearSession();
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
226
241
|
return session;
|
|
227
242
|
}
|
|
228
243
|
/*
|
|
@@ -257,6 +272,7 @@ var EmbeddedProvider = class {
|
|
|
257
272
|
walletId: this.walletId,
|
|
258
273
|
addressCount: this.addresses.length
|
|
259
274
|
});
|
|
275
|
+
await this.ensureValidAuthenticator();
|
|
260
276
|
const result = {
|
|
261
277
|
walletId: this.walletId,
|
|
262
278
|
addresses: this.addresses,
|
|
@@ -286,8 +302,9 @@ var EmbeddedProvider = class {
|
|
|
286
302
|
}
|
|
287
303
|
}
|
|
288
304
|
/*
|
|
289
|
-
* We use this method to validate if a session is still valid
|
|
290
|
-
* This checks session status,
|
|
305
|
+
* We use this method to validate if a session is still valid.
|
|
306
|
+
* This checks session status, required fields, and authenticator expiration.
|
|
307
|
+
* Sessions never expire by age - only authenticators expire.
|
|
291
308
|
*/
|
|
292
309
|
isSessionValid(session) {
|
|
293
310
|
if (!session) {
|
|
@@ -305,20 +322,23 @@ var EmbeddedProvider = class {
|
|
|
305
322
|
this.logger.log("EMBEDDED_PROVIDER", "Session not completed", { status: session.status });
|
|
306
323
|
return false;
|
|
307
324
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
325
|
+
if (!session.authenticatorExpiresAt) {
|
|
326
|
+
this.logger.log("EMBEDDED_PROVIDER", "Session invalid - missing authenticator timing", {
|
|
327
|
+
sessionId: session.sessionId
|
|
328
|
+
});
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
if (Date.now() >= session.authenticatorExpiresAt) {
|
|
332
|
+
this.logger.log("EMBEDDED_PROVIDER", "Authenticator expired, session invalid", {
|
|
333
|
+
authenticatorExpiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
|
|
334
|
+
now: (/* @__PURE__ */ new Date()).toISOString()
|
|
315
335
|
});
|
|
316
336
|
return false;
|
|
317
337
|
}
|
|
318
338
|
this.logger.log("EMBEDDED_PROVIDER", "Session is valid", {
|
|
319
339
|
sessionId: session.sessionId,
|
|
320
340
|
walletId: session.walletId,
|
|
321
|
-
|
|
341
|
+
authenticatorExpires: new Date(session.authenticatorExpiresAt).toISOString()
|
|
322
342
|
});
|
|
323
343
|
return true;
|
|
324
344
|
}
|
|
@@ -387,9 +407,11 @@ var EmbeddedProvider = class {
|
|
|
387
407
|
platform: platformName
|
|
388
408
|
});
|
|
389
409
|
const base64urlPublicKey = base64urlEncode(bs58.decode(stamperInfo.publicKey));
|
|
410
|
+
const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;
|
|
411
|
+
const username = `user-${shortPubKey}`;
|
|
390
412
|
const { organizationId } = await tempClient.createOrganization(organizationName, [
|
|
391
413
|
{
|
|
392
|
-
username
|
|
414
|
+
username,
|
|
393
415
|
role: "ADMIN",
|
|
394
416
|
authenticators: [
|
|
395
417
|
{
|
|
@@ -397,12 +419,14 @@ var EmbeddedProvider = class {
|
|
|
397
419
|
authenticatorKind: "keypair",
|
|
398
420
|
publicKey: base64urlPublicKey,
|
|
399
421
|
algorithm: "Ed25519"
|
|
422
|
+
// Commented for now until KMS supports fully expirable organizations
|
|
423
|
+
// expiresAtMs: expiresAtMs,
|
|
400
424
|
}
|
|
401
425
|
]
|
|
402
426
|
}
|
|
403
427
|
]);
|
|
404
428
|
this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId });
|
|
405
|
-
return { organizationId, stamperInfo };
|
|
429
|
+
return { organizationId, stamperInfo, expiresAtMs, username };
|
|
406
430
|
}
|
|
407
431
|
async connect(authOptions) {
|
|
408
432
|
try {
|
|
@@ -431,8 +455,8 @@ var EmbeddedProvider = class {
|
|
|
431
455
|
}
|
|
432
456
|
this.validateAuthOptions(authOptions);
|
|
433
457
|
this.logger.info("EMBEDDED_PROVIDER", "No existing connection, creating new auth flow");
|
|
434
|
-
const { organizationId, stamperInfo } = await this.createOrganizationAndStamper();
|
|
435
|
-
const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions);
|
|
458
|
+
const { organizationId, stamperInfo, expiresAtMs, username } = await this.createOrganizationAndStamper();
|
|
459
|
+
const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username);
|
|
436
460
|
if (!session) {
|
|
437
461
|
return {
|
|
438
462
|
addresses: [],
|
|
@@ -444,6 +468,7 @@ var EmbeddedProvider = class {
|
|
|
444
468
|
await this.storage.saveSession(session);
|
|
445
469
|
}
|
|
446
470
|
await this.initializeClientFromSession(session);
|
|
471
|
+
await this.ensureValidAuthenticator();
|
|
447
472
|
const result = {
|
|
448
473
|
walletId: this.walletId,
|
|
449
474
|
addresses: this.addresses,
|
|
@@ -509,15 +534,19 @@ var EmbeddedProvider = class {
|
|
|
509
534
|
if (!this.client || !this.walletId) {
|
|
510
535
|
throw new Error("Not connected");
|
|
511
536
|
}
|
|
537
|
+
await this.ensureValidAuthenticator();
|
|
512
538
|
this.logger.info("EMBEDDED_PROVIDER", "Signing message", {
|
|
513
539
|
walletId: this.walletId,
|
|
514
540
|
message: params.message
|
|
515
541
|
});
|
|
516
542
|
const parsedMessage = parseMessage(params.message);
|
|
543
|
+
const session = await this.storage.getSession();
|
|
544
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
517
545
|
const rawResponse = await this.client.signMessage({
|
|
518
546
|
walletId: this.walletId,
|
|
519
547
|
message: parsedMessage.base64url,
|
|
520
|
-
networkId: params.networkId
|
|
548
|
+
networkId: params.networkId,
|
|
549
|
+
derivationIndex
|
|
521
550
|
});
|
|
522
551
|
this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
|
|
523
552
|
walletId: this.walletId,
|
|
@@ -529,19 +558,24 @@ var EmbeddedProvider = class {
|
|
|
529
558
|
if (!this.client || !this.walletId) {
|
|
530
559
|
throw new Error("Not connected");
|
|
531
560
|
}
|
|
561
|
+
await this.ensureValidAuthenticator();
|
|
532
562
|
this.logger.info("EMBEDDED_PROVIDER", "Signing and sending transaction", {
|
|
533
563
|
walletId: this.walletId,
|
|
534
564
|
networkId: params.networkId
|
|
535
565
|
});
|
|
536
566
|
const parsedTransaction = await parseTransaction(params.transaction, params.networkId);
|
|
567
|
+
const session = await this.storage.getSession();
|
|
568
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
537
569
|
this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
|
|
538
570
|
walletId: this.walletId,
|
|
539
|
-
transaction: parsedTransaction
|
|
571
|
+
transaction: parsedTransaction,
|
|
572
|
+
derivationIndex
|
|
540
573
|
});
|
|
541
574
|
const rawResponse = await this.client.signAndSendTransaction({
|
|
542
575
|
walletId: this.walletId,
|
|
543
576
|
transaction: parsedTransaction.base64url,
|
|
544
|
-
networkId: params.networkId
|
|
577
|
+
networkId: params.networkId,
|
|
578
|
+
derivationIndex
|
|
545
579
|
});
|
|
546
580
|
this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
|
|
547
581
|
walletId: this.walletId,
|
|
@@ -562,20 +596,20 @@ var EmbeddedProvider = class {
|
|
|
562
596
|
* It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.
|
|
563
597
|
* Returns null for redirect flows since they don't complete synchronously.
|
|
564
598
|
*/
|
|
565
|
-
async handleAuthFlow(organizationId, stamperInfo, authOptions) {
|
|
599
|
+
async handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username) {
|
|
566
600
|
if (this.config.embeddedWalletType === "user-wallet") {
|
|
567
601
|
this.logger.info("EMBEDDED_PROVIDER", "Creating user-wallet, routing authentication", {
|
|
568
602
|
authProvider: authOptions?.provider || "phantom-connect"
|
|
569
603
|
});
|
|
570
604
|
if (authOptions?.provider === "jwt") {
|
|
571
|
-
return await this.handleJWTAuth(organizationId, stamperInfo, authOptions);
|
|
605
|
+
return await this.handleJWTAuth(organizationId, stamperInfo, authOptions, expiresAtMs, username);
|
|
572
606
|
} else {
|
|
573
607
|
this.logger.info("EMBEDDED_PROVIDER", "Starting redirect-based authentication flow", {
|
|
574
608
|
organizationId,
|
|
575
609
|
parentOrganizationId: this.config.organizationId,
|
|
576
610
|
provider: authOptions?.provider
|
|
577
611
|
});
|
|
578
|
-
return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions);
|
|
612
|
+
return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions, username);
|
|
579
613
|
}
|
|
580
614
|
} else {
|
|
581
615
|
this.logger.info("EMBEDDED_PROVIDER", "Creating app-wallet", {
|
|
@@ -598,9 +632,15 @@ var EmbeddedProvider = class {
|
|
|
598
632
|
stamperInfo,
|
|
599
633
|
authProvider: "app-wallet",
|
|
600
634
|
userInfo: { embeddedWalletType: this.config.embeddedWalletType },
|
|
635
|
+
accountDerivationIndex: 0,
|
|
636
|
+
// App wallets default to index 0
|
|
601
637
|
status: "completed",
|
|
602
638
|
createdAt: now,
|
|
603
|
-
lastUsed: now
|
|
639
|
+
lastUsed: now,
|
|
640
|
+
authenticatorCreatedAt: now,
|
|
641
|
+
authenticatorExpiresAt: expiresAtMs,
|
|
642
|
+
lastRenewalAttempt: void 0,
|
|
643
|
+
username
|
|
604
644
|
};
|
|
605
645
|
await this.storage.saveSession(session);
|
|
606
646
|
this.logger.info("EMBEDDED_PROVIDER", "App-wallet created successfully", { walletId, organizationId });
|
|
@@ -611,7 +651,7 @@ var EmbeddedProvider = class {
|
|
|
611
651
|
* We use this method to handle JWT-based authentication for user-wallets.
|
|
612
652
|
* It authenticates using the provided JWT token and creates a completed session.
|
|
613
653
|
*/
|
|
614
|
-
async handleJWTAuth(organizationId, stamperInfo, authOptions) {
|
|
654
|
+
async handleJWTAuth(organizationId, stamperInfo, authOptions, expiresAtMs, username) {
|
|
615
655
|
this.logger.info("EMBEDDED_PROVIDER", "Using JWT authentication flow");
|
|
616
656
|
if (!authOptions.jwtToken) {
|
|
617
657
|
this.logger.error("EMBEDDED_PROVIDER", "JWT token missing for JWT authentication");
|
|
@@ -634,9 +674,14 @@ var EmbeddedProvider = class {
|
|
|
634
674
|
stamperInfo,
|
|
635
675
|
authProvider: authResult.provider,
|
|
636
676
|
userInfo: authResult.userInfo,
|
|
677
|
+
accountDerivationIndex: authResult.accountDerivationIndex,
|
|
637
678
|
status: "completed",
|
|
638
679
|
createdAt: now,
|
|
639
|
-
lastUsed: now
|
|
680
|
+
lastUsed: now,
|
|
681
|
+
authenticatorCreatedAt: now,
|
|
682
|
+
authenticatorExpiresAt: expiresAtMs,
|
|
683
|
+
lastRenewalAttempt: void 0,
|
|
684
|
+
username
|
|
640
685
|
};
|
|
641
686
|
this.logger.log("EMBEDDED_PROVIDER", "Saving JWT session");
|
|
642
687
|
await this.storage.saveSession(session);
|
|
@@ -647,7 +692,7 @@ var EmbeddedProvider = class {
|
|
|
647
692
|
* It saves a temporary session before redirecting to prevent losing state during the redirect flow.
|
|
648
693
|
* Session timestamp is updated before redirect to prevent race conditions.
|
|
649
694
|
*/
|
|
650
|
-
async handleRedirectAuth(organizationId, stamperInfo, authOptions) {
|
|
695
|
+
async handleRedirectAuth(organizationId, stamperInfo, authOptions, username) {
|
|
651
696
|
this.logger.info("EMBEDDED_PROVIDER", "Using Phantom Connect authentication flow (redirect-based)", {
|
|
652
697
|
provider: authOptions?.provider,
|
|
653
698
|
hasRedirectUrl: !!this.config.authOptions?.redirectUrl,
|
|
@@ -663,9 +708,15 @@ var EmbeddedProvider = class {
|
|
|
663
708
|
stamperInfo,
|
|
664
709
|
authProvider: "phantom-connect",
|
|
665
710
|
userInfo: { provider: authOptions?.provider },
|
|
711
|
+
accountDerivationIndex: void 0,
|
|
712
|
+
// Will be set when redirect completes
|
|
666
713
|
status: "pending",
|
|
667
714
|
createdAt: now,
|
|
668
|
-
lastUsed: now
|
|
715
|
+
lastUsed: now,
|
|
716
|
+
authenticatorCreatedAt: now,
|
|
717
|
+
authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,
|
|
718
|
+
lastRenewalAttempt: void 0,
|
|
719
|
+
username: username || `user-${stamperInfo.keyId.substring(0, 8)}`
|
|
669
720
|
};
|
|
670
721
|
this.logger.log("EMBEDDED_PROVIDER", "Saving temporary session before redirect", {
|
|
671
722
|
sessionId: tempSession.sessionId,
|
|
@@ -697,6 +748,7 @@ var EmbeddedProvider = class {
|
|
|
697
748
|
});
|
|
698
749
|
tempSession.walletId = authResult.walletId;
|
|
699
750
|
tempSession.authProvider = authResult.provider || tempSession.authProvider;
|
|
751
|
+
tempSession.accountDerivationIndex = authResult.accountDerivationIndex;
|
|
700
752
|
tempSession.status = "completed";
|
|
701
753
|
tempSession.lastUsed = Date.now();
|
|
702
754
|
await this.storage.saveSession(tempSession);
|
|
@@ -712,16 +764,119 @@ var EmbeddedProvider = class {
|
|
|
712
764
|
}
|
|
713
765
|
session.walletId = authResult.walletId;
|
|
714
766
|
session.authProvider = authResult.provider || session.authProvider;
|
|
767
|
+
session.accountDerivationIndex = authResult.accountDerivationIndex;
|
|
715
768
|
session.status = "completed";
|
|
716
769
|
session.lastUsed = Date.now();
|
|
717
770
|
await this.storage.saveSession(session);
|
|
718
771
|
await this.initializeClientFromSession(session);
|
|
772
|
+
await this.ensureValidAuthenticator();
|
|
719
773
|
return {
|
|
720
774
|
walletId: this.walletId,
|
|
721
775
|
addresses: this.addresses,
|
|
722
776
|
status: "completed"
|
|
723
777
|
};
|
|
724
778
|
}
|
|
779
|
+
/*
|
|
780
|
+
* Ensures the authenticator is valid and performs renewal if needed.
|
|
781
|
+
* The renewal of the authenticator can only happen meanwhile the previous authenticator is still valid.
|
|
782
|
+
*/
|
|
783
|
+
async ensureValidAuthenticator() {
|
|
784
|
+
const session = await this.storage.getSession();
|
|
785
|
+
if (!session) {
|
|
786
|
+
throw new Error("No active session found");
|
|
787
|
+
}
|
|
788
|
+
const now = Date.now();
|
|
789
|
+
if (!session.authenticatorExpiresAt) {
|
|
790
|
+
this.logger.warn("EMBEDDED_PROVIDER", "Session missing authenticator timing - treating as invalid session");
|
|
791
|
+
await this.disconnect();
|
|
792
|
+
throw new Error("Invalid session - missing authenticator timing");
|
|
793
|
+
}
|
|
794
|
+
const timeUntilExpiry = session.authenticatorExpiresAt - now;
|
|
795
|
+
this.logger.log("EMBEDDED_PROVIDER", "Checking authenticator expiration", {
|
|
796
|
+
expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
|
|
797
|
+
timeUntilExpiry
|
|
798
|
+
});
|
|
799
|
+
if (timeUntilExpiry <= 0) {
|
|
800
|
+
this.logger.error("EMBEDDED_PROVIDER", "Authenticator has expired, disconnecting");
|
|
801
|
+
await this.disconnect();
|
|
802
|
+
throw new Error("Authenticator expired");
|
|
803
|
+
}
|
|
804
|
+
const renewalWindow = AUTHENTICATOR_RENEWAL_WINDOW_MS;
|
|
805
|
+
if (timeUntilExpiry <= renewalWindow) {
|
|
806
|
+
this.logger.info("EMBEDDED_PROVIDER", "Authenticator needs renewal", {
|
|
807
|
+
expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),
|
|
808
|
+
timeUntilExpiry,
|
|
809
|
+
renewalWindow
|
|
810
|
+
});
|
|
811
|
+
try {
|
|
812
|
+
await this.renewAuthenticator(session);
|
|
813
|
+
this.logger.info("EMBEDDED_PROVIDER", "Authenticator renewed successfully");
|
|
814
|
+
} catch (error) {
|
|
815
|
+
this.logger.error("EMBEDDED_PROVIDER", "Failed to renew authenticator", {
|
|
816
|
+
error: error instanceof Error ? error.message : String(error)
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
/*
|
|
822
|
+
* We use this method to perform silent authenticator renewal.
|
|
823
|
+
* It generates a new keypair, creates a new authenticator, and switches to it.
|
|
824
|
+
*/
|
|
825
|
+
async renewAuthenticator(session) {
|
|
826
|
+
if (!this.client) {
|
|
827
|
+
throw new Error("Client not initialized");
|
|
828
|
+
}
|
|
829
|
+
this.logger.info("EMBEDDED_PROVIDER", "Starting authenticator renewal");
|
|
830
|
+
try {
|
|
831
|
+
const newKeyInfo = await this.stamper.rotateKeyPair();
|
|
832
|
+
this.logger.log("EMBEDDED_PROVIDER", "Generated new keypair for renewal", {
|
|
833
|
+
newKeyId: newKeyInfo.keyId,
|
|
834
|
+
newPublicKey: newKeyInfo.publicKey
|
|
835
|
+
});
|
|
836
|
+
const base64urlPublicKey = base64urlEncode(bs58.decode(newKeyInfo.publicKey));
|
|
837
|
+
const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;
|
|
838
|
+
let authenticatorResult;
|
|
839
|
+
try {
|
|
840
|
+
authenticatorResult = await this.client.createAuthenticator({
|
|
841
|
+
organizationId: session.organizationId,
|
|
842
|
+
username: session.username,
|
|
843
|
+
authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,
|
|
844
|
+
authenticator: {
|
|
845
|
+
authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,
|
|
846
|
+
authenticatorKind: "keypair",
|
|
847
|
+
publicKey: base64urlPublicKey,
|
|
848
|
+
algorithm: "Ed25519"
|
|
849
|
+
// Commented for now until KMS supports fully expiring organizations
|
|
850
|
+
// expiresAtMs: expiresAtMs,
|
|
851
|
+
},
|
|
852
|
+
replaceExpirable: true
|
|
853
|
+
});
|
|
854
|
+
} catch (error) {
|
|
855
|
+
this.logger.error("EMBEDDED_PROVIDER", "Failed to create new authenticator", {
|
|
856
|
+
error: error instanceof Error ? error.message : String(error)
|
|
857
|
+
});
|
|
858
|
+
await this.stamper.rollbackRotation();
|
|
859
|
+
throw new Error(`Failed to create new authenticator: ${error instanceof Error ? error.message : String(error)}`);
|
|
860
|
+
}
|
|
861
|
+
this.logger.info("EMBEDDED_PROVIDER", "Created new authenticator", {
|
|
862
|
+
authenticatorId: authenticatorResult.id
|
|
863
|
+
});
|
|
864
|
+
await this.stamper.commitRotation(authenticatorResult.id || "unknown");
|
|
865
|
+
const now = Date.now();
|
|
866
|
+
session.stamperInfo = newKeyInfo;
|
|
867
|
+
session.authenticatorCreatedAt = now;
|
|
868
|
+
session.authenticatorExpiresAt = expiresAtMs;
|
|
869
|
+
session.lastRenewalAttempt = now;
|
|
870
|
+
await this.storage.saveSession(session);
|
|
871
|
+
this.logger.info("EMBEDDED_PROVIDER", "Authenticator renewal completed successfully", {
|
|
872
|
+
newKeyId: newKeyInfo.keyId,
|
|
873
|
+
expiresAt: new Date(expiresAtMs).toISOString()
|
|
874
|
+
});
|
|
875
|
+
} catch (error) {
|
|
876
|
+
await this.stamper.rollbackRotation();
|
|
877
|
+
throw error;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
725
880
|
/*
|
|
726
881
|
* We use this method to initialize the PhantomClient and fetch wallet addresses from a completed session.
|
|
727
882
|
* This is the final step that sets up the provider's client state and retrieves available addresses.
|
|
@@ -746,6 +901,8 @@ var EmbeddedProvider = class {
|
|
|
746
901
|
}
|
|
747
902
|
};
|
|
748
903
|
export {
|
|
904
|
+
AUTHENTICATOR_EXPIRATION_TIME_MS,
|
|
905
|
+
AUTHENTICATOR_RENEWAL_WINDOW_MS,
|
|
749
906
|
EmbeddedProvider,
|
|
750
907
|
JWTAuth,
|
|
751
908
|
generateSessionId,
|