@0xsequence/wallet-wdk 3.0.2 → 3.0.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.
Files changed (47) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/CHANGELOG.md +12 -0
  5. package/dist/sequence/handlers/authcode.d.ts.map +1 -1
  6. package/dist/sequence/handlers/authcode.js +6 -0
  7. package/dist/sequence/handlers/identity.d.ts +1 -0
  8. package/dist/sequence/handlers/identity.d.ts.map +1 -1
  9. package/dist/sequence/handlers/identity.js +3 -0
  10. package/dist/sequence/handlers/idtoken.d.ts +33 -0
  11. package/dist/sequence/handlers/idtoken.d.ts.map +1 -0
  12. package/dist/sequence/handlers/idtoken.js +110 -0
  13. package/dist/sequence/handlers/index.d.ts +1 -0
  14. package/dist/sequence/handlers/index.d.ts.map +1 -1
  15. package/dist/sequence/handlers/index.js +1 -0
  16. package/dist/sequence/manager.d.ts +20 -14
  17. package/dist/sequence/manager.d.ts.map +1 -1
  18. package/dist/sequence/manager.js +21 -3
  19. package/dist/sequence/sessions.d.ts.map +1 -1
  20. package/dist/sequence/sessions.js +5 -1
  21. package/dist/sequence/signers.d.ts.map +1 -1
  22. package/dist/sequence/signers.js +4 -0
  23. package/dist/sequence/types/signer.d.ts +1 -1
  24. package/dist/sequence/types/signer.js +1 -1
  25. package/dist/sequence/types/wallet.d.ts +1 -1
  26. package/dist/sequence/wallets.d.ts +7 -1
  27. package/dist/sequence/wallets.d.ts.map +1 -1
  28. package/dist/sequence/wallets.js +69 -7
  29. package/package.json +6 -6
  30. package/src/sequence/handlers/authcode.ts +6 -0
  31. package/src/sequence/handlers/identity.ts +4 -0
  32. package/src/sequence/handlers/idtoken.ts +140 -0
  33. package/src/sequence/handlers/index.ts +1 -0
  34. package/src/sequence/manager.ts +78 -29
  35. package/src/sequence/sessions.ts +7 -1
  36. package/src/sequence/signers.ts +5 -0
  37. package/src/sequence/types/signer.ts +1 -1
  38. package/src/sequence/types/wallet.ts +1 -1
  39. package/src/sequence/wallets.ts +88 -9
  40. package/test/authcode-pkce.test.ts +1 -1
  41. package/test/authcode.test.ts +2 -2
  42. package/test/identity-auth-dbs.test.ts +86 -2
  43. package/test/identity-signer.test.ts +1 -1
  44. package/test/idtoken.test.ts +327 -0
  45. package/test/sessions-idtoken.test.ts +97 -0
  46. package/test/signers-kindof.test.ts +22 -0
  47. package/test/wallets.test.ts +141 -1
@@ -1,8 +1,38 @@
1
1
  import { Wallet as CoreWallet, Envelope, Signers, State } from '@0xsequence/wallet-core';
2
2
  import { Config, Constants, Payload } from '@0xsequence/wallet-primitives';
3
3
  import { Address, Provider, RpcTransport } from 'ox';
4
+ import { AuthCodeHandler } from './handlers/authcode.js';
5
+ import { IdTokenHandler } from './handlers/idtoken.js';
4
6
  import { MnemonicHandler } from './handlers/mnemonic.js';
5
7
  import { Kinds } from './types/signer.js';
8
+ function getSignupHandlerKey(kind) {
9
+ if (kind === 'google-pkce') {
10
+ return Kinds.LoginGoogle;
11
+ }
12
+ if (kind.startsWith('custom-')) {
13
+ return kind;
14
+ }
15
+ return 'login-' + kind;
16
+ }
17
+ function getSignerKindForSignup(kind) {
18
+ if (kind === 'google-id-token' || kind === 'google-pkce') {
19
+ return Kinds.LoginGoogle;
20
+ }
21
+ if (kind.startsWith('custom-')) {
22
+ return kind;
23
+ }
24
+ return ('login-' + kind);
25
+ }
26
+ function getIdTokenSignupHandler(shared, kind) {
27
+ const handler = shared.handlers.get(kind);
28
+ if (!handler) {
29
+ throw new Error('handler-not-registered');
30
+ }
31
+ if (!(handler instanceof IdTokenHandler)) {
32
+ throw new Error('handler-does-not-support-id-token');
33
+ }
34
+ return handler;
35
+ }
6
36
  export function isLoginToWalletArgs(args) {
7
37
  return 'wallet' in args;
8
38
  }
