@seams/wallet-server 0.44.0 → 0.46.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.
Files changed (35) hide show
  1. package/README.md +4 -4
  2. package/artifact-manifest.json +11 -11
  3. package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
  4. package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
  5. package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
  6. package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
  7. package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
  8. package/dist/esm/authorization/factorEvidence.js +37 -1
  9. package/dist/esm/authorization/voiceIdDeviceProof.js +32 -6
  10. package/dist/esm/hosted-wallet-gateway.js +1 -1
  11. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +1 -0
  12. package/dist/esm/router/cloudflare/d1/wallet/d1VoiceIdSessions.js +34 -1
  13. package/dist/esm/router/cloudflare.js +317 -100
  14. package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.js +181 -14
  15. package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExportRequestScopedCloudflare.js +21 -5
  16. package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +4 -0
  17. package/dist/esm/router/transport/fetch/routes/ecdsaOperationStepUpFactor.js +51 -1
  18. package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +3 -1
  19. package/dist/esm/shared-ts/src/authorization/capabilityKinds.js +2 -1
  20. package/dist/esm/shared-ts/src/authorization/voiceIdDeviceAssertion.js +70 -1
  21. package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +18 -1
  22. package/dist/esm/shared-ts/src/utils/routerAbEd25519YaoDigests.js +8 -1
  23. package/dist/types/shared-ts/src/authorization/capabilityKinds.d.ts +2 -1
  24. package/dist/types/shared-ts/src/authorization/voiceIdDeviceAssertion.d.ts +30 -0
  25. package/dist/types/shared-ts/src/utils/routerAbEcdsaDerivation.d.ts +11 -1
  26. package/dist/types/shared-ts/src/utils/routerAbEd25519YaoDigests.d.ts +3 -0
  27. package/dist/types/wallet-server/src/authorization/domain.d.ts +3 -0
  28. package/dist/types/wallet-server/src/authorization/factorEvidence.d.ts +11 -1
  29. package/dist/types/wallet-server/src/authorization/voiceIdDeviceProof.d.ts +27 -1
  30. package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1VoiceIdSessions.d.ts +3 -1
  31. package/dist/types/wallet-server/src/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.d.ts +36 -2
  32. package/dist/types/wallet-server/src/router/domains/voiceId/voiceIdSessions.d.ts +23 -1
  33. package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +1 -0
  34. package/dist/types/wallet-server/src/router/transport/fetch/routes/ecdsaOperationStepUpFactor.d.ts +2 -1
  35. package/package.json +1 -1
