@@ -61,12 +61,13 @@ export type ExportWalletParams = {
61
61
62
62
export type ExportWalletResult = string ;
63
63
64
+ const SESSION_STAMPER = NativeTEKStamper ;
65
+
64
66
// TODO: need to emit events
65
67
export class RNSignerClient extends BaseSignerClient <
66
68
ExportWalletParams ,
67
69
string
68
70
> {
69
- private stamper = NativeTEKStamper ;
70
71
oauthCallbackUrl : string ;
71
72
rpId : string | undefined ;
72
73
private validAuthenticatingTypes : AuthenticatingEventMetadata [ "type" ] [ ] = [
@@ -80,7 +81,7 @@ export class RNSignerClient extends BaseSignerClient<
80
81
RNSignerClientParamsSchema . parse ( params ) ;
81
82
82
83
super ( {
83
- stamper : NativeTEKStamper ,
84
+ stamper : SESSION_STAMPER ,
84
85
rootOrgId : rootOrgId ?? "24c1acf5-810f-41e0-a503-d5d13fa8e830" ,
85
86
connection,
86
87
} ) ;
@@ -93,7 +94,7 @@ export class RNSignerClient extends BaseSignerClient<
93
94
args : Omit < OtpParams , "targetPublicKey" > ,
94
95
) : Promise < SubmitOtpCodeResponse > {
95
96
this . eventEmitter . emit ( "authenticating" , { type : "otpVerify" } ) ;
96
- const publicKey = await this . stamper . init ( ) ;
97
+ const publicKey = await this . initSessionStamper ( ) ;
97
98
98
99
const response = await this . request ( "/v1/otp" , {
99
100
...args ,
@@ -130,7 +131,7 @@ export class RNSignerClient extends BaseSignerClient<
130
131
params : Omit < EmailAuthParams , "targetPublicKey" > ,
131
132
) : Promise < { orgId : string ; otpId ?: string ; multiFactors ?: MfaFactor [ ] } > {
132
133
this . eventEmitter . emit ( "authenticating" , { type : "email" } ) ;
133
- const targetPublicKey = await this . stamper . init ( ) ;
134
+ const targetPublicKey = await this . initSessionStamper ( ) ;
134
135
135
136
try {
136
137
return await this . request ( "/v1/auth" , {
@@ -156,7 +157,7 @@ export class RNSignerClient extends BaseSignerClient<
156
157
) : Promise < { orgId : string ; otpId ?: string } > {
157
158
this . eventEmitter . emit ( "authenticating" , { type : "sms" } ) ;
158
159
const { phone } = params ;
159
- const targetPublicKey = await this . stamper . init ( ) ;
160
+ const targetPublicKey = await this . initSessionStamper ( ) ;
160
161
161
162
return this . request ( "/v1/auth" , {
162
163
phone,
@@ -169,7 +170,7 @@ export class RNSignerClient extends BaseSignerClient<
169
170
) : Promise < JwtResponse > {
170
171
this . eventEmitter . emit ( "authenticating" , { type : "custom-jwt" } ) ;
171
172
172
- const publicKey = await this . stamper . init ( ) ;
173
+ const publicKey = await this . initSessionStamper ( ) ;
173
174
return this . request ( "/v1/auth-jwt" , {
174
175
jwt : args . jwt ,
175
176
targetPublicKey : publicKey ,
@@ -194,9 +195,9 @@ export class RNSignerClient extends BaseSignerClient<
194
195
type : params . authenticatingType ,
195
196
} ) ;
196
197
197
- await this . stamper . init ( ) ;
198
+ await this . initSessionStamper ( ) ;
198
199
199
- const result = await this . stamper . injectCredentialBundle ( params . bundle ) ;
200
+ const result = await SESSION_STAMPER . injectCredentialBundle ( params . bundle ) ;
200
201
201
202
if ( ! result ) {
202
203
throw new Error ( "Failed to inject credential bundle" ) ;
@@ -223,7 +224,7 @@ export class RNSignerClient extends BaseSignerClient<
223
224
this . eventEmitter . emit ( "authenticating" , { type : "oauth" } ) ;
224
225
225
226
const oauthParams = args ;
226
- const turnkeyPublicKey = await this . stamper . init ( ) ;
227
+ const turnkeyPublicKey = await this . initSessionStamper ( ) ;
227
228
const oauthCallbackUrl = this . oauthCallbackUrl ;
228
229
const oauthConfig = await this . getOauthConfig ( ) ;
229
230
const providerUrl = await this . getOauthProviderUrl ( {
@@ -294,8 +295,8 @@ export class RNSignerClient extends BaseSignerClient<
294
295
295
296
override async disconnect ( ) : Promise < void > {
296
297
this . user = undefined ;
297
- this . stamper . clear ( ) ;
298
- await this . stamper . init ( ) ;
298
+ SESSION_STAMPER . clear ( ) ;
299
+ await this . initSessionStamper ( ) ;
299
300
}
300
301
301
302
/**
@@ -426,7 +427,7 @@ export class RNSignerClient extends BaseSignerClient<
426
427
}
427
428
428
429
override targetPublicKey ( ) : Promise < string > {
429
- return this . stamper . init ( ) ;
430
+ return this . initSessionStamper ( ) ;
430
431
}
431
432
432
433
protected override getWebAuthnAttestation = async (
@@ -461,14 +462,34 @@ export class RNSignerClient extends BaseSignerClient<
461
462
} ;
462
463
463
464
protected override getOauthConfig = async ( ) : Promise < OauthConfig > => {
464
- const publicKey = await this . stamper . init ( ) ;
465
+ const currentStamper = this . turnkeyClient . stamper ;
466
+ const publicKey = await this . initSessionStamper ( ) ;
465
467
468
+ // swap the stamper back in case the user logged in with a different stamper (passkeys)
469
+ this . setStamper ( currentStamper ) ;
466
470
const nonce = this . getOauthNonce ( publicKey ) ;
467
471
return this . request ( "/v1/prepare-oauth" , { nonce } ) ;
468
472
} ;
469
473
474
+ private initSessionStamperPromise : Promise < string > | null = null ;
475
+
470
476
protected override async initSessionStamper ( ) : Promise < string > {
471
- return this . stamper . init ( ) ;
477
+ if ( this . initSessionStamperPromise ) {
478
+ return this . initSessionStamperPromise ;
479
+ }
480
+
481
+ this . initSessionStamperPromise = ( async ( ) => {
482
+ await SESSION_STAMPER . init ( ) ;
483
+ this . setStamper ( SESSION_STAMPER ) ;
484
+ return SESSION_STAMPER . publicKey ( ) ! ;
485
+ } ) ( ) ;
486
+
487
+ try {
488
+ const result = await this . initSessionStamperPromise ;
489
+ return result ;
490
+ } finally {
491
+ this . initSessionStamperPromise = null ;
492
+ }
472
493
}
473
494
474
495
protected override async initWebauthnStamper (
0 commit comments