@@ -13,7 +43,10 @@ export function isLoginToPasskeyArgs(args) {
13
43
  return 'kind' in args && args.kind === 'passkey';
14
44
  }
15
45
  export function isAuthCodeArgs(args) {
16
- return 'kind' in args && (args.kind === 'google-pkce' || args.kind === 'apple');
46
+ return 'code' in args && 'commitment' in args;
47
+ }
48
+ export function isIdTokenArgs(args) {
49
+ return 'idToken' in args;
17
50
  }
18
51
  function buildCappedTree(members) {
19
52
  const loginMemberWeight = 1n;
@@ -277,9 +310,22 @@ export class Wallets {
277
310
  loginEmail: returnedEmail,
278
311
  };
279
312
  }
313
+ case 'google-id-token': {
314
+ const handler = getIdTokenSignupHandler(this.shared, Kinds.LoginGoogle);
315
+ const [signer, metadata] = await handler.completeAuth(args.idToken);
316
+ const loginEmail = metadata.email;
317
+ this.shared.modules.logger.log('Created new id token signer:', signer.address);
318
+ return {
319
+ signer,
320
+ extra: {
321
+ signerKind: Kinds.LoginGoogle,
322
+ },
323
+ loginEmail,
324
+ };
325
+ }
280
326
  case 'google-pkce':
281
327
  case 'apple': {
282
- const handler = this.shared.handlers.get('login-' + args.kind);
328
+ const handler = this.shared.handlers.get(getSignupHandlerKey(args.kind));
283
329
  if (!handler) {
284
330
  throw new Error('handler-not-registered');
285
331
  }
@@ -289,14 +335,24 @@ export class Wallets {
289
335
  return {
290
336
  signer,
291
337
  extra: {
292
- signerKind: 'login-' + args.kind,
338
+ signerKind: getSignerKindForSignup(args.kind),
293
339
  },
294
340
  loginEmail,
295
341
  };
296
342
  }
297
343
  }