@@ -28,5 +28,35 @@ export declare function buildVoiceIdWalletSessionChallenge(fields: Omit<VoiceIdW
28
28
  export declare function parseVoiceIdWalletSessionChallenge(raw: unknown): VoiceIdWalletSessionChallenge;
29
29
  export declare function parseVoiceIdDeviceAssertion(raw: unknown): VoiceIdDeviceAssertion;
30
30
  export declare function voiceIdWalletSessionChallengeBytes(challenge: VoiceIdWalletSessionChallenge): Uint8Array<ArrayBuffer>;
31
+ /** The operations a fresh voice check can authorize; signing uses a Wallet Session. */
32
+ export type VoiceIdOperationKind = 'near.export_key' | 'evm.export_key';
33
+ /**
34
+ * What the enrolled device key signs after a local voice match for one
35
+ * operation. `operationChallenge` is the digest that a passkey signs for the
36
+ * same operation, and the server accepts that operation only once. It is a
37
+ * different statement from a Wallet Session challenge, under its own domain,
38
+ * so neither proof can stand in for the other.
39
+ */
40
+ export type VoiceIdOperationStatement = Readonly<{
41
+ kind: 'voiceid_operation_statement_v1';
42
+ walletId: WalletId;
43
+ walletAuthMethodId: WalletAuthMethodId;
44
+ walletAuthorityId: WalletAuthorityId;
45
+ deviceKeyId: DigestB64u;
46
+ operationKind: VoiceIdOperationKind;
47
+ operationChallenge: DigestB64u;
48
+ requestOrigin: string;
49
+ issuedAtMs: number;
50
+ expiresAtMs: number;
51
+ }>;
52
+ export type VoiceIdOperationAssertion = Readonly<{
53
+ kind: 'voiceid_operation_assertion_v1';
54
+ statement: VoiceIdOperationStatement;
55
+ signatureB64u: string;
56
+ }>;
57
+ export declare function buildVoiceIdOperationStatement(fields: Omit<VoiceIdOperationStatement, 'kind'>): VoiceIdOperationStatement;
58
+ export declare function parseVoiceIdOperationStatement(raw: unknown): VoiceIdOperationStatement;
59
+ export declare function parseVoiceIdOperationAssertion(raw: unknown): VoiceIdOperationAssertion;
60
+ export declare function voiceIdOperationStatementBytes(statement: VoiceIdOperationStatement): Uint8Array<ArrayBuffer>;
31
61
  export {};
32
62
  //# sourceMappingURL=voiceIdDeviceAssertion.d.ts.map
@@ -5,7 +5,8 @@ import { type EcdsaServerGeneration } from './ecdsaCapabilityActivation';
5
5
  import { type RouterAbMpcMaterialActivationRefWire, type RouterAbNormalSigningAuthorizationWire } from './routerAbNormalSigningIdentity';
6
6
  import { type EvmEcdsaMpcOperationKind, type MpcWalletSigningQuotaId, type WalletSessionMintId, type EcdsaAuthorizationSessionId, type WalletSessionAuthorizationId, type WalletSessionId } from '../authorization/capabilityKinds';
7
7
  import type { ActiveWalletSessionV1, WalletSessionOperationCredentialV1 } from '../device-linking/contracts';
8
- import { type EmailOtpWalletAuthAuthority, type PasskeyWalletAuthAuthority } from './walletAuthAuthority';
8
+ import { type EmailOtpWalletAuthAuthority, type PasskeyWalletAuthAuthority, type VoiceIdWalletAuthAuthority } from './walletAuthAuthority';
9
+ import { type VoiceIdOperationAssertion } from '../authorization/voiceIdDeviceAssertion';
9
10
  /**
10
11
  * The longest an ECDSA presignature ceremony may run. The Gateway authorizes a
11
12
  * pool fill only when the requested ceremony deadline is within this limit.
@@ -486,12 +487,21 @@ type RouterAbEcdsaOperationStepUpProofV1Wire = {
486
487
  readonly webauthn_authentication: RouterAbEcdsaOperationStepUpWebAuthnCredentialV1Wire;
487
488
  readonly challenge_id?: never;
488
489
  readonly otp_code?: never;
490
+ readonly assertion?: never;
489
491
  } | {
490
492
  readonly kind: 'email_otp';
491
493
  readonly authority: EmailOtpWalletAuthAuthority;
492
494
  readonly challenge_id: string;
493
495
  readonly otp_code: string;
494
496
  readonly webauthn_authentication?: never;
497
+ readonly assertion?: never;
498
+ } | {
499
+ readonly kind: 'voiceid';
500
+ readonly authority: VoiceIdWalletAuthAuthority;
501
+ readonly assertion: VoiceIdOperationAssertion;
502
+ readonly webauthn_authentication?: never;
503
+ readonly challenge_id?: never;
504
+ readonly otp_code?: never;
495
505
  };
496
506
  export type RouterAbEcdsaOperationStepUpAuthorizationRequestV1Wire = {
497
507
  readonly kind: 'router_ab_ecdsa_operation_step_up_v1';
@@ -7,6 +7,9 @@ type RouterAbEd25519YaoExportAuthorityBindingV1 = ReadonlyExclusiveUnion<{
7
7
  } | {
8
8
  readonly kind: 'email_otp';
9
9
  readonly providerSubjectId: string;
10
+ } | {
11
+ readonly kind: 'voiceid';
12
+ readonly deviceKeyId: string;
10
13
  }>;
11
14
  export declare function requireVisibleIdentifier(value: unknown, label: string): string;
12
15
  export declare function requireBytes(value: unknown, label: string, minimumLength: number, maximumLength: number): number[];
@@ -36,6 +36,9 @@ export type VerifiedOwnerProofCommon = {
36
36
  readonly authSource: {
37
37
  readonly kind: 'passkey';
38
38
  readonly credentialIdB64u: WebAuthnCredentialIdB64u;
39
+ } | {
40
+ readonly kind: 'voiceid';
41
+ readonly deviceKeyId: DigestB64u;
39
42
  } | {
40
43
  readonly kind: 'oidc_provider';
41
44
  readonly providerId: 'google_oidc' | 'oidc';
@@ -4,6 +4,7 @@ import type { DigestB64u } from '../../../shared-ts/src/utils/canonicalPrimitive
4
4
  import { type EmailOtpChallengeId, type WalletId, type WebAuthnCredentialIdB64u } from '../../../shared-ts/src/utils/domainIds';
5
5
  import { type WalletAuthAuthorityRef } from '../../../shared-ts/src/utils/walletAuthAuthority';
6
6
  import type { OwnerOperationBinding, SessionOrigin, VerifiedOwnerProofFields, VerifiedAuthorizationEvidence, VerifiedOwnerProofId, VerifiedOwnerProofMethod } from './domain';
7
+ import type { VerifiedVoiceIdOperationProof } from './voiceIdDeviceProof';
7
8
  type VerifiedWalletOperationEvidenceSetFields = {
8
9
  readonly tenantId: TenantId;
9
10
  readonly principalId: PrincipalId;
@@ -66,7 +67,12 @@ type VerifiedWalletOperationEmailOtpFactorResult = VerifiedWalletOperationFactor
66
67
  readonly challengeId: EmailOtpChallengeId;
67
68
  readonly verificationReceiptDigest: DigestB64u;
68
69
  };
69
- export type VerifiedWalletOperationFactorResult = VerifiedWalletOperationPasskeyFactorResult | VerifiedWalletOperationEmailOtpFactorResult;
70
+ type VerifiedWalletOperationVoiceIdFactorResult = VerifiedWalletOperationFactorBinding & {
71
+ readonly kind: 'verified_wallet_operation_voiceid_factor';
72
+ readonly deviceKeyId: DigestB64u;
73
+ readonly assertionDigest: DigestB64u;
74
+ };
75
+ export type VerifiedWalletOperationFactorResult = VerifiedWalletOperationPasskeyFactorResult | VerifiedWalletOperationEmailOtpFactorResult | VerifiedWalletOperationVoiceIdFactorResult;
70
76
  type VerifiedWalletSessionFactorBinding = {
71
77
  readonly tenantId: TenantId;
72
78
  readonly principalId: PrincipalId;
@@ -106,6 +112,10 @@ export type VerifiedOwnerProofInput = {
106
112
  };
107
113
  export declare function buildVerifiedWalletOperationPasskeyFactorResult(fields: Omit<VerifiedWalletOperationPasskeyFactorResult, 'kind'>): VerifiedWalletOperationPasskeyFactorResult;
108
114
  export declare function buildVerifiedWalletOperationEmailOtpFactorResult(fields: Omit<VerifiedWalletOperationEmailOtpFactorResult, 'kind'>): VerifiedWalletOperationEmailOtpFactorResult;
115
+ /** Only a verified operation statement yields this factor; its proof supplies the key and digest. */
116
+ export declare function buildVerifiedWalletOperationVoiceIdFactorResult(fields: Omit<VerifiedWalletOperationVoiceIdFactorResult, 'kind' | 'deviceKeyId' | 'assertionDigest'> & {
117
+ readonly proof: VerifiedVoiceIdOperationProof;
118
+ }): VerifiedWalletOperationVoiceIdFactorResult;
109
119
  export declare function buildVerifiedWalletSessionPasskeyFactorResult(fields: Omit<VerifiedWalletSessionPasskeyFactorResult, 'kind'>): VerifiedWalletSessionPasskeyFactorResult;
110
120
  export declare function buildVerifiedWalletSessionEmailOtpFactorResult(fields: Omit<VerifiedWalletSessionEmailOtpFactorResult, 'kind'>): VerifiedWalletSessionEmailOtpFactorResult;
111
121
  /** Nominal server-only owner proofs; private constructors block browser forgery. */
@@ -1,4 +1,4 @@
1
- import { type VoiceIdDevicePublicKeyB64u, type VoiceIdWalletSessionChallenge } from '../../../shared-ts/src/authorization/voiceIdDeviceAssertion';
1
+ import { type VoiceIdDevicePublicKeyB64u, type VoiceIdOperationKind, type VoiceIdOperationStatement, type VoiceIdWalletSessionChallenge } from '../../../shared-ts/src/authorization/voiceIdDeviceAssertion';
2
2
  import { type DigestB64u } from '../../../shared-ts/src/utils/canonicalPrimitives';
3
3
  import type { WalletAuthMethodId, WalletAuthorityId, WalletId } from '../../../shared-ts/src/utils/domainIds';
4
4
  export type RegisteredVoiceIdDeviceKey = Readonly<{
@@ -25,5 +25,31 @@ export declare function verifyVoiceIdWalletSessionAssertion(input: {
25
25
  nowMs: number;
26
26
  consumeChallenge: ConsumeVoiceIdChallenge;
27
27
  }): Promise<VerifiedVoiceIdSessionProof>;
28
+ declare class VerifiedVoiceIdOperationStatementProof {
29
+ readonly statement: VoiceIdOperationStatement;
30
+ readonly deviceKeyId: DigestB64u;
31
+ readonly assertionDigest: DigestB64u;
32
+ private readonly proofBrand;
33
+ constructor(statement: VoiceIdOperationStatement, deviceKeyId: DigestB64u, assertionDigest: DigestB64u);
34
+ }
35
+ /**
36
+ * A voice check for one operation. It is not a Wallet Session proof, and no
37
+ * conversion exists between the two: a session assertion signs a different
38
+ * statement under a different domain.
39
+ */
40
+ export type VerifiedVoiceIdOperationProof = VerifiedVoiceIdOperationStatementProof;
41
+ /**
42
+ * Only this server boundary turns a signed operation statement into verified
43
+ * proof. The caller supplies the digest the operation expects and owns its
44
+ * single use, as it does for a passkey assertion over the same digest.
45
+ */
46
+ export declare function verifyVoiceIdOperationAssertion(input: {
47
+ registered: RegisteredVoiceIdDeviceKey;
48
+ assertion: unknown;
49
+ operationKind: VoiceIdOperationKind;
50
+ operationChallenge: DigestB64u;
51
+ requestOrigin: string;
52
+ nowMs: number;
53
+ }): Promise<VerifiedVoiceIdOperationProof>;
28
54
  export {};
29
55
  //# sourceMappingURL=voiceIdDeviceProof.d.ts.map
@@ -2,7 +2,7 @@ import type { AuthorizationService } from '../../../../authorization/service';
2
2
  import type { D1WalletAuthMethodStore } from '../../../../core/d1WalletAuthMethodStore';
3
3
  import type { CloudflareD1PasskeyCustodyEnvelopeStore } from '../passkeyCustody/d1PasskeyCustodyEnvelopeStore';
4
4
  import type { D1WalletAuthorityStore } from './d1WalletAuthorityStore';
5
- import type { VoiceIdChallengeRequest, VoiceIdChallengeResult, VoiceIdVerifyRequest, VoiceIdVerifyResult } from '../../../domains/voiceId/voiceIdSessions';
5
+ import type { VoiceIdChallengeRequest, VoiceIdChallengeResult, VoiceIdOperationVerifyRequest, VoiceIdOperationVerifyResult, VoiceIdVerifyRequest, VoiceIdVerifyResult } from '../../../domains/voiceId/voiceIdSessions';
6
6
  import { D1VoiceIdWalletSessionChallenges } from './d1VoiceIdWalletSessionChallenges';
7
7
  export declare class D1VoiceIdSessions {
8
8
  private readonly authMethods;
@@ -15,5 +15,7 @@ export declare class D1VoiceIdSessions {
15
15
  private resolveActiveMethod;
16
16
  issueChallenge(input: VoiceIdChallengeRequest): Promise<VoiceIdChallengeResult>;
17
17
  verifyAndIssue(input: VoiceIdVerifyRequest): Promise<VoiceIdVerifyResult>;
18
+ /** Verifies a voice check for one operation; the operation's own claim makes it single use. */
19
+ verifyOperation(input: VoiceIdOperationVerifyRequest): Promise<VoiceIdOperationVerifyResult>;
18
20
  }
19
21
  //# sourceMappingURL=d1VoiceIdSessions.d.ts.map
@@ -2,8 +2,10 @@ import type { WalletExecutionAuthority } from '../../walletRegistration/walletRe
2
2
  import { type RouterAbEd25519YaoExportAdmissionReceiptV1, type RouterAbEd25519YaoExportAdmissionRequestV1, type RouterAbEd25519YaoExportExecuteRequestV1, type RouterAbEd25519YaoExportResultV1 } from '../../../../../../shared-ts/src/utils/routerAbEd25519Yao';
3
3
  import { type RouterAbTraceContextV1 } from '../../../../../../shared-ts/src/utils/routerAbTraceContext';
4
4
  import { type ThresholdEd25519SessionId } from '../../../../../../shared-ts/src/utils/domainIds';
5
+ import { type VoiceIdOperationAssertion } from '../../../../../../shared-ts/src/authorization/voiceIdDeviceAssertion';
6
+ import type { VoiceIdSeedEnvelope } from '../../../../../../shared-ts/src/passkey-custody/custodyEnvelope';
5
7
  import type { WebAuthnAuthenticationCredential } from '../../../../core/types';
6
- import type { RouterApiAuthorizedOperationService, RouterApiEmailOtpRouteService, RouterApiWalletAuthMethodService, RouterApiWalletRegistrationService, RouterApiWebAuthnService } from '../../../framework/authServicePort';
8
+ import type { RouterApiAuthorizedOperationService, RouterApiEmailOtpRouteService, RouterApiWalletAuthMethodService, RouterApiWalletRegistrationService, RouterApiWalletUnlockService, RouterApiWebAuthnService } from '../../../framework/authServicePort';
7
9
  import { type RouterApiModule } from '../../../framework/modules';
8
10
  import type { RouterAbEd25519YaoActiveCapabilityResolverV1 } from '../recovery/routerAbEd25519YaoRecovery';
9
11
  import type { RouterAbEd25519YaoExportExecuteAdmissionContextV1 } from '../routerAbEd25519YaoGatewayEnvelope';
@@ -102,8 +104,10 @@ export type RouterAbEd25519YaoExportAdmissionAuthorization = {
102
104
  readonly kind: 'passkey';
103
105
  readonly webauthnAuthentication: WebAuthnAuthenticationCredential;
104
106
  readonly providerSubjectId?: never;
107
+ readonly walletAuthMethodId?: never;
105
108
  readonly challengeId?: never;
106
109
  readonly otpCode?: never;
110
+ readonly assertion?: never;
107
111
  } | {
108
112
  readonly kind: 'email_otp_factor';
109
113
  readonly providerSubjectId: string;
@@ -111,6 +115,23 @@ export type RouterAbEd25519YaoExportAdmissionAuthorization = {
111
115
  readonly challengeId: string;
112
116
  readonly otpCode: string;
113
117
  readonly webauthnAuthentication?: never;
118
+ readonly assertion?: never;
119
+ } | {
120
+ readonly kind: 'voiceid_device';
121
+ readonly walletAuthMethodId: string;
122
+ readonly assertion: VoiceIdOperationAssertion;
123
+ readonly webauthnAuthentication?: never;
124
+ readonly providerSubjectId?: never;
125
+ readonly challengeId?: never;
126
+ readonly otpCode?: never;
127
+ };
128
+ /**
129
+ * The VoiceID seed envelope the admission returns after a voice check. The
130
+ * browser opens it with the factor secret from the same check.
131
+ */
132
+ export type RouterAbEd25519YaoExportVoiceIdCustodyReleaseV1 = {
133
+ readonly kind: 'voiceid_custody_envelope';
134
+ readonly envelope: VoiceIdSeedEnvelope;
114
135
  };
115
136
  export type RouterAbEd25519YaoExportAdmissionAuthorizationInputV1 = {
116
137
  readonly request: Request;
@@ -172,6 +193,11 @@ export type RouterAbEd25519YaoExportAdmissionAuthorizationResultV1 = {
172
193
  readonly admission: RouterAbEd25519YaoExportOperationAdmissionV1;
173
194
  readonly ownershipGeneration: number;
174
195
  readonly factorRelease?: RouterAbEd25519YaoExportEmailOtpFactorReleaseV1;
196
+ readonly custodyRelease?: RouterAbEd25519YaoExportVoiceIdCustodyReleaseV1;
197
+ } | RouterAbEd25519YaoExportAuthorizationFailure;
198
+ export type RouterAbEd25519YaoExportVoiceIdCustodyReleaseResultV1 = {
199
+ readonly ok: true;
200
+ readonly custodyRelease: RouterAbEd25519YaoExportVoiceIdCustodyReleaseV1;
175
201
  } | RouterAbEd25519YaoExportAuthorizationFailure;
176
202
  export type RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult = {
177
203
  readonly ok: true;
@@ -182,6 +208,12 @@ export type RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult = {
182
208
  export interface RouterAbEd25519YaoExportAuthorizationAdapter {
183
209
  authorizeAdmission(input: RouterAbEd25519YaoExportAdmissionAuthorizationInputV1): Promise<RouterAbEd25519YaoExportAdmissionAuthorizationResultV1> | RouterAbEd25519YaoExportAdmissionAuthorizationResultV1;
184
210
  authorizeExecution(input: RouterAbEd25519YaoExportExecutionAuthorizationInputV1): Promise<RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult> | RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult;
211
+ /**
212
+ * The VoiceID seed envelope for an exact retry of an export already
213
+ * authorized with VoiceID. The retry's statement is verified again; its
214
+ * export is not authorized again.
215
+ */
216
+ releaseVoiceIdCustodyForAuthorizedExport(input: RouterAbEd25519YaoExportAdmissionAuthorizationInputV1): Promise<RouterAbEd25519YaoExportVoiceIdCustodyReleaseResultV1>;
185
217
  /** The identity an already-authorized export's admission resolves to now. */
186
218
  resolveAuthorizationIdentity(body: RouterAbEd25519YaoExportAdmissionRequestV1): Promise<RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult> | RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult;
187
219
  }
@@ -263,13 +295,15 @@ export declare class InMemoryRouterAbEd25519YaoExportService implements RouterAb
263
295
  export declare class RouterAbEd25519YaoExportOwnerProofAuthorizationAdapter implements RouterAbEd25519YaoExportAuthorizationAdapter {
264
296
  private readonly webAuthn;
265
297
  private readonly emailOtp;
298
+ private readonly voiceId;
266
299
  private readonly walletAuthMethods;
267
300
  private readonly authorizedOperations;
268
301
  private readonly resolveEd25519MaterialActivation;
269
302
  private readonly admitEstablishedHome;
270
- constructor(webAuthn: Pick<RouterApiWebAuthnService, 'verifyWebAuthnAuthenticationLite'>, emailOtp: Pick<RouterApiEmailOtpRouteService, 'verifyEmailOtpChallenge'>, walletAuthMethods: Pick<RouterApiWalletAuthMethodService, 'resolveActivePasskeyAuthorityForVerifiedCredential' | 'resolveActiveEmailOtpAuthorityForVerifiedMethod'>, authorizedOperations: RouterApiAuthorizedOperationService, resolveEd25519MaterialActivation: RouterApiWalletRegistrationService['resolveEd25519MaterialActivation'], admitEstablishedHome: WalletExecutionAuthority['admitEstablishedHome']);
303
+ constructor(webAuthn: Pick<RouterApiWebAuthnService, 'verifyWebAuthnAuthenticationLite'>, emailOtp: Pick<RouterApiEmailOtpRouteService, 'verifyEmailOtpChallenge'>, voiceId: Pick<RouterApiWalletUnlockService, 'verifyVoiceIdOperation'>, walletAuthMethods: Pick<RouterApiWalletAuthMethodService, 'resolveActivePasskeyAuthorityForVerifiedCredential' | 'resolveActiveEmailOtpAuthorityForVerifiedMethod'>, authorizedOperations: RouterApiAuthorizedOperationService, resolveEd25519MaterialActivation: RouterApiWalletRegistrationService['resolveEd25519MaterialActivation'], admitEstablishedHome: WalletExecutionAuthority['admitEstablishedHome']);
271
304
  authorizeAdmission(input: RouterAbEd25519YaoExportAdmissionAuthorizationInputV1): Promise<RouterAbEd25519YaoExportAdmissionAuthorizationResultV1>;
272
305
  authorizeExecution(input: RouterAbEd25519YaoExportExecutionAuthorizationInputV1): RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult;
306
+ releaseVoiceIdCustodyForAuthorizedExport(input: RouterAbEd25519YaoExportAdmissionAuthorizationInputV1): Promise<RouterAbEd25519YaoExportVoiceIdCustodyReleaseResultV1>;
273
307
  resolveAuthorizationIdentity(body: RouterAbEd25519YaoExportAdmissionRequestV1): Promise<RouterAbEd25519YaoExportAuthorizationIdentityResolutionResult>;
274
308
  }
275
309
  export type RouterAbEd25519YaoExportAdmissionEnvelopeParseResultV1 = {
@@ -1,4 +1,7 @@
1
- import type { VoiceIdDeviceAssertion, VoiceIdWalletSessionChallenge } from '../../../../../shared-ts/src/authorization/voiceIdDeviceAssertion';
1
+ import type { VoiceIdDeviceAssertion, VoiceIdOperationKind, VoiceIdWalletSessionChallenge } from '../../../../../shared-ts/src/authorization/voiceIdDeviceAssertion';
2
+ import type { DigestB64u } from '../../../../../shared-ts/src/utils/canonicalPrimitives';
3
+ import type { VoiceIdWalletAuthAuthority } from '../../../../../shared-ts/src/utils/walletAuthAuthority';
4
+ import type { VerifiedVoiceIdOperationProof } from '../../../authorization/voiceIdDeviceProof';
2
5
  import type { WalletAuthMethodId, WalletId } from '../../../../../shared-ts/src/utils/domainIds';
3
6
  import type { VoiceIdSeedEnvelope } from '../../../../../shared-ts/src/passkey-custody/custodyEnvelope';
4
7
  import type { DirectV2IssueResult, IssuedWalletSessionAuthorizationV2 } from '../../../authorization/domain';
@@ -32,4 +35,23 @@ export type VoiceIdVerifyResult = {
32
35
  readonly kind: 'rejected';
33
36
  readonly code: 'challenge_unavailable' | 'method_unavailable' | 'invalid_assertion' | 'issuance_unavailable';
34
37
  };
38
+ /** A fresh voice check for one operation, verified against the active VoiceID method. */
39
+ export type VoiceIdOperationVerifyRequest = Readonly<{
40
+ walletId: WalletId;
41
+ walletAuthMethodId: WalletAuthMethodId;
42
+ assertion: unknown;
43
+ operationKind: VoiceIdOperationKind;
44
+ operationChallenge: DigestB64u;
45
+ requestOrigin: SessionOrigin;
46
+ nowMs: number;
47
+ }>;
48
+ export type VoiceIdOperationVerifyResult = {
49
+ readonly kind: 'verified';
50
+ readonly proof: VerifiedVoiceIdOperationProof;
51
+ readonly authority: VoiceIdWalletAuthAuthority;
52
+ readonly custodyEnvelope: VoiceIdSeedEnvelope;
53
+ } | {
54
+ readonly kind: 'rejected';
55
+ readonly code: 'method_unavailable' | 'invalid_assertion';
56
+ };
35
57
  //# sourceMappingURL=voiceIdSessions.d.ts.map
@@ -1208,6 +1208,7 @@ export interface RouterApiWalletRegistrationRouteService extends RouterApiWallet
1208
1208
  export interface RouterApiWalletUnlockService {
1209
1209
  issueVoiceIdChallenge(input: import('../domains/voiceId/voiceIdSessions').VoiceIdChallengeRequest): Promise<import('../domains/voiceId/voiceIdSessions').VoiceIdChallengeResult>;
1210
1210
  verifyAndIssueVoiceId(input: import('../domains/voiceId/voiceIdSessions').VoiceIdVerifyRequest): Promise<import('../domains/voiceId/voiceIdSessions').VoiceIdVerifyResult>;
1211
+ verifyVoiceIdOperation(input: import('../domains/voiceId/voiceIdSessions').VoiceIdOperationVerifyRequest): Promise<import('../domains/voiceId/voiceIdSessions').VoiceIdOperationVerifyResult>;
1211
1212
  createEmailOtpUnlockChallenge(input: RouterApiMethodTypes['createEmailOtpUnlockChallenge']['input']): Promise<RouterApiMethodTypes['createEmailOtpUnlockChallenge']['result']>;
1212
1213
  createWebAuthnLoginOptions(input: RouterApiMethodTypes['createWebAuthnLoginOptions']['input']): Promise<RouterApiMethodTypes['createWebAuthnLoginOptions']['result']>;
1213
1214
  markEmailOtpStrongAuthSatisfied(input: RouterApiMethodTypes['markEmailOtpStrongAuthSatisfied']['input']): Promise<RouterApiMethodTypes['markEmailOtpStrongAuthSatisfied']['result']>;
@@ -5,7 +5,7 @@ import type { RouterAbEcdsaOperationStepUpAuthorizationRequestV1Wire } from '../
5
5
  import { type VerifiedWalletOperationFactorResult } from '../../../../authorization/factorEvidence';
6
6
  import type { SessionOrigin } from '../../../../authorization/domain';
7
7
  import type { WalletExecutionLaneAuthSource } from '../../../../core/signingLanes/WalletExecutionLaneProjection';
8
- import type { RouterApiEmailOtpRouteService, RouterApiWebAuthnService } from '../../../framework/authServicePort';
8
+ import type { RouterApiEmailOtpRouteService, RouterApiWalletUnlockService, RouterApiWebAuthnService } from '../../../framework/authServicePort';
9
9
  type StepUpUnseal = {
10
10
  readonly kind: 'not_requested';
11
11
  } | {
@@ -32,6 +32,7 @@ export declare function verifyEcdsaOperationStepUpFactor(input: {
32
32
  readonly expiresAtMs: number;
33
33
  readonly webAuthn: Pick<RouterApiWebAuthnService, 'verifyWebAuthnAuthenticationLite'>;
34
34
  readonly emailOtp: Pick<RouterApiEmailOtpRouteService, 'verifyEmailOtpChallenge' | 'consumeEmailOtpGrant'>;
35
+ readonly voiceId: Pick<RouterApiWalletUnlockService, 'verifyVoiceIdOperation'>;
35
36
  }): Promise<VerifiedStepUpFactorResult>;
36
37
  export {};
37
38
  //# sourceMappingURL=ecdsaOperationStepUpFactor.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seams/wallet-server",
3
- "version": "0.44.0",
3
+ "version": "0.46.0",
4
4
  "type": "module",
5
5
  "description": "Seams server TypeScript SDK for NEAR and EVM-family wallets",
6
6
  "main": "./dist/esm/index.js",