@0xsequence/wallet-wdk 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +24 -0
- package/dist/sequence/handlers/authcode.d.ts.map +1 -1
- package/dist/sequence/handlers/authcode.js +6 -0
- package/dist/sequence/handlers/identity.d.ts +1 -0
- package/dist/sequence/handlers/identity.d.ts.map +1 -1
- package/dist/sequence/handlers/identity.js +3 -0
- package/dist/sequence/handlers/idtoken.d.ts +33 -0
- package/dist/sequence/handlers/idtoken.d.ts.map +1 -0
- package/dist/sequence/handlers/idtoken.js +113 -0
- package/dist/sequence/handlers/index.d.ts +1 -0
- package/dist/sequence/handlers/index.d.ts.map +1 -1
- package/dist/sequence/handlers/index.js +1 -0
- package/dist/sequence/manager.d.ts +23 -14
- package/dist/sequence/manager.d.ts.map +1 -1
- package/dist/sequence/manager.js +28 -4
- package/dist/sequence/sessions.d.ts.map +1 -1
- package/dist/sequence/sessions.js +5 -1
- package/dist/sequence/signers.d.ts.map +1 -1
- package/dist/sequence/signers.js +4 -0
- package/dist/sequence/types/signer.d.ts +1 -1
- package/dist/sequence/types/signer.js +1 -1
- package/dist/sequence/types/wallet.d.ts +1 -1
- package/dist/sequence/wallets.d.ts +7 -1
- package/dist/sequence/wallets.d.ts.map +1 -1
- package/dist/sequence/wallets.js +73 -7
- package/package.json +6 -6
- package/src/sequence/handlers/authcode.ts +6 -0
- package/src/sequence/handlers/identity.ts +4 -0
- package/src/sequence/handlers/idtoken.ts +146 -0
- package/src/sequence/handlers/index.ts +1 -0
- package/src/sequence/manager.ts +110 -43
- package/src/sequence/sessions.ts +7 -1
- package/src/sequence/signers.ts +5 -0
- package/src/sequence/types/signer.ts +1 -1
- package/src/sequence/types/wallet.ts +1 -1
- package/src/sequence/wallets.ts +98 -9
- package/test/authcode-pkce.test.ts +1 -1
- package/test/authcode.test.ts +2 -2
- package/test/identity-auth-dbs.test.ts +122 -2
- package/test/identity-signer.test.ts +1 -1
- package/test/idtoken.test.ts +343 -0
- package/test/sessions-idtoken.test.ts +98 -0
- package/test/signers-kindof.test.ts +22 -0
- package/test/wallets.test.ts +202 -1
package/src/sequence/wallets.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Config, Constants, Payload } from '@0xsequence/wallet-primitives'
|
|
|
3
3
|
import { Address, Hex, Provider, RpcTransport } from 'ox'
|
|
4
4
|
import { AuthCommitment } from '../dbs/auth-commitments.js'
|
|
5
5
|
import { AuthCodeHandler } from './handlers/authcode.js'
|
|
6
|
+
import { IdTokenHandler } from './handlers/idtoken.js'
|
|
6
7
|
import { MnemonicHandler } from './handlers/mnemonic.js'
|
|
7
8
|
import { OtpHandler } from './handlers/otp.js'
|
|
8
9
|
import { Shared } from './manager.js'
|
|
@@ -13,6 +14,43 @@ import { Wallet, WalletSelectionUiHandler } from './types/wallet.js'
|
|
|
13
14
|
import { PasskeysHandler } from './handlers/passkeys.js'
|
|
14
15
|
import type { PasskeySigner } from './passkeys-provider.js'
|
|
15
16
|
|
|
17
|
+
function getSignupHandlerKey(kind: SignupArgs['kind'] | StartSignUpWithRedirectArgs['kind'] | AuthCommitment['kind']) {
|
|
18
|
+
if (kind === 'google-pkce') {
|
|
19
|
+
return Kinds.LoginGoogle
|
|
20
|
+
}
|
|
21
|
+
if (kind.startsWith('custom-')) {
|
|
22
|
+
return kind
|
|
23
|
+
}
|
|
24
|
+
return 'login-' + kind
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getSignerKindForSignup(kind: SignupArgs['kind'] | AuthCommitment['kind']) {
|
|
28
|
+
if (kind === 'google-id-token' || kind === 'google-pkce') {
|
|
29
|
+
return Kinds.LoginGoogle
|
|
30
|
+
}
|
|
31
|
+
if (kind === 'apple-id-token' || kind === 'apple') {
|
|
32
|
+
return Kinds.LoginApple
|
|
33
|
+
}
|
|
34
|
+
if (kind.startsWith('custom-')) {
|
|
35
|
+
return kind
|
|
36
|
+
}
|
|
37
|
+
return ('login-' + kind) as string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getIdTokenSignupHandler(
|
|
41
|
+
shared: Shared,
|
|
42
|
+
kind: typeof Kinds.LoginGoogle | typeof Kinds.LoginApple | `custom-${string}`,
|
|
43
|
+
): IdTokenHandler {
|
|
44
|
+
const handler = shared.handlers.get(kind)
|
|
45
|
+
if (!handler) {
|
|
46
|
+
throw new Error('handler-not-registered')
|
|
47
|
+
}
|
|
48
|
+
if (!(handler instanceof IdTokenHandler)) {
|
|
49
|
+
throw new Error('handler-does-not-support-id-token')
|
|
50
|
+
}
|
|
51
|
+
return handler
|
|
52
|
+
}
|
|
53
|
+
|
|
16
54
|
export type StartSignUpWithRedirectArgs = {
|
|
17
55
|
kind: 'google-pkce' | 'apple' | `custom-${string}`
|
|
18
56
|
target: string
|
|
@@ -49,6 +87,11 @@ export type EmailOtpSignupArgs = CommonSignupArgs & {
|
|
|
49
87
|
email: string
|
|
50
88
|
}
|
|
51
89
|
|
|
90
|
+
export type IdTokenSignupArgs = CommonSignupArgs & {
|
|
91
|
+
kind: 'google-id-token' | 'apple-id-token' | `custom-${string}`
|
|
92
|
+
idToken: string
|
|
93
|
+
}
|
|
94
|
+
|
|
52
95
|
export type CompleteRedirectArgs = CommonSignupArgs & {
|
|
53
96
|
state: string
|
|
54
97
|
code: string
|
|
@@ -62,7 +105,12 @@ export type AuthCodeSignupArgs = CommonSignupArgs & {
|
|
|
62
105
|
isRedirect: boolean
|
|
63
106
|
}
|
|
64
107
|
|
|
65
|
-
export type SignupArgs =
|
|
108
|
+
export type SignupArgs =
|
|
109
|
+
| PasskeySignupArgs
|
|
110
|
+
| MnemonicSignupArgs
|
|
111
|
+
| EmailOtpSignupArgs
|
|
112
|
+
| IdTokenSignupArgs
|
|
113
|
+
| AuthCodeSignupArgs
|
|
66
114
|
|
|
67
115
|
export type LoginToWalletArgs = {
|
|
68
116
|
wallet: Address.Address
|
|
@@ -180,6 +228,7 @@ export interface WalletsInterface {
|
|
|
180
228
|
* - `kind: 'mnemonic'`: Uses a mnemonic phrase as the login credential.
|
|
181
229
|
* - `kind: 'passkey'`: Prompts the user to create a WebAuthn passkey.
|
|
182
230
|
* - `kind: 'email-otp'`: Initiates an OTP flow to the user's email.
|
|
231
|
+
* - `kind: 'google-id-token' | 'apple-id-token'`: Completes an OIDC ID token flow when the provider is configured with `authMethod: 'id-token'`.
|
|
183
232
|
* - `kind: 'google-pkce' | 'apple'`: Completes an OAuth redirect flow.
|
|
184
233
|
* Common options like `noGuard` or `noRecovery` can customize the wallet's security features.
|
|
185
234
|
* @returns A promise that resolves to the address of the newly created wallet, or `undefined` if the sign-up was aborted.
|
|
@@ -361,7 +410,11 @@ export function isLoginToPasskeyArgs(args: LoginArgs): args is LoginToPasskeyArg
|
|
|
361
410
|
}
|
|
362
411
|
|
|
363
412
|
export function isAuthCodeArgs(args: SignupArgs): args is AuthCodeSignupArgs {
|
|
364
|
-
return '
|
|
413
|
+
return 'code' in args && 'commitment' in args
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export function isIdTokenArgs(args: SignupArgs): args is IdTokenSignupArgs {
|
|
417
|
+
return 'idToken' in args
|
|
365
418
|
}
|
|
366
419
|
|
|
367
420
|
function buildCappedTree(members: { address: Address.Address; imageHash?: Hex.Hex }[]): Config.Topology {
|
|
@@ -674,9 +727,28 @@ export class Wallets implements WalletsInterface {
|
|
|
674
727
|
}
|
|
675
728
|
}
|
|
676
729
|
|
|
730
|
+
case 'google-id-token':
|
|
731
|
+
case 'apple-id-token': {
|
|
732
|
+
const handler = getIdTokenSignupHandler(
|
|
733
|
+
this.shared,
|
|
734
|
+
args.kind === 'google-id-token' ? Kinds.LoginGoogle : Kinds.LoginApple,
|
|
735
|
+
)
|
|
736
|
+
const [signer, metadata] = await handler.completeAuth(args.idToken)
|
|
737
|
+
const loginEmail = metadata.email
|
|
738
|
+
this.shared.modules.logger.log('Created new id token signer:', signer.address)
|
|
739
|
+
|
|
740
|
+
return {
|
|
741
|
+
signer,
|
|
742
|
+
extra: {
|
|
743
|
+
signerKind: getSignerKindForSignup(args.kind),
|
|
744
|
+
},
|
|
745
|
+
loginEmail,
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
677
749
|
case 'google-pkce':
|
|
678
750
|
case 'apple': {
|
|
679
|
-
const handler = this.shared.handlers.get(
|
|
751
|
+
const handler = this.shared.handlers.get(getSignupHandlerKey(args.kind)) as AuthCodeHandler
|
|
680
752
|
if (!handler) {
|
|
681
753
|
throw new Error('handler-not-registered')
|
|
682
754
|
}
|
|
@@ -688,7 +760,7 @@ export class Wallets implements WalletsInterface {
|
|
|
688
760
|
return {
|
|
689
761
|
signer,
|
|
690
762
|
extra: {
|
|
691
|
-
signerKind:
|
|
763
|
+
signerKind: getSignerKindForSignup(args.kind),
|
|
692
764
|
},
|
|
693
765
|
loginEmail,
|
|
694
766
|
}
|
|
@@ -696,7 +768,18 @@ export class Wallets implements WalletsInterface {
|
|
|
696
768
|
}
|
|
697
769
|
|
|
698
770
|
if (args.kind.startsWith('custom-')) {
|
|
699
|
-
|
|
771
|
+
if (isIdTokenArgs(args)) {
|
|
772
|
+
const handler = getIdTokenSignupHandler(this.shared, args.kind)
|
|
773
|
+
const [signer, metadata] = await handler.completeAuth(args.idToken)
|
|
774
|
+
return {
|
|
775
|
+
signer,
|
|
776
|
+
extra: {
|
|
777
|
+
signerKind: args.kind,
|
|
778
|
+
},
|
|
779
|
+
loginEmail: metadata.email,
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
700
783
|
const handler = this.shared.handlers.get(args.kind) as AuthCodeHandler
|
|
701
784
|
if (!handler) {
|
|
702
785
|
throw new Error('handler-not-registered')
|
|
@@ -716,11 +799,14 @@ export class Wallets implements WalletsInterface {
|
|
|
716
799
|
}
|
|
717
800
|
|
|
718
801
|
async startSignUpWithRedirect(args: StartSignUpWithRedirectArgs) {
|
|
719
|
-
const kind = args.kind
|
|
720
|
-
const handler = this.shared.handlers.get(kind)
|
|
802
|
+
const kind = getSignupHandlerKey(args.kind)
|
|
803
|
+
const handler = this.shared.handlers.get(kind)
|
|
721
804
|
if (!handler) {
|
|
722
805
|
throw new Error('handler-not-registered')
|
|
723
806
|
}
|
|
807
|
+
if (!(handler instanceof AuthCodeHandler)) {
|
|
808
|
+
throw new Error('handler-does-not-support-redirect')
|
|
809
|
+
}
|
|
724
810
|
return handler.commitAuth(args.target, true)
|
|
725
811
|
}
|
|
726
812
|
|
|
@@ -742,11 +828,14 @@ export class Wallets implements WalletsInterface {
|
|
|
742
828
|
use4337: args.use4337,
|
|
743
829
|
})
|
|
744
830
|
} else {
|
|
745
|
-
const
|
|
746
|
-
const handler = this.shared.handlers.get(
|
|
831
|
+
const handlerKind = getSignupHandlerKey(commitment.kind)
|
|
832
|
+
const handler = this.shared.handlers.get(handlerKind)
|
|
747
833
|
if (!handler) {
|
|
748
834
|
throw new Error('handler-not-registered')
|
|
749
835
|
}
|
|
836
|
+
if (!(handler instanceof AuthCodeHandler)) {
|
|
837
|
+
throw new Error('handler-does-not-support-redirect')
|
|
838
|
+
}
|
|
750
839
|
|
|
751
840
|
await handler.completeAuth(commitment, args.code)
|
|
752
841
|
}
|
|
@@ -326,7 +326,7 @@ describe('AuthCodePkceHandler', () => {
|
|
|
326
326
|
|
|
327
327
|
describe('Integration and Edge Cases', () => {
|
|
328
328
|
it('Should have correct kind property', () => {
|
|
329
|
-
expect(handler.kind).toBe('login-google
|
|
329
|
+
expect(handler.kind).toBe('login-google')
|
|
330
330
|
})
|
|
331
331
|
|
|
332
332
|
it('Should handle redirect URI configuration', () => {
|
package/test/authcode.test.ts
CHANGED
|
@@ -188,7 +188,7 @@ describe('AuthCodeHandler', () => {
|
|
|
188
188
|
// === KIND GETTER ===
|
|
189
189
|
|
|
190
190
|
describe('kind getter', () => {
|
|
191
|
-
it('Should return login-google
|
|
191
|
+
it('Should return login-google for Google PKCE handler', () => {
|
|
192
192
|
const googleHandler = new AuthCodeHandler(
|
|
193
193
|
'google-pkce',
|
|
194
194
|
'https://accounts.google.com',
|
|
@@ -200,7 +200,7 @@ describe('AuthCodeHandler', () => {
|
|
|
200
200
|
mockAuthKeys,
|
|
201
201
|
)
|
|
202
202
|
|
|
203
|
-
expect(googleHandler.kind).toBe('login-google
|
|
203
|
+
expect(googleHandler.kind).toBe('login-google')
|
|
204
204
|
})
|
|
205
205
|
|
|
206
206
|
it('Should return login-apple for Apple handler', () => {
|
|
@@ -351,9 +351,84 @@ describe('Identity Authentication Databases', () => {
|
|
|
351
351
|
},
|
|
352
352
|
})
|
|
353
353
|
|
|
354
|
-
// Verify that Google
|
|
354
|
+
// Verify that Google is registered under the canonical signer kind while
|
|
355
|
+
// still using the PKCE flow by default.
|
|
355
356
|
const handlers = (manager as any).shared.handlers
|
|
356
|
-
expect(handlers.has('login-google
|
|
357
|
+
expect(handlers.has('login-google')).toBe(true)
|
|
358
|
+
expect(handlers.has('login-google-pkce')).toBe(false)
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
it('Should register the Google ID token handler when configured explicitly', async () => {
|
|
362
|
+
manager = new Manager({
|
|
363
|
+
stateProvider: new State.Local.Provider(new State.Local.IndexedDbStore(`manager-google-idtoken-${Date.now()}`)),
|
|
364
|
+
networks: [
|
|
365
|
+
{
|
|
366
|
+
name: 'Test Network',
|
|
367
|
+
type: Network.NetworkType.MAINNET,
|
|
368
|
+
rpcUrl: LOCAL_RPC_URL,
|
|
369
|
+
chainId: Network.ChainId.ARBITRUM,
|
|
370
|
+
blockExplorer: { url: 'https://arbiscan.io' },
|
|
371
|
+
nativeCurrency: {
|
|
372
|
+
name: 'Ether',
|
|
373
|
+
symbol: 'ETH',
|
|
374
|
+
decimals: 18,
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
relayers: [],
|
|
379
|
+
authCommitmentsDb,
|
|
380
|
+
authKeysDb,
|
|
381
|
+
identity: {
|
|
382
|
+
url: 'https://dev-identity.sequence-dev.app',
|
|
383
|
+
fetch: window.fetch,
|
|
384
|
+
google: {
|
|
385
|
+
enabled: true,
|
|
386
|
+
clientId: 'test-google-client-id',
|
|
387
|
+
authMethod: 'id-token',
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
})
|
|
391
|
+
|
|
392
|
+
const handlers = (manager as any).shared.handlers
|
|
393
|
+
expect(handlers.has('login-google-id-token')).toBe(false)
|
|
394
|
+
expect(handlers.has('login-google')).toBe(true)
|
|
395
|
+
expect(handlers.has('login-google-pkce')).toBe(false)
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
it('Should register the Apple ID token handler when configured explicitly', async () => {
|
|
399
|
+
manager = new Manager({
|
|
400
|
+
stateProvider: new State.Local.Provider(new State.Local.IndexedDbStore(`manager-apple-idtoken-${Date.now()}`)),
|
|
401
|
+
networks: [
|
|
402
|
+
{
|
|
403
|
+
name: 'Test Network',
|
|
404
|
+
type: Network.NetworkType.MAINNET,
|
|
405
|
+
rpcUrl: LOCAL_RPC_URL,
|
|
406
|
+
chainId: Network.ChainId.ARBITRUM,
|
|
407
|
+
blockExplorer: { url: 'https://arbiscan.io' },
|
|
408
|
+
nativeCurrency: {
|
|
409
|
+
name: 'Ether',
|
|
410
|
+
symbol: 'ETH',
|
|
411
|
+
decimals: 18,
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
relayers: [],
|
|
416
|
+
authCommitmentsDb,
|
|
417
|
+
authKeysDb,
|
|
418
|
+
identity: {
|
|
419
|
+
url: 'https://dev-identity.sequence-dev.app',
|
|
420
|
+
fetch: window.fetch,
|
|
421
|
+
apple: {
|
|
422
|
+
enabled: true,
|
|
423
|
+
clientId: 'test-apple-client-id',
|
|
424
|
+
authMethod: 'id-token',
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
const handlers = (manager as any).shared.handlers
|
|
430
|
+
expect(handlers.has('login-apple-id-token')).toBe(false)
|
|
431
|
+
expect(handlers.has('login-apple')).toBe(true)
|
|
357
432
|
})
|
|
358
433
|
|
|
359
434
|
it('Should use auth databases when email authentication is enabled', async () => {
|
|
@@ -424,5 +499,50 @@ describe('Identity Authentication Databases', () => {
|
|
|
424
499
|
const handlers = (manager as any).shared.handlers
|
|
425
500
|
expect(handlers.has('login-apple')).toBe(true)
|
|
426
501
|
})
|
|
502
|
+
|
|
503
|
+
it('Should register custom ID token providers without enabling redirect flow for them', async () => {
|
|
504
|
+
manager = new Manager({
|
|
505
|
+
stateProvider: new State.Local.Provider(new State.Local.IndexedDbStore(`manager-custom-idtoken-${Date.now()}`)),
|
|
506
|
+
networks: [
|
|
507
|
+
{
|
|
508
|
+
name: 'Test Network',
|
|
509
|
+
type: Network.NetworkType.MAINNET,
|
|
510
|
+
rpcUrl: LOCAL_RPC_URL,
|
|
511
|
+
chainId: Network.ChainId.ARBITRUM,
|
|
512
|
+
blockExplorer: { url: 'https://arbiscan.io' },
|
|
513
|
+
nativeCurrency: {
|
|
514
|
+
name: 'Ether',
|
|
515
|
+
symbol: 'ETH',
|
|
516
|
+
decimals: 18,
|
|
517
|
+
},
|
|
518
|
+
},
|
|
519
|
+
],
|
|
520
|
+
relayers: [],
|
|
521
|
+
authCommitmentsDb,
|
|
522
|
+
authKeysDb,
|
|
523
|
+
identity: {
|
|
524
|
+
url: 'https://dev-identity.sequence-dev.app',
|
|
525
|
+
fetch: window.fetch,
|
|
526
|
+
customProviders: [
|
|
527
|
+
{
|
|
528
|
+
kind: 'custom-google-native',
|
|
529
|
+
authMethod: 'id-token',
|
|
530
|
+
issuer: 'https://accounts.google.com',
|
|
531
|
+
clientId: 'test-google-client-id',
|
|
532
|
+
},
|
|
533
|
+
],
|
|
534
|
+
},
|
|
535
|
+
})
|
|
536
|
+
|
|
537
|
+
const handlers = (manager as any).shared.handlers
|
|
538
|
+
expect(handlers.has('custom-google-native')).toBe(true)
|
|
539
|
+
await expect(
|
|
540
|
+
manager.wallets.startSignUpWithRedirect({
|
|
541
|
+
kind: 'custom-google-native',
|
|
542
|
+
target: '/home',
|
|
543
|
+
metadata: {},
|
|
544
|
+
}),
|
|
545
|
+
).rejects.toThrow('handler-does-not-support-redirect')
|
|
546
|
+
})
|
|
427
547
|
})
|
|
428
548
|
})
|