298
344
  if (args.kind.startsWith('custom-')) {
299
- // TODO: support other custom auth methods (e.g. id-token)
345
+ if (isIdTokenArgs(args)) {
346
+ const handler = getIdTokenSignupHandler(this.shared, args.kind);
347
+ const [signer, metadata] = await handler.completeAuth(args.idToken);
348
+ return {
349
+ signer,
350
+ extra: {
351
+ signerKind: args.kind,
352
+ },
353
+ loginEmail: metadata.email,
354
+ };
355
+ }
300
356
  const handler = this.shared.handlers.get(args.kind);
301
357
  if (!handler) {
302
358
  throw new Error('handler-not-registered');
@@ -313,11 +369,14 @@ export class Wallets {
313
369
  throw new Error('invalid-signup-kind');
314
370
  }
315
371
  async startSignUpWithRedirect(args) {
316
- const kind = args.kind.startsWith('custom-') ? args.kind : 'login-' + args.kind;
372
+ const kind = getSignupHandlerKey(args.kind);
317
373
  const handler = this.shared.handlers.get(kind);
318
374
  if (!handler) {
319
375
  throw new Error('handler-not-registered');
320
376
  }
377
+ if (!(handler instanceof AuthCodeHandler)) {
378
+ throw new Error('handler-does-not-support-redirect');
379
+ }
321
380
  return handler.commitAuth(args.target, true);
322
381
  }
323
382
  async completeRedirect(args) {
@@ -338,11 +397,14 @@ export class Wallets {
338
397
  });
339
398
  }
340
399
  else {
341
- const kind = commitment.kind.startsWith('custom-') ? commitment.kind : 'login-' + commitment.kind;
342
- const handler = this.shared.handlers.get(kind);
400
+ const handlerKind = getSignupHandlerKey(commitment.kind);
401
+ const handler = this.shared.handlers.get(handlerKind);
343
402
  if (!handler) {
344
403
  throw new Error('handler-not-registered');
345
404
  }
405
+ if (!(handler instanceof AuthCodeHandler)) {
406
+ throw new Error('handler-does-not-support-redirect');
407
+ }
346
408
  await handler.completeAuth(commitment, args.code);
347
409
  }
348
410
  if (!commitment.target) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xsequence/wallet-wdk",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -30,11 +30,11 @@
30
30
  "jwt-decode": "^4.0.0",
31
31
  "ox": "^0.9.17",
32
32
  "uuid": "^13.0.0",
33
- "@0xsequence/guard": "^3.0.2",
34
- "@0xsequence/relayer": "^3.0.2",
35
- "@0xsequence/identity-instrument": "^3.0.2",
36
- "@0xsequence/wallet-primitives": "^3.0.2",
37
- "@0xsequence/wallet-core": "^3.0.2"
33
+ "@0xsequence/relayer": "^3.0.3",
34
+ "@0xsequence/guard": "^3.0.3",
35
+ "@0xsequence/identity-instrument": "^3.0.3",
36
+ "@0xsequence/wallet-core": "^3.0.3",
37
+ "@0xsequence/wallet-primitives": "^3.0.3"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "tsc",
@@ -6,6 +6,7 @@ import * as Identity from '@0xsequence/identity-instrument'
6
6
  import { SignerUnavailable, SignerReady, SignerActionable, BaseSignatureRequest } from '../types/signature-request.js'
7
7
  import { IdentitySigner } from '../../identity/signer.js'
8
8
  import { IdentityHandler } from './identity.js'
9
+ import { Kinds } from '../types/signer.js'
9
10
  import type { NavigationLike, WdkEnv } from '../../env.js'
10
11
 
11
12
  export class AuthCodeHandler extends IdentityHandler implements Handler {
@@ -26,6 +27,11 @@ export class AuthCodeHandler extends IdentityHandler implements Handler {
26
27
  }
27
28
 
28
29
  public get kind() {
30
+ if (this.signupKind === 'google-pkce') {
31
+ // Keep Google PKCE on the canonical kind so Google signers created before
32
+ // canonicalization still resolve as `login-google`.
33
+ return Kinds.LoginGoogle
34
+ }
29
35
  return 'login-' + this.signupKind
30
36
  }
31
37
 
@@ -81,6 +81,10 @@ export class IdentityHandler {
81
81
  return new IdentitySigner(this.nitro, authKey, this.env.crypto)
82
82
  }
83
83
 
84
+ protected async clearAuthKeySigner(address: string): Promise<void> {
85
+ await this.authKeys.delBySigner(address)
86
+ }
87
+
84
88
  private async getAuthKey(signer: string): Promise<Db.AuthKey | undefined> {
85
89
  let authKey = await this.authKeys.getBySigner(signer)
86
90
  if (!signer && !authKey) {
@@ -0,0 +1,140 @@
1
+ import { Address, Hex } from 'ox'
2
+ import { Signers } from '@0xsequence/wallet-core'
3
+ import { Handler } from './handler.js'
4
+ import * as Identity from '@0xsequence/identity-instrument'
5
+ import * as Db from '../../dbs/index.js'
6
+ import { Signatures } from '../signatures.js'
7
+ import { SignerActionable, SignerReady, SignerUnavailable, BaseSignatureRequest } from '../types/signature-request.js'
8
+ import { IdentitySigner } from '../../identity/signer.js'
9
+ import { IdentityHandler } from './identity.js'
10
+ import { Kinds } from '../types/signer.js'
11
+ import type { WdkEnv } from '../../env.js'
12
+
13
+ type RespondFn = (idToken: string) => Promise<void>
14
+
15
+ export type PromptIdTokenHandler = (kind: 'google-id-token' | `custom-${string}`, respond: RespondFn) => Promise<void>
16
+
17
+ export class IdTokenHandler extends IdentityHandler implements Handler {
18
+ private onPromptIdToken: undefined | PromptIdTokenHandler
19
+
20
+ constructor(
21
+ public readonly signupKind: 'google-id-token' | `custom-${string}`,
22
+ public readonly issuer: string,
23
+ public readonly audience: string,
24
+ nitro: Identity.IdentityInstrument,
25
+ signatures: Signatures,
26
+ authKeys: Db.AuthKeys,
27
+ env?: WdkEnv,
28
+ ) {
29
+ super(nitro, authKeys, signatures, Identity.IdentityType.OIDC, env)
30
+ }
31
+
32
+ public get kind() {
33
+ if (this.signupKind === 'google-id-token') {
34
+ return Kinds.LoginGoogle
35
+ }
36
+ return 'login-' + this.signupKind
37
+ }
38
+
39
+ public registerUI(onPromptIdToken: PromptIdTokenHandler) {
40
+ this.onPromptIdToken = onPromptIdToken
41
+ return () => {
42
+ this.onPromptIdToken = undefined
43
+ }
44
+ }
45
+
46
+ public unregisterUI() {
47
+ this.onPromptIdToken = undefined
48
+ }
49
+
50
+ public async completeAuth(idToken: string): Promise<[IdentitySigner, { [key: string]: string }]> {
51
+ const challenge = new Identity.IdTokenChallenge(this.issuer, this.audience, idToken)
52
+ await this.nitroCommitVerifier(challenge)
53
+ const { signer: identitySigner, email } = await this.nitroCompleteAuth(challenge)
54
+
55
+ return [identitySigner, { email }]
56
+ }
57
+
58
+ public async getSigner(): Promise<{ signer: Signers.Signer & Signers.Witnessable; email: string }> {
59
+ const onPromptIdToken = this.onPromptIdToken
60
+ if (!onPromptIdToken) {
61
+ throw new Error('id-token-handler-ui-not-registered')
62
+ }
63
+
64
+ return await this.handleAuth(onPromptIdToken)
65
+ }
66
+
67
+ async status(
68
+ address: Address.Address,
69
+ _imageHash: Hex.Hex | undefined,
70
+ request: BaseSignatureRequest,
71
+ ): Promise<SignerUnavailable | SignerReady | SignerActionable> {
72
+ const signer = await this.getAuthKeySigner(address)
73
+ if (signer) {
74
+ return {
75
+ address,
76
+ handler: this,
77
+ status: 'ready',
78
+ handle: async () => {
79
+ await this.sign(signer, request)
80
+ return true
81
+ },
82
+ }
83
+ }
84
+
85
+ const onPromptIdToken = this.onPromptIdToken
86
+ if (!onPromptIdToken) {
87
+ return {
88
+ address,
89
+ handler: this,
90
+ reason: 'ui-not-registered',
91
+ status: 'unavailable',
92
+ }
93
+ }
94
+
95
+ return {
96
+ address,
97
+ handler: this,
98
+ status: 'actionable',
99
+ message: 'request-id-token',
100
+ handle: async () => {
101
+ try {
102
+ const { signer } = await this.handleAuth(onPromptIdToken)
103
+ const signerAddress = (await signer.address) as Address.Address
104
+ if (!Address.isEqual(signerAddress, address)) {
105
+ // ID-token auth prompts are keyed by provider kind, not the requested signer address.
106
+ // For example, a user can pick a different Google account in the account picker and
107
+ // return a token for a different identity than this request expects.
108
+ await this.clearAuthKeySigner(signerAddress)
109
+ throw new Error('id-token-signer-mismatch')
110
+ }
111
+ return true
112
+ } catch {
113
+ return false
114
+ }
115
+ },
116
+ }
117
+ }
118
+
119
+ private handleAuth(
120
+ onPromptIdToken: PromptIdTokenHandler,
121
+ ): Promise<{ signer: Signers.Signer & Signers.Witnessable; email: string }> {
122
+ // eslint-disable-next-line no-async-promise-executor
123
+ return new Promise(async (resolve, reject) => {
124
+ try {
125
+ const respond: RespondFn = async (idToken) => {
126
+ try {
127
+ const [signer, metadata] = await this.completeAuth(idToken)
128
+ resolve({ signer, email: metadata.email || '' })
129
+ } catch (error) {
130
+ reject(error)
131
+ }
132
+ }
133
+
134
+ await onPromptIdToken(this.signupKind, respond)
135
+ } catch (error) {
136
+ reject(error)
137
+ }
138
+ })
139
+ }
140
+ }
@@ -3,4 +3,5 @@ export { DevicesHandler } from './devices.js'
3
3
  export { PasskeysHandler } from './passkeys.js'
4
4
  export { OtpHandler } from './otp.js'
5
5
  export { AuthCodePkceHandler } from './authcode-pkce.js'
6
+ export { IdTokenHandler } from './idtoken.js'
6
7
  export { MnemonicHandler } from './mnemonic.js'
@@ -14,6 +14,7 @@ import {
14
14
  AuthCodePkceHandler,
15
15
  DevicesHandler,
16
16
  Handler,
17
+ IdTokenHandler,
17
18
  MnemonicHandler,
18
19
  OtpHandler,
19
20
  PasskeysHandler,
@@ -31,9 +32,25 @@ import { Wallets, WalletsInterface } from './wallets.js'
31
32
  import { GuardHandler, PromptCodeHandler } from './handlers/guard.js'
32
33
  import { PasskeyCredential } from '../dbs/index.js'
33
34
  import { PromptMnemonicHandler } from './handlers/mnemonic.js'
35
+ import { PromptIdTokenHandler } from './handlers/idtoken.js'
34
36
  import { PromptOtpHandler } from './handlers/otp.js'
35
37
  import { defaultPasskeyProvider, type PasskeyProvider } from './passkeys-provider.js'
36
38
 
39
+ type CustomIdentityProvider =
40
+ | {
41
+ kind: `custom-${string}`
42
+ authMethod: 'id-token'
43
+ issuer: string
44
+ clientId: string
45
+ }
46
+ | {
47
+ kind: `custom-${string}`
48
+ authMethod: 'authcode' | 'authcode-pkce'
49
+ issuer: string
50
+ oauthUrl: string
51
+ clientId: string
52
+ }
53
+
37
54
  export type ManagerOptions = {
38
55
  verbose?: boolean
39
56
 
@@ -85,18 +102,13 @@ export type ManagerOptions = {
85
102
  google?: {
86
103
  enabled: boolean
87
104
  clientId: string
105
+ authMethod?: 'authcode-pkce' | 'id-token'
88
106
  }
89
107
  apple?: {
90
108
  enabled: boolean
91
109
  clientId: string
92
110
  }
93
- customProviders?: {
94
- kind: `custom-${string}`
95
- authMethod: 'id-token' | 'authcode' | 'authcode-pkce'
96
- issuer: string
97
- oauthUrl: string
98
- clientId: string
99
- }[]
111
+ customProviders?: CustomIdentityProvider[]
100
112
  }
101
113
  }
102
114
 
@@ -112,18 +124,13 @@ export type ResolvedIdentityOptions = {
112
124
  google: {
113
125
  enabled: boolean
114
126
  clientId: string
127
+ authMethod: 'authcode-pkce' | 'id-token'
115
128
  }
116
129
  apple: {
117
130
  enabled: boolean
118
131
  clientId: string
119
132
  }
120
- customProviders?: {
121
- kind: `custom-${string}`
122
- authMethod: 'id-token' | 'authcode' | 'authcode-pkce'
123
- issuer: string
124
- oauthUrl: string
125
- clientId: string
126
- }[]
133
+ customProviders?: CustomIdentityProvider[]
127
134
  }
128
135
 
129
136
  export type ResolvedManagerOptions = {
@@ -248,6 +255,7 @@ export const ManagerOptionsDefaults = {
248
255
  google: {
249
256
  enabled: false,
250
257
  clientId: '',
258
+ authMethod: 'authcode-pkce' as const,
251
259
  },
252
260
  apple: {
253
261
  enabled: false,
@@ -677,20 +685,35 @@ export class Manager {
677
685
  shared.handlers.set(Kinds.LoginEmailOtp, this.otpHandler)
678
686
  }
679
687
  if (ops.identity.google?.enabled) {
680
- shared.handlers.set(
681
- Kinds.LoginGooglePkce,
682
- new AuthCodePkceHandler(
683
- 'google-pkce',
684
- 'https://accounts.google.com',
685
- 'https://accounts.google.com/o/oauth2/v2/auth',
686
- ops.identity.google.clientId,
687
- identityInstrument,
688
- modules.signatures,
689
- shared.databases.authCommitments,
690
- shared.databases.authKeys,
691
- shared.env,
692
- ),
693
- )
688
+ if (ops.identity.google.authMethod === 'id-token') {
689
+ shared.handlers.set(
690
+ Kinds.LoginGoogle,
691
+ new IdTokenHandler(
692
+ 'google-id-token',
693
+ 'https://accounts.google.com',
694
+ ops.identity.google.clientId,
695
+ identityInstrument,
696
+ modules.signatures,
697
+ shared.databases.authKeys,
698
+ shared.env,
699
+ ),
700
+ )
701
+ } else {
702
+ shared.handlers.set(
703
+ Kinds.LoginGoogle,
704
+ new AuthCodePkceHandler(
705
+ 'google-pkce',
706
+ 'https://accounts.google.com',
707
+ 'https://accounts.google.com/o/oauth2/v2/auth',
708
+ ops.identity.google.clientId,
709
+ identityInstrument,
710
+ modules.signatures,
711
+ shared.databases.authCommitments,
712
+ shared.databases.authKeys,
713
+ shared.env,
714
+ ),
715
+ )
716
+ }
694
717
  }
695
718
  if (ops.identity.apple?.enabled) {
696
719
  shared.handlers.set(
@@ -712,7 +735,19 @@ export class Manager {
712
735
  for (const provider of ops.identity.customProviders) {
713
736
  switch (provider.authMethod) {
714
737
  case 'id-token':
715
- throw new Error('id-token is not supported yet')
738
+ shared.handlers.set(
739
+ provider.kind,
740
+ new IdTokenHandler(
741
+ provider.kind,
742
+ provider.issuer,
743
+ provider.clientId,
744
+ identityInstrument,
745
+ modules.signatures,
746
+ shared.databases.authKeys,
747
+ shared.env,
748
+ ),
749
+ )
750
+ break
716
751
  case 'authcode':
717
752
  shared.handlers.set(
718
753
  provider.kind,
@@ -770,6 +805,20 @@ export class Manager {
770
805
  return this.otpHandler?.registerUI(onPromptOtp) || (() => {})
771
806
  }
772
807
 
808
+ public registerIdTokenUI(onPromptIdToken: PromptIdTokenHandler) {
809
+ const unregisters: (() => void)[] = []
810
+
811
+ this.shared.handlers.forEach((handler) => {
812
+ if (handler instanceof IdTokenHandler) {
813
+ unregisters.push(handler.registerUI(onPromptIdToken))
814
+ }
815
+ })
816
+
817
+ return () => {
818
+ unregisters.forEach((unregister) => unregister())
819
+ }
820
+ }
821
+
773
822
  public registerGuardUI(onPromptCode: PromptCodeHandler) {
774
823
  return this.guardHandler?.registerUI(onPromptCode) || (() => {})
775
824
  }
@@ -9,7 +9,9 @@ import {
9
9
  SessionConfig,
10
10
  } from '@0xsequence/wallet-primitives'
11
11
  import { Address, Bytes, Hash, Hex } from 'ox'
12
+ import { AuthCodeHandler } from './handlers/authcode.js'
12
13
  import { AuthCodePkceHandler } from './handlers/authcode-pkce.js'
14
+ import { IdTokenHandler } from './handlers/idtoken.js'
13
15
  import { IdentityHandler, identityTypeToHex } from './handlers/identity.js'
14
16
  import { Handler } from './handlers/index.js'
15
17
  import { ManagerOptionsDefaults, Shared } from './manager.js'
@@ -362,7 +364,11 @@ export class Sessions implements SessionsInterface {
362
364
  let audienceHash: Hex.Hex = '0x'
363
365
  if (handler instanceof IdentityHandler) {
364
366
  identityType = handler.identityType
365
- if (handler instanceof AuthCodePkceHandler) {
367
+ if (
368
+ handler instanceof AuthCodeHandler ||
369
+ handler instanceof AuthCodePkceHandler ||
370
+ handler instanceof IdTokenHandler
371
+ ) {
366
372
  issuerHash = Hash.keccak256(Hex.fromString(handler.issuer))
367
373
  audienceHash = Hash.keccak256(Hex.fromString(handler.audience))
368
374
  }
@@ -12,6 +12,11 @@ function toKnownKind(kind: string): Kind {
12
12
  return kind as Kind
13
13
  }
14
14
 
15
+ if (kind === 'login-google-pkce') {
16
+ // Normalize legacy Google PKCE witnesses while the canonical signer kind is `login-google`.
17
+ return Kinds.LoginGoogle
18
+ }
19
+
15
20
  if (Object.values(Kinds).includes(kind as (typeof Kinds)[keyof typeof Kinds])) {
16
21
  return kind as Kind
17
22
  }
@@ -5,7 +5,7 @@ export const Kinds = {
5
5
  LoginPasskey: 'login-passkey',
6
6
  LoginMnemonic: 'login-mnemonic', // Todo: do not name it login-mnemonic, just mnemonic
7
7
  LoginEmailOtp: 'login-email-otp',
8
- LoginGooglePkce: 'login-google-pkce',
8
+ LoginGoogle: 'login-google',
9
9
  LoginApple: 'login-apple',
10
10
  Recovery: 'recovery-extension',
11
11
  Guard: 'guard-extension',
@@ -36,7 +36,7 @@ export interface Wallet {
36
36
 
37
37
  /**
38
38
  * A string identifier for the authentication method used for this session.
39
- * Examples: 'login-mnemonic', 'login-passkey', 'login-google-pkce'.
39
+ * Examples: 'login-mnemonic', 'login-passkey', 'login-google'.
40
40
  * @property
41
41
  */
42
42
  loginType: string