@seams/wallet-server 0.7.1 → 0.7.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 (259) hide show
  1. package/THIRD_PARTY_NOTICES.md +1 -105
  2. package/artifact-manifest.json +21 -21
  3. package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
  4. package/cloudflare-router-ab/build/deriver-a/index_bg.wasm +0 -0
  5. package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
  6. package/cloudflare-router-ab/build/deriver-b/index_bg.wasm +0 -0
  7. package/cloudflare-router-ab/build/local-tools/darwin-arm64/router_ab_local_init +0 -0
  8. package/cloudflare-router-ab/build/local-tools/darwin-x64/router_ab_local_init +0 -0
  9. package/cloudflare-router-ab/build/local-tools/linux-x64/router_ab_local_init +0 -0
  10. package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
  11. package/cloudflare-router-ab/build/router/index_bg.wasm +0 -0
  12. package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
  13. package/cloudflare-router-ab/build/signing-worker/index_bg.wasm +0 -0
  14. package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
  15. package/cloudflare-router-ab/build/tenant-root-control-plane/index_bg.wasm +0 -0
  16. package/dist/esm/authorization/service.js +8 -0
  17. package/dist/esm/authorization/vaultProxyUse.js +2 -6
  18. package/dist/esm/cloud-host.js +4 -4
  19. package/dist/esm/core/IdentityStore.js +23 -110
  20. package/dist/esm/core/SessionService.js +7 -30
  21. package/dist/esm/core/ThresholdService/routerAbNormalSigningPolicy.js +3 -10
  22. package/dist/esm/core/ThresholdService/stores/WalletSessionStore.js +21 -97
  23. package/dist/esm/core/ThresholdService/stores/exportReplayGuard.js +7 -0
  24. package/dist/esm/core/WalletStore.js +4 -6
  25. package/dist/esm/core/authService/bytes.js +1 -4
  26. package/dist/esm/core/authService/emailOtpChallengeOperations.js +2 -5
  27. package/dist/esm/core/authService/emailOtpChallengeProof.js +9 -40
  28. package/dist/esm/core/authService/emailOtpChallengeVerification.js +19 -90
  29. package/dist/esm/core/authService/emailOtpChallenges.js +10 -45
  30. package/dist/esm/core/authService/emailOtpDelivery.js +10 -45
  31. package/dist/esm/core/authService/emailOtpEnrollment.js +9 -40
  32. package/dist/esm/core/authService/emailOtpGrant.js +9 -40
  33. package/dist/esm/core/authService/emailOtpRegistrationEnrollment.js +9 -40
  34. package/dist/esm/core/authService/emailOtpSeal.js +5 -20
  35. package/dist/esm/core/authService/emailOtpUnlock.js +20 -110
  36. package/dist/esm/core/authService/googleEmailOtpRegistration.js +28 -115
  37. package/dist/esm/core/authService/identity.js +5 -20
  38. package/dist/esm/core/authService/nearPublicKeyMetadata.js +6 -25
  39. package/dist/esm/core/authService/oidcVerification.js +22 -34
  40. package/dist/esm/core/authService/rateLimits.js +2 -5
  41. package/dist/esm/core/authService/thresholdEcdsaKeyInventory.js +2 -1
  42. package/dist/esm/core/authService/webauthn.js +37 -191
  43. package/dist/esm/core/authService/webauthnVerificationOutcomes.js +5 -24
  44. package/dist/esm/core/d1EcdsaSignerRead.js +76 -0
  45. package/dist/esm/core/d1IdentityStore.js +16 -75
  46. package/dist/esm/core/d1TenantStore.js +1 -1
  47. package/dist/esm/core/d1WalletStore.js +15 -25
  48. package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -5
  49. package/dist/esm/core/deviceLinking/linkedDeviceSessionApproval.js +1 -3
  50. package/dist/esm/core/deviceLinking/linkedDeviceSessionRecord.js +2 -8
  51. package/dist/esm/core/deviceLinking/requestProof.js +13 -4
  52. package/dist/esm/core/ecdsaMaterialReadSnapshot.js +85 -0
  53. package/dist/esm/core/nearRelayerAccountProvisioning.js +2 -5
  54. package/dist/esm/core/signingLanes/WalletExecutionLaneProjection.js +3 -6
  55. package/dist/esm/core/signingMaterial/ordinaryInactiveSignerMaterialReservation.js +2 -5
  56. package/dist/esm/core/storeBackends.js +1 -1
  57. package/dist/esm/core/thresholdEcdsaChainTarget.js +1 -3
  58. package/dist/esm/hosted-wallet-gateway.js +2 -2
  59. package/dist/esm/localHostedWalletGatewayHandler.js +13 -0
  60. package/dist/esm/localIntendedMaterialAdmissionFault.js +176 -0
  61. package/dist/esm/localIntendedPresignCancellation.js +44 -0
  62. package/dist/esm/router/auth/commonRouterUtils.js +24 -10
  63. package/dist/esm/router/auth/walletSessionFailure.js +2 -5
  64. package/dist/esm/router/auth/webAuthnCredentialCodecs.js +4 -15
  65. package/dist/esm/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.js +1 -0
  66. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthBoundary.js +2 -6
  67. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +5 -27
  68. package/dist/esm/router/cloudflare/d1/auth/walletSessionCredentialReaders.js +76 -0
  69. package/dist/esm/router/cloudflare/d1/authorization/authorizedOperationStatements.js +28 -21
  70. package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +209 -44
  71. package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +8 -12
  72. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +50 -8
  73. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +1 -1
  74. package/dist/esm/router/cloudflare/d1/deviceLinking/index.js +3 -3
  75. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +12 -55
  76. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +17 -80
  77. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpDeliveryRuntime.js +6 -25
  78. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +12 -47
  79. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +24 -85
  80. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRegistrationEnrollmentFinalizer.js +7 -30
  81. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpServerSealRuntime.js +5 -20
  82. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +23 -110
  83. package/dist/esm/router/cloudflare/d1/identity/d1IdentityService.js +9 -40
  84. package/dist/esm/router/cloudflare/d1/near/d1NearPublicKeyStore.js +3 -10
  85. package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +18 -91
  86. package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +6 -30
  87. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +4 -15
  88. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +2 -7
  89. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpRecords.js +9 -13
  90. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpService.js +11 -50
  91. package/dist/esm/router/cloudflare/d1/registration/d1EvmFamilyEcdsaRegistrationBranch.js +5 -20
  92. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.js +4 -7
  93. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +2 -1
  94. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +7 -30
  95. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +32 -22
  96. package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +1 -4
  97. package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +119 -25
  98. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +31 -168
  99. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +6 -9
  100. package/dist/esm/router/cloudflare/durableObjects/thresholdStore.js +59 -66
  101. package/dist/esm/router/cloudflare/runtime/routerAbPrewarm.js +2 -2
  102. package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +5 -20
  103. package/dist/esm/router/cloudflare/runtime/tenantRootCreationGrant.js +2 -9
  104. package/dist/esm/router/cloudflare/runtime/walletControlOps.js +2 -1
  105. package/dist/esm/router/cloudflare/signingLanes/cloudflareLaneCurveExecution.js +2 -1
  106. package/dist/esm/router/cloudflare/signingLanes/cloudflareLaneProtocolCommitter.js +2 -2
  107. package/dist/esm/router/cloudflare.js +2146 -1802
  108. package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPersistence.js +5 -8
  109. package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryWalletSessionAuthorization.js +3 -6
  110. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.js +6 -25
  111. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationSideEffectBoundary.js +39 -55
  112. package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +15 -62
  113. package/dist/esm/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.js +83 -74
  114. package/dist/esm/router/domains/signingOperations/routerAbNormalSigningAdmission.js +1 -0
  115. package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +1 -0
  116. package/dist/esm/router/domains/signingOperations/walletExecutionAdmission.js +1 -4
  117. package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +7 -13
  118. package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +41 -200
  119. package/dist/esm/router/express.js +317 -699
  120. package/dist/esm/router/framework/http.js +5 -1
  121. package/dist/esm/router/framework/runtimeSnapshotConsumer.js +8 -35
  122. package/dist/esm/router/transport/fetch/createFetchRouter.js +3 -6
  123. package/dist/esm/router/transport/fetch/routes/auth.js +9 -41
  124. package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +5 -22
  125. package/dist/esm/router/transport/fetch/routes/nearPublicKeys.js +4 -16
  126. package/dist/esm/router/transport/fetch/routes/sessions.js +1 -0
  127. package/dist/esm/router/transport/fetch/routes/syncAccount.js +8 -36
  128. package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +27 -79
  129. package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +4 -1
  130. package/dist/esm/router/transport/fetch/routes/webauthnAuthenticators.js +4 -16
  131. package/dist/esm/shared-ts/src/authorization/walletSignerActivationEquality.js +12 -0
  132. package/dist/esm/shared-ts/src/device-linking/committedSignerPackages.js +2 -5
  133. package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -5
  134. package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +12 -16
  135. package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +5 -8
  136. package/dist/esm/shared-ts/src/passkey-custody/primitives.js +5 -1
  137. package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +4 -8
  138. package/dist/esm/shared-ts/src/tenant-root/tenantRootIdentifier.js +12 -0
  139. package/dist/esm/shared-ts/src/tenant-root/tenantRootIdentity.js +2 -9
  140. package/dist/esm/shared-ts/src/tenant-root/tenantRootOperationRecord.js +1 -4
  141. package/dist/esm/shared-ts/src/utils/ecdsaKeyFactsInventory.js +2 -4
  142. package/dist/esm/shared-ts/src/utils/ecdsaServerTiming.js +0 -1
  143. package/dist/esm/shared-ts/src/utils/emailOtpDomain.js +3 -1
  144. package/dist/esm/shared-ts/src/utils/exactKeys.js +17 -0
  145. package/dist/esm/shared-ts/src/utils/failure.js +20 -0
  146. package/dist/esm/shared-ts/src/utils/registrationIntent.js +3 -12
  147. package/dist/esm/shared-ts/src/utils/registrationSignerPlan.js +2 -5
  148. package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -1
  149. package/dist/esm/shared-ts/src/utils/routerAbEd25519Yao.js +1 -1
  150. package/dist/esm/shared-ts/src/utils/thresholdEcdsaChainTarget.js +9 -0
  151. package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -4
  152. package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +10 -32
  153. package/dist/esm/threshold/session/signingSessionSeal/idempotencyBackends.js +3 -3
  154. package/dist/esm/threshold/session/signingSessionSeal/idempotencyRecords.js +3 -9
  155. package/dist/esm/threshold/session/signingSessionSeal/service.js +8 -35
  156. package/dist/esm/threshold/session/signingSessionSeal/transport/express.js +18 -94
  157. package/dist/esm/threshold/session/signingSessionSeal/transport/fetch.js +6 -30
  158. package/dist/esm/threshold/session/signingSessionSeal/transport/shared.js +5 -20
  159. package/dist/esm/wasm/evm_crypto/pkg/evm_crypto_bg.wasm +0 -0
  160. package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
  161. package/dist/types/shared-ts/src/authorization/delegatedAuthority.d.ts +2 -1
  162. package/dist/types/shared-ts/src/authorization/walletSessionIssuance.d.ts +9 -2
  163. package/dist/types/shared-ts/src/authorization/walletSignerActivationEquality.d.ts +4 -0
  164. package/dist/types/shared-ts/src/device-linking/committedSignerPackages.d.ts +3 -4
  165. package/dist/types/shared-ts/src/device-linking/contracts.d.ts +5 -63
  166. package/dist/types/shared-ts/src/device-linking/sourceContribution.d.ts +2 -0
  167. package/dist/types/shared-ts/src/passkey-custody/custodyEnvelope.d.ts +5 -12
  168. package/dist/types/shared-ts/src/passkey-custody/primitives.d.ts +9 -0
  169. package/dist/types/shared-ts/src/signing-lanes/execution.d.ts +11 -1
  170. package/dist/types/shared-ts/src/signing-lanes/ids.d.ts +1 -10
  171. package/dist/types/shared-ts/src/signing-lanes/rotation.d.ts +3 -5
  172. package/dist/types/shared-ts/src/tenant-root/tenantRootIdentifier.d.ts +3 -0
  173. package/dist/types/shared-ts/src/tenant-root/tenantRootOperationRecord.d.ts +2 -1
  174. package/dist/types/shared-ts/src/threshold/ecdsaDerivationRoleLocalBootstrap.d.ts +6 -0
  175. package/dist/types/shared-ts/src/threshold/signingRootScope.d.ts +1 -0
  176. package/dist/types/shared-ts/src/utils/ecdsaKeyFactsInventory.d.ts +2 -11
  177. package/dist/types/shared-ts/src/utils/eip1559TxWasmJson.d.ts +16 -0
  178. package/dist/types/shared-ts/src/utils/emailOtpDomain.d.ts +2 -0
  179. package/dist/types/shared-ts/src/utils/exactKeys.d.ts +11 -0
  180. package/dist/types/shared-ts/src/utils/failure.d.ts +12 -0
  181. package/dist/types/shared-ts/src/utils/jsonRpc.d.ts +3 -4
  182. package/dist/types/shared-ts/src/utils/nearRpcResults.d.ts +1 -0
  183. package/dist/types/shared-ts/src/utils/registrationAuthMethodInput.d.ts +3 -8
  184. package/dist/types/shared-ts/src/utils/registrationSignerPlan.d.ts +7 -19
  185. package/dist/types/shared-ts/src/utils/routerAbEcdsaDerivation.d.ts +3 -1
  186. package/dist/types/shared-ts/src/utils/routerAbEd25519Yao.d.ts +1 -0
  187. package/dist/types/shared-ts/src/utils/routerAbEd25519YaoDigests.d.ts +3 -4
  188. package/dist/types/shared-ts/src/utils/routerAbNormalSigningIdentity.d.ts +30 -8
  189. package/dist/types/shared-ts/src/utils/routerApiKeyAuth.d.ts +2 -0
  190. package/dist/types/shared-ts/src/utils/signingSessionSeal.d.ts +10 -11
  191. package/dist/types/shared-ts/src/utils/thresholdEcdsaChainTarget.d.ts +25 -0
  192. package/dist/types/shared-ts/src/utils/variant.d.ts +18 -0
  193. package/dist/types/shared-ts/src/utils/walletAuthMethodRecord.d.ts +3 -6
  194. package/dist/types/shared-ts/src/utils/webauthnDeviceInfo.d.ts +4 -2
  195. package/dist/types/shared-ts/src/wallet-recovery/recoveryEnvelopes.d.ts +3 -16
  196. package/dist/types/shared-ts/src/wallet-recovery/walletRecoveryPreparation.d.ts +15 -0
  197. package/dist/types/shared-ts/src/wallet-recovery/walletRecoveryTarget.d.ts +3 -4
  198. package/dist/types/wallet-server/src/authorization/domain.d.ts +13 -2
  199. package/dist/types/wallet-server/src/authorization/ecdsaWalletSessionAdmission.d.ts +27 -3
  200. package/dist/types/wallet-server/src/authorization/service.d.ts +19 -0
  201. package/dist/types/wallet-server/src/core/ThresholdService/stores/SessionStore.d.ts +2 -2
  202. package/dist/types/wallet-server/src/core/ThresholdService/stores/WalletSessionStore.d.ts +1 -1
  203. package/dist/types/wallet-server/src/core/ThresholdService/stores/exportReplayGuard.d.ts +3 -0
  204. package/dist/types/wallet-server/src/core/ThresholdService/validation.d.ts +8 -101
  205. package/dist/types/wallet-server/src/core/WebAuthnAuthenticatorStore.d.ts +8 -0
  206. package/dist/types/wallet-server/src/core/authService/bytes.d.ts +0 -1
  207. package/dist/types/wallet-server/src/core/authService/emailOtpChallenges.d.ts +2 -10
  208. package/dist/types/wallet-server/src/core/authService/emailOtpSeal.d.ts +1 -1
  209. package/dist/types/wallet-server/src/core/authService/emailOtpUnlock.d.ts +3 -10
  210. package/dist/types/wallet-server/src/core/d1EcdsaSignerRead.d.ts +39 -0
  211. package/dist/types/wallet-server/src/core/d1WalletStore.d.ts +10 -0
  212. package/dist/types/wallet-server/src/core/deviceLinking/linkedDeviceSessionRecord.d.ts +3 -4
  213. package/dist/types/wallet-server/src/core/ecdsaMaterialReadSnapshot.d.ts +19 -0
  214. package/dist/types/wallet-server/src/core/routerAbSigning/RouterAbNormalSigningRuntime.d.ts +3 -5
  215. package/dist/types/wallet-server/src/core/rpcClients/near/NearClient.d.ts +1 -2
  216. package/dist/types/wallet-server/src/core/signingLanes/WalletExecutionLaneProjection.d.ts +2 -11
  217. package/dist/types/wallet-server/src/core/signingLanes/signingWorkerLaneMaterialIdentity.d.ts +2 -19
  218. package/dist/types/wallet-server/src/core/thresholdEcdsaChainTarget.d.ts +3 -11
  219. package/dist/types/wallet-server/src/core/types.d.ts +2 -6
  220. package/dist/types/wallet-server/src/localIntendedMaterialAdmissionFault.d.ts +38 -0
  221. package/dist/types/wallet-server/src/localIntendedPresignCancellation.d.ts +4 -0
  222. package/dist/types/wallet-server/src/router/auth/authRequestValidation.d.ts +4 -9
  223. package/dist/types/wallet-server/src/router/auth/commonRouterUtils.d.ts +15 -1
  224. package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RouterApiAuthBoundary.d.ts +0 -1
  225. package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RouterApiAuthService.d.ts +1 -1
  226. package/dist/types/wallet-server/src/router/cloudflare/d1/auth/walletSessionCredentialReaders.d.ts +9 -0
  227. package/dist/types/wallet-server/src/router/cloudflare/d1/authorization/authorizedOperationStatements.d.ts +4 -0
  228. package/dist/types/wallet-server/src/router/cloudflare/d1/authorization/d1AuthorizationStore.d.ts +10 -1
  229. package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.d.ts +19 -2
  230. package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.d.ts +2 -6
  231. package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.d.ts +5 -8
  232. package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpEnrollmentStore.d.ts +2 -8
  233. package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpRateLimitStore.d.ts +2 -9
  234. package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.d.ts +5 -5
  235. package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpServerSealRuntime.d.ts +4 -14
  236. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.d.ts +2 -6
  237. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationService.d.ts +8 -6
  238. package/dist/types/wallet-server/src/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.d.ts +14 -1
  239. package/dist/types/wallet-server/src/router/cloudflare/d1/webauthn/d1WebAuthnRecords.d.ts +10 -39
  240. package/dist/types/wallet-server/src/router/cloudflare/runtime/walletConsoleOps.d.ts +8 -34
  241. package/dist/types/wallet-server/src/router/domains/ecdsa/thresholdEcdsaRequestValidation.d.ts +3 -15
  242. package/dist/types/wallet-server/src/router/domains/ed25519Yao/session/routerAbEd25519YaoWalletSession.d.ts +9 -50
  243. package/dist/types/wallet-server/src/router/domains/passkeyCustody/walletRecoveryKeyManifest.d.ts +1 -13
  244. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.d.ts +8 -9
  245. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbNormalSigningAdmission.d.ts +13 -0
  246. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbOperationStepUp.d.ts +3 -4
  247. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbPrivateSigningWorker.d.ts +7 -16
  248. package/dist/types/wallet-server/src/router/domains/syncAccount/syncAccountRequestValidation.d.ts +2 -7
  249. package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +3 -1
  250. package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +25 -4
  251. package/dist/types/wallet-server/src/router/framework/http.d.ts +1 -0
  252. package/dist/types/wallet-server/src/router/framework/ror/normalize.d.ts +1 -9
  253. package/dist/types/wallet-server/src/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.d.ts +3 -6
  254. package/dist/types/wallet-server/src/router/transport/fetch/routes/syncAccountBootstrap.d.ts +3 -5
  255. package/dist/types/wallet-server/src/router/transport/fetch/routes/thresholdEcdsa.d.ts +0 -1
  256. package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/idempotencyRecords.d.ts +1 -2
  257. package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/signingSessionSeal.types.d.ts +6 -8
  258. package/package.json +1 -1
  259. package/dist/esm/wasm/router_ab_ecdsa_signing_worker/pkg/router_ab_ecdsa_signing_worker_bg.wasm +0 -0
@@ -1,4 +1,5 @@
1
1
  import { ROUTER_AB_ED25519_YAO_EXPORT_ADMISSION_PATH_V1, ROUTER_AB_ED25519_YAO_EXPORT_EXECUTE_PATH_V1, ROUTER_AB_ED25519_YAO_RECOVERY_ACTIVATE_PATH_V1, ROUTER_AB_ED25519_YAO_RECOVERY_ADMISSION_PATH_V1, ROUTER_AB_ED25519_YAO_RECOVERY_EXECUTE_PATH_V1, ROUTER_AB_ED25519_YAO_REGISTRATION_ADMISSION_PATH_V1, ROUTER_AB_ED25519_YAO_REGISTRATION_EXECUTE_PATH_V1 } from "../../../../shared-ts/src/utils/routerAbEd25519Yao.js";
2
+ import { hasExactKeys } from "../../../../shared-ts/src/utils/exactKeys.js";
2
3
  import { parseRouterAbEd25519YaoProductRegistrationStateV1 } from "./routerAbEd25519YaoProductRegistration.js";
3
4
  //#region src/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPersistence.ts
4
5
  /** Bind the generic JSON adapter to the validated opaque ceremony key. */
@@ -194,7 +195,7 @@ function decodeRouterAbEd25519YaoProductRegistrationStateValueV1(value) {
194
195
  };
195
196
  }
196
197
  function decodeRouterAbEd25519YaoProductRegistrationBytesV1(value) {
197
- if (!hasExactRouterAbEd25519YaoProductRegistrationJsonKeys(value, ["__seamsType", "values"]) || value.__seamsType !== BYTES_KIND || !Array.isArray(value.values)) return { ok: false };
198
+ if (!hasExactKeys(value, ["__seamsType", "values"]) || value.__seamsType !== BYTES_KIND || !Array.isArray(value.values)) return { ok: false };
198
199
  const bytes = [];
199
200
  for (const entry of value.values) {
200
201
  if (typeof entry !== "number" || !Number.isSafeInteger(entry) || entry < 0 || entry > 255) return { ok: false };
@@ -206,7 +207,7 @@ function decodeRouterAbEd25519YaoProductRegistrationBytesV1(value) {
206
207
  };
207
208
  }
208
209
  function decodeRouterAbEd25519YaoProductRegistrationMapV1(value) {
209
- if (!hasExactRouterAbEd25519YaoProductRegistrationJsonKeys(value, ["__seamsType", "entries"]) || value.__seamsType !== MAP_KIND || !Array.isArray(value.entries)) return { ok: false };
210
+ if (!hasExactKeys(value, ["__seamsType", "entries"]) || value.__seamsType !== MAP_KIND || !Array.isArray(value.entries)) return { ok: false };
210
211
  const map = /* @__PURE__ */ new Map();
211
212
  const keys = /* @__PURE__ */ new Set();
212
213
  for (const entry of value.entries) {
@@ -223,7 +224,7 @@ function decodeRouterAbEd25519YaoProductRegistrationMapV1(value) {
223
224
  };
224
225
  }
225
226
  function decodeRouterAbEd25519YaoProductRegistrationSetV1(value) {
226
- if (!hasExactRouterAbEd25519YaoProductRegistrationJsonKeys(value, ["__seamsType", "values"]) || value.__seamsType !== SET_KIND || !Array.isArray(value.values)) return { ok: false };
227
+ if (!hasExactKeys(value, ["__seamsType", "values"]) || value.__seamsType !== SET_KIND || !Array.isArray(value.values)) return { ok: false };
227
228
  const set = /* @__PURE__ */ new Set();
228
229
  const encodedEntries = /* @__PURE__ */ new Set();
229
230
  for (const entry of value.values) {
@@ -255,11 +256,7 @@ function readRouterAbEd25519YaoCeremonyKeyObjectV1(input) {
255
256
  }
256
257
  function exactRouterAbEd25519YaoProductRegistrationStateEnvelopeV1(input) {
257
258
  if (!isRouterAbEd25519YaoProductRegistrationJsonObjectV1(input)) return null;
258
- return hasExactRouterAbEd25519YaoProductRegistrationJsonKeys(input, ["kind", "state"]) ? input : null;
259
- }
260
- function hasExactRouterAbEd25519YaoProductRegistrationJsonKeys(input, fields) {
261
- const actual = Object.keys(input);
262
- return actual.length === fields.length && actual.every((field) => fields.some((expectedField) => expectedField === field));
259
+ return hasExactKeys(input, ["kind", "state"]) ? input : null;
263
260
  }
264
261
  function assertNever(value) {
265
262
  throw new Error(`Unsupported Ed25519 Yao ceremony field: ${String(value)}`);
@@ -1,7 +1,7 @@
1
1
  import { NEAR_ED25519_MPC_OPERATION_KINDS } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
2
2
  import { base64UrlEncode } from "../../../../shared-ts/src/utils/base64.js";
3
3
  import { routerAbMpcMaterialActivationRefToWire, sameRouterAbMpcMaterialActivationRef } from "../../../../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
4
- import "../../../../shared-ts/src/utils/routerAbEd25519Yao.js";
4
+ import { sameRouterAbEd25519YaoByteSequence } from "../../../../shared-ts/src/utils/routerAbEd25519Yao.js";
5
5
  import { extractBearerCredential } from "../../../auth/routerApiKeyAuth.js";
6
6
  import { walletSessionFailureMessage } from "../../../auth/walletSessionFailure.js";
7
7
  import { resolveWalletSessionAuthorizationV2Admission } from "../../signingOperations/walletExecutionAdmission.js";
@@ -16,9 +16,6 @@ function authorizationFailure(input) {
16
16
  message: input.message
17
17
  };
18
18
  }
19
- function sameRouterAbEd25519YaoByteSequenceV1(left, right) {
20
- return left.length === right.length && left.every((value, index) => value === right[index]);
21
- }
22
19
  function sameRouterAbEd25519YaoApplicationBindingV1(left, right) {
23
20
  return left.wallet_id === right.wallet_id && left.near_ed25519_signing_key_id === right.near_ed25519_signing_key_id && left.signing_root_id === right.signing_root_id && left.key_creation_signer_slot === right.key_creation_signer_slot;
24
21
  }
@@ -28,7 +25,7 @@ async function entryMatchesAdmission(input) {
28
25
  keySetId: input.entry.keySetId
29
26
  });
30
27
  const basis = input.entry.recoveryBasis;
31
- return String(input.prepared.walletId) === input.request.scope.account_id && String(input.prepared.walletId) === input.request.application_binding.wallet_id && input.request.scope.lifecycle_id === expectedLifecycleId && input.request.scope.threshold_session_id === `${expectedLifecycleId}:threshold-session` && input.request.scope.root_share_epoch === basis.scope.root_share_epoch && input.request.scope.account_id === basis.scope.account_id && input.request.scope.signer_set_id === basis.scope.signer_set_id && input.request.scope.signing_worker_id === basis.scope.signing_worker_id && sameRouterAbMpcMaterialActivationRef(input.request.active_material_activation, basis.activeMaterialActivation) && sameRouterAbEd25519YaoApplicationBindingV1(input.request.application_binding, basis.applicationBinding) && input.request.participant_ids[0] === basis.participantIds[0] && input.request.participant_ids[1] === basis.participantIds[1] && sameRouterAbEd25519YaoByteSequenceV1(input.request.active_capability_binding, basis.activeCapabilityBinding) && sameRouterAbEd25519YaoByteSequenceV1(input.request.registered_public_key, basis.registeredPublicKey);
28
+ return String(input.prepared.walletId) === input.request.scope.account_id && String(input.prepared.walletId) === input.request.application_binding.wallet_id && input.request.scope.lifecycle_id === expectedLifecycleId && input.request.scope.threshold_session_id === `${expectedLifecycleId}:threshold-session` && input.request.scope.root_share_epoch === basis.scope.root_share_epoch && input.request.scope.account_id === basis.scope.account_id && input.request.scope.signer_set_id === basis.scope.signer_set_id && input.request.scope.signing_worker_id === basis.scope.signing_worker_id && sameRouterAbMpcMaterialActivationRef(input.request.active_material_activation, basis.activeMaterialActivation) && sameRouterAbEd25519YaoApplicationBindingV1(input.request.application_binding, basis.applicationBinding) && input.request.participant_ids[0] === basis.participantIds[0] && input.request.participant_ids[1] === basis.participantIds[1] && sameRouterAbEd25519YaoByteSequence(input.request.active_capability_binding, basis.activeCapabilityBinding) && sameRouterAbEd25519YaoByteSequence(input.request.registered_public_key, basis.registeredPublicKey);
32
29
  }
33
30
  async function authorizePreparedRecovery(input) {
34
31
  const challengeId = String(input.request.request.headers.get("x-seams-wallet-recovery-challenge-id") || "").trim();
@@ -249,7 +246,7 @@ function exactRecoveryAdmissionMatches(input) {
249
246
  const identity = input.activeMaterial.exportIdentity;
250
247
  const walletId = String(input.admission.context.authorization.session.walletId);
251
248
  const registeredPublicKeyB64u = base64UrlEncode(Uint8Array.from(identity.registered_public_key));
252
- return String(input.admission.admission.signer.walletId) === walletId && registeredPublicKeyB64u === input.admission.admission.signer.registeredPublicKeyB64u && request.scope.account_id === walletId && request.application_binding.wallet_id === walletId && sameRouterAbMpcMaterialActivationRef(request.active_material_activation, input.materialActivation) && sameRouterAbMpcMaterialActivationRef(input.activeMaterial.materialActivation, input.materialActivation) && sameRouterAbMpcMaterialActivationRef(identity.scope.material_activation, input.materialActivation) && request.scope.root_share_epoch === identity.scope.root_share_epoch && request.scope.account_id === identity.scope.account_id && request.scope.threshold_session_id === identity.scope.threshold_session_id && request.scope.signer_set_id === identity.scope.signer_set_id && request.scope.signing_worker_id === identity.scope.signing_worker_id && input.activeMaterial.runtimePolicyScope.signingRootVersion === request.scope.root_share_epoch && input.activeMaterial.nearAccountId.length > 0 && input.activeMaterial.signerSlot === request.application_binding.key_creation_signer_slot && input.activeMaterial.signingWorkerId === request.scope.signing_worker_id && sameRouterAbEd25519YaoApplicationBindingV1(request.application_binding, identity.application_binding) && request.participant_ids[0] === input.activeMaterial.participantIds[0] && request.participant_ids[1] === input.activeMaterial.participantIds[1] && request.participant_ids[0] === identity.participant_ids[0] && request.participant_ids[1] === identity.participant_ids[1] && sameRouterAbEd25519YaoByteSequenceV1(request.registered_public_key, identity.registered_public_key);
249
+ return String(input.admission.admission.signer.walletId) === walletId && registeredPublicKeyB64u === input.admission.admission.signer.registeredPublicKeyB64u && request.scope.account_id === walletId && request.application_binding.wallet_id === walletId && sameRouterAbMpcMaterialActivationRef(request.active_material_activation, input.materialActivation) && sameRouterAbMpcMaterialActivationRef(input.activeMaterial.materialActivation, input.materialActivation) && sameRouterAbMpcMaterialActivationRef(identity.scope.material_activation, input.materialActivation) && request.scope.root_share_epoch === identity.scope.root_share_epoch && request.scope.account_id === identity.scope.account_id && request.scope.threshold_session_id === identity.scope.threshold_session_id && request.scope.signer_set_id === identity.scope.signer_set_id && request.scope.signing_worker_id === identity.scope.signing_worker_id && input.activeMaterial.runtimePolicyScope.signingRootVersion === request.scope.root_share_epoch && input.activeMaterial.nearAccountId.length > 0 && input.activeMaterial.signerSlot === request.application_binding.key_creation_signer_slot && input.activeMaterial.signingWorkerId === request.scope.signing_worker_id && sameRouterAbEd25519YaoApplicationBindingV1(request.application_binding, identity.application_binding) && request.participant_ids[0] === input.activeMaterial.participantIds[0] && request.participant_ids[1] === input.activeMaterial.participantIds[1] && request.participant_ids[0] === identity.participant_ids[0] && request.participant_ids[1] === identity.participant_ids[1] && sameRouterAbEd25519YaoByteSequence(request.registered_public_key, identity.registered_public_key);
253
250
  }
254
251
  async function authorizeV2RecoveryAdmission(input) {
255
252
  const resolved = await resolveExactEd25519OperationCredentialMaterial({
@@ -1,6 +1,7 @@
1
1
  import { sameRouterAbMpcMaterialActivationRef } from "../../../../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
2
2
  import { deriveRouterAbEd25519YaoStableContextBindingV1 } from "../../../../shared-ts/src/utils/routerAbEd25519YaoDigests.js";
3
3
  import { deriveSigningRootId } from "../../../../shared-ts/src/threshold/signingRootScope.js";
4
+ import { failure } from "../../../../shared-ts/src/utils/failure.js";
4
5
  import { computeAddSignerNearEd25519SigningKeyId } from "../../../../shared-ts/src/utils/registrationIds.js";
5
6
  import { findRegistrationSignerPlanNearEd25519Branch, registrationNearEd25519BranchKey, registrationSignerPlanFromSelection } from "../../../../shared-ts/src/utils/registrationSignerPlan.js";
6
7
  //#region src/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.ts
@@ -217,21 +218,9 @@ var InMemoryRouterAbEd25519YaoRegistrationIntentAuthorizationAdapter = class {
217
218
  }
218
219
  async bindVerifiedIntent(verified) {
219
220
  const credential = activationIntentCredential(verified);
220
- if (!VERIFIED_INTENT_CREDENTIAL.test(credential)) return {
221
- ok: false,
222
- code: "invalid_registration_intent",
223
- message: "registration intent grant is not a canonical Bearer credential"
224
- };
225
- if (!Number.isSafeInteger(verified.expiresAtMs) || verified.expiresAtMs <= Date.now()) return {
226
- ok: false,
227
- code: "invalid_registration_intent",
228
- message: "registration intent authority is expired"
229
- };
230
- if (!await activationIntentMatchesAdmission(verified)) return {
231
- ok: false,
232
- code: "invalid_registration_intent",
233
- message: "registration intent does not match the Ed25519 Yao admission subject"
234
- };
221
+ if (!VERIFIED_INTENT_CREDENTIAL.test(credential)) return failure("invalid_registration_intent", "registration intent grant is not a canonical Bearer credential");
222
+ if (!Number.isSafeInteger(verified.expiresAtMs) || verified.expiresAtMs <= Date.now()) return failure("invalid_registration_intent", "registration intent authority is expired");
223
+ if (!await activationIntentMatchesAdmission(verified)) return failure("invalid_registration_intent", "registration intent does not match the Ed25519 Yao admission subject");
235
224
  const credentialDigest = await credentialDigestSha256(credential);
236
225
  const purpose = activationIntentPurpose(verified);
237
226
  const copiedAdmissionRequest = copyAdmissionRequest(verified.admissionRequest);
@@ -245,11 +234,7 @@ var InMemoryRouterAbEd25519YaoRegistrationIntentAuthorizationAdapter = class {
245
234
  return exactRetry ? {
246
235
  ok: true,
247
236
  admissionRequest: copyAdmissionRequest(existing.admissionRequest)
248
- } : {
249
- ok: false,
250
- code: "registration_intent_conflict",
251
- message: "registration intent credential or lifecycle is already bound"
252
- };
237
+ } : failure("registration_intent_conflict", "registration intent credential or lifecycle is already bound");
253
238
  }
254
239
  this.authorities.push({
255
240
  kind: "available",
@@ -266,11 +251,7 @@ var InMemoryRouterAbEd25519YaoRegistrationIntentAuthorizationAdapter = class {
266
251
  }
267
252
  async bindVerifiedContinuation(verified) {
268
253
  const existing = findAuthorityByLifecycleId(this.authorities, verified.admissionRequest.scope.lifecycle_id);
269
- if (!existing || existing.authority.purpose !== "wallet_registration" || existing.authority.admissionFingerprint !== canonicalAdmissionRequest(verified.admissionRequest) || !Number.isSafeInteger(verified.expiresAtMs) || verified.expiresAtMs <= Date.now() || !verified.credential.startsWith("wst_") || !VERIFIED_INTENT_CREDENTIAL.test(verified.credential)) return {
270
- ok: false,
271
- code: "registration_intent_conflict",
272
- message: "NEAR continuation does not match its original authorization"
273
- };
254
+ if (!existing || existing.authority.purpose !== "wallet_registration" || existing.authority.admissionFingerprint !== canonicalAdmissionRequest(verified.admissionRequest) || !Number.isSafeInteger(verified.expiresAtMs) || verified.expiresAtMs <= Date.now() || !verified.credential.startsWith("wst_") || !VERIFIED_INTENT_CREDENTIAL.test(verified.credential)) return failure("registration_intent_conflict", "NEAR continuation does not match its original authorization");
274
255
  this.authorities[existing.index] = {
275
256
  kind: existing.authority.kind,
276
257
  purpose: existing.authority.purpose,
@@ -1,3 +1,4 @@
1
+ import { hasExactKeys } from "../../../../shared-ts/src/utils/exactKeys.js";
1
2
  //#region src/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationSideEffectBoundary.ts
2
3
  const SIDE_EFFECT_CLAIM_FIELDS = [
3
4
  "kind",
@@ -34,79 +35,66 @@ function throwIfRouterAbEd25519YaoRetryableSideEffectFailureV1(failure) {
34
35
  function parseRouterAbEd25519YaoRegistrationSideEffectRecordV2(raw, input) {
35
36
  const record = readRouterAbEd25519YaoRegistrationSideEffectRecordObjectV1(raw);
36
37
  if (record === null || record.operation !== input.operation) return null;
37
- if (record.kind === "router_ab_ed25519_yao_registration_side_effect_claim_v1") {
38
- if (!hasExactRouterAbEd25519YaoRegistrationSideEffectRecordKeys(record, SIDE_EFFECT_CLAIM_FIELDS)) return null;
39
- const requestFingerprint = parseFingerprint(record.requestFingerprint);
40
- const preparedArtifactFingerprint = parsePreparedFingerprint(record.preparedArtifactFingerprint);
41
- const claimedAtMs = parseTimestamp(record.claimedAtMs);
42
- const prepared = input.parsePrepared(record.prepared);
43
- if (requestFingerprint === null || preparedArtifactFingerprint === null || claimedAtMs === null || prepared === null) return null;
44
- return {
45
- kind: "router_ab_ed25519_yao_registration_side_effect_claim_v1",
46
- operation: input.operation,
47
- requestFingerprint,
48
- preparedArtifactFingerprint,
49
- claimedAtMs,
50
- prepared
51
- };
52
- }
53
- if (record.kind !== "router_ab_ed25519_yao_registration_side_effect_completion_v2" || !hasExactRouterAbEd25519YaoRegistrationSideEffectRecordKeys(record, SIDE_EFFECT_COMPLETION_V2_FIELDS)) return null;
54
- const requestFingerprint = parseFingerprint(record.requestFingerprint);
55
- const preparedArtifactFingerprint = parsePreparedFingerprint(record.preparedArtifactFingerprint);
56
- const claimedAtMs = parseTimestamp(record.claimedAtMs);
57
- const prepared = input.parsePrepared(record.prepared);
58
- if (requestFingerprint === null || preparedArtifactFingerprint === null || claimedAtMs === null || prepared === null) return null;
38
+ if (record.kind === "router_ab_ed25519_yao_registration_side_effect_claim_v1") return parseRouterAbEd25519YaoRegistrationSideEffectClaimV1(record, input);
39
+ if (record.kind !== "router_ab_ed25519_yao_registration_side_effect_completion_v2" || !hasExactKeys(record, SIDE_EFFECT_COMPLETION_V2_FIELDS)) return null;
40
+ const claim = parseRouterAbEd25519YaoRegistrationSideEffectClaimFields(record, input.parsePrepared);
41
+ if (claim === null) return null;
59
42
  const completedAtMs = parseTimestamp(record.completedAtMs);
60
43
  const receipt = input.parseReceipt(record.receipt);
61
44
  if (completedAtMs === null || receipt === null) return null;
62
45
  return {
63
46
  kind: "router_ab_ed25519_yao_registration_side_effect_completion_v2",
64
47
  operation: input.operation,
65
- requestFingerprint,
66
- preparedArtifactFingerprint,
67
- claimedAtMs,
48
+ requestFingerprint: claim.requestFingerprint,
49
+ preparedArtifactFingerprint: claim.preparedArtifactFingerprint,
50
+ claimedAtMs: claim.claimedAtMs,
68
51
  completedAtMs,
69
- prepared,
52
+ prepared: claim.prepared,
70
53
  receipt
71
54
  };
72
55
  }
73
56
  function parseRouterAbEd25519YaoRegistrationSideEffectRecordV1(raw, input) {
74
57
  const record = readRouterAbEd25519YaoRegistrationSideEffectRecordObjectV1(raw);
75
58
  if (record === null || record.operation !== input.operation) return null;
76
- if (record.kind === "router_ab_ed25519_yao_registration_side_effect_claim_v1") {
77
- if (!hasExactRouterAbEd25519YaoRegistrationSideEffectRecordKeys(record, SIDE_EFFECT_CLAIM_FIELDS)) return null;
78
- const requestFingerprint = parseFingerprint(record.requestFingerprint);
79
- const preparedArtifactFingerprint = parsePreparedFingerprint(record.preparedArtifactFingerprint);
80
- const claimedAtMs = parseTimestamp(record.claimedAtMs);
81
- const prepared = input.parsePrepared(record.prepared);
82
- if (requestFingerprint === null || preparedArtifactFingerprint === null || claimedAtMs === null || prepared === null) return null;
83
- return {
84
- kind: "router_ab_ed25519_yao_registration_side_effect_claim_v1",
85
- operation: input.operation,
86
- requestFingerprint,
87
- preparedArtifactFingerprint,
88
- claimedAtMs,
89
- prepared
90
- };
91
- }
92
- if (record.kind !== "router_ab_ed25519_yao_registration_side_effect_completion_v1" || !hasExactRouterAbEd25519YaoRegistrationSideEffectRecordKeys(record, SIDE_EFFECT_COMPLETION_V1_FIELDS)) return null;
93
- const requestFingerprint = parseFingerprint(record.requestFingerprint);
94
- const preparedArtifactFingerprint = parsePreparedFingerprint(record.preparedArtifactFingerprint);
95
- const claimedAtMs = parseTimestamp(record.claimedAtMs);
96
- const prepared = input.parsePrepared(record.prepared);
97
- if (requestFingerprint === null || preparedArtifactFingerprint === null || claimedAtMs === null || prepared === null) return null;
59
+ if (record.kind === "router_ab_ed25519_yao_registration_side_effect_claim_v1") return parseRouterAbEd25519YaoRegistrationSideEffectClaimV1(record, input);
60
+ if (record.kind !== "router_ab_ed25519_yao_registration_side_effect_completion_v1" || !hasExactKeys(record, SIDE_EFFECT_COMPLETION_V1_FIELDS)) return null;
61
+ const claim = parseRouterAbEd25519YaoRegistrationSideEffectClaimFields(record, input.parsePrepared);
62
+ if (claim === null) return null;
98
63
  const completedAtMs = parseTimestamp(record.completedAtMs);
99
64
  const response = input.parseResponse(record.response);
100
65
  if (completedAtMs === null || response === null) return null;
101
66
  return {
102
67
  kind: "router_ab_ed25519_yao_registration_side_effect_completion_v1",
103
68
  operation: input.operation,
69
+ requestFingerprint: claim.requestFingerprint,
70
+ preparedArtifactFingerprint: claim.preparedArtifactFingerprint,
71
+ claimedAtMs: claim.claimedAtMs,
72
+ completedAtMs,
73
+ prepared: claim.prepared,
74
+ response
75
+ };
76
+ }
77
+ function parseRouterAbEd25519YaoRegistrationSideEffectClaimV1(record, input) {
78
+ if (!hasExactKeys(record, SIDE_EFFECT_CLAIM_FIELDS)) return null;
79
+ const claim = parseRouterAbEd25519YaoRegistrationSideEffectClaimFields(record, input.parsePrepared);
80
+ if (claim === null) return null;
81
+ return {
82
+ kind: "router_ab_ed25519_yao_registration_side_effect_claim_v1",
83
+ operation: input.operation,
84
+ ...claim
85
+ };
86
+ }
87
+ function parseRouterAbEd25519YaoRegistrationSideEffectClaimFields(record, parsePrepared) {
88
+ const requestFingerprint = parseFingerprint(record.requestFingerprint);
89
+ const preparedArtifactFingerprint = parsePreparedFingerprint(record.preparedArtifactFingerprint);
90
+ const claimedAtMs = parseTimestamp(record.claimedAtMs);
91
+ const prepared = parsePrepared(record.prepared);
92
+ if (requestFingerprint === null || preparedArtifactFingerprint === null || claimedAtMs === null || prepared === null) return null;
93
+ return {
104
94
  requestFingerprint,
105
95
  preparedArtifactFingerprint,
106
96
  claimedAtMs,
107
- completedAtMs,
108
- prepared,
109
- response
97
+ prepared
110
98
  };
111
99
  }
112
100
  /**
@@ -403,10 +391,6 @@ function readRouterAbEd25519YaoRegistrationSideEffectRecordObjectV1(value) {
403
391
  function isRouterAbEd25519YaoRegistrationSideEffectRecordObjectV1(value) {
404
392
  return typeof value === "object" && value !== null && !Array.isArray(value);
405
393
  }
406
- function hasExactRouterAbEd25519YaoRegistrationSideEffectRecordKeys(record, expectedKeys) {
407
- const actualKeys = Object.keys(record);
408
- return actualKeys.length === expectedKeys.length && actualKeys.every((key) => expectedKeys.some((expectedKey) => expectedKey === key));
409
- }
410
394
  function parseFingerprint(value) {
411
395
  return typeof value === "string" && /^[a-zA-Z0-9_-]{32,128}$/u.test(value) ? value : null;
412
396
  }
@@ -2,9 +2,10 @@ import { base64UrlDecode, base64UrlEncode } from "../../../shared-ts/src/utils/b
2
2
  import "../../../shared-ts/src/utils/encoders.js";
3
3
  import { normalizeOptionalTrimmedString } from "../../../shared-ts/src/utils/normalize.js";
4
4
  import { isPlainObject } from "../../../shared-ts/src/utils/validation.js";
5
+ import { failure } from "../../../shared-ts/src/utils/failure.js";
5
6
  import { emailOtpStatusCode } from "./emailOtpSessionRouteHelpers.js";
7
+ import { EMAIL_OTP_FACTOR_RELEASE_AAD_DOMAIN_V1 } from "../../../shared-ts/src/utils/emailOtpDomain.js";
6
8
  //#region src/router/domains/emailOtp/emailOtpRouteHandlers.ts
7
- const EMAIL_OTP_FACTOR_RELEASE_AAD_DOMAIN = "seams/email-otp/factor-release/v1";
8
9
  function decodeEmailOtpFactorSecret32(value) {
9
10
  const magnitude = base64UrlDecode(value);
10
11
  if (magnitude.length === 0 || magnitude.length > 32) {
@@ -18,7 +19,7 @@ function decodeEmailOtpFactorSecret32(value) {
18
19
  }
19
20
  function emailOtpFactorReleaseAad(input) {
20
21
  return new TextEncoder().encode([
21
- EMAIL_OTP_FACTOR_RELEASE_AAD_DOMAIN,
22
+ EMAIL_OTP_FACTOR_RELEASE_AAD_DOMAIN_V1,
22
23
  input.walletId,
23
24
  input.enrollmentId,
24
25
  input.enrollmentSealKeyVersion,
@@ -32,19 +33,11 @@ async function sealEmailOtpFactorSecretForWorker(input) {
32
33
  factorSecret32 = decodeEmailOtpFactorSecret32(input.factorSecret32B64u);
33
34
  workerPublicKey65 = base64UrlDecode(input.workerEphemeralPublicKey65B64u);
34
35
  } catch {
35
- return {
36
- ok: false,
37
- code: "invalid_body",
38
- message: "Email OTP factor release key is invalid"
39
- };
36
+ return failure("invalid_body", "Email OTP factor release key is invalid");
40
37
  }
41
38
  if (workerPublicKey65.length !== 65 || workerPublicKey65[0] !== 4) {
42
39
  factorSecret32.fill(0);
43
- return {
44
- ok: false,
45
- code: "invalid_body",
46
- message: "Email OTP factor release key is invalid"
47
- };
40
+ return failure("invalid_body", "Email OTP factor release key is invalid");
48
41
  }
49
42
  try {
50
43
  const workerPublicKey = await crypto.subtle.importKey("raw", workerPublicKey65, {
@@ -76,11 +69,7 @@ async function sealEmailOtpFactorSecretForWorker(input) {
76
69
  ciphertextB64u: base64UrlEncode(ciphertext)
77
70
  };
78
71
  } catch {
79
- return {
80
- ok: false,
81
- code: "factor_release_failed",
82
- message: "Email OTP factor release encryption failed"
83
- };
72
+ return failure("factor_release_failed", "Email OTP factor release encryption failed");
84
73
  } finally {
85
74
  factorSecret32.fill(0);
86
75
  }
@@ -92,11 +81,7 @@ async function handleEmailOtpDevCleanupGoogleRegistrationRoute(input) {
92
81
  const code = verified.code || "not_verified";
93
82
  return {
94
83
  status: code === "internal" ? 500 : code === "not_configured" || code === "unsupported" ? 501 : code === "invalid_body" ? 400 : 401,
95
- body: {
96
- ok: false,
97
- code,
98
- message: verified.message || "Google login failed"
99
- }
84
+ body: failure(code, verified.message || "Google login failed")
100
85
  };
101
86
  }
102
87
  const runtimePolicyScope = isPlainObject(body.runtimePolicyScope) ? body.runtimePolicyScope : null;
@@ -113,30 +98,18 @@ async function handleEmailOtpDevCleanupGoogleRegistrationRoute(input) {
113
98
  async function handleEmailOtpRegistrationSealRoute(input) {
114
99
  if (!isPlainObject(input.body)) return {
115
100
  status: 400,
116
- body: {
117
- ok: false,
118
- code: "invalid_body",
119
- message: "Invalid body"
120
- }
101
+ body: failure("invalid_body", "Invalid body")
121
102
  };
122
103
  const allowedFields = new Set(["walletId", "wrappedCiphertext"]);
123
104
  for (const field of Object.keys(input.body)) if (!allowedFields.has(field)) return {
124
105
  status: 400,
125
- body: {
126
- ok: false,
127
- code: "invalid_body",
128
- message: `Unsupported field: ${field}`
129
- }
106
+ body: failure("invalid_body", `Unsupported field: ${field}`)
130
107
  };
131
108
  const walletId = normalizeOptionalTrimmedString(input.body.walletId);
132
109
  const wrappedCiphertext = normalizeOptionalTrimmedString(input.body.wrappedCiphertext);
133
110
  if (!walletId || !wrappedCiphertext) return {
134
111
  status: 400,
135
- body: {
136
- ok: false,
137
- code: "invalid_body",
138
- message: "Missing walletId or wrappedCiphertext"
139
- }
112
+ body: failure("invalid_body", "Missing walletId or wrappedCiphertext")
140
113
  };
141
114
  const result = await input.service.applyEmailOtpServerSeal({ wrappedCiphertext });
142
115
  return {
@@ -150,11 +123,7 @@ async function handleEmailOtpRegistrationSealRoute(input) {
150
123
  async function handleEmailOtpDevOutboxRoute(input) {
151
124
  if (!isPlainObject(input.body)) return {
152
125
  status: 400,
153
- body: {
154
- ok: false,
155
- code: "invalid_body",
156
- message: "Invalid body"
157
- }
126
+ body: failure("invalid_body", "Invalid body")
158
127
  };
159
128
  const allowedFields = new Set([
160
129
  "idToken",
@@ -164,11 +133,7 @@ async function handleEmailOtpDevOutboxRoute(input) {
164
133
  ]);
165
134
  for (const field of Object.keys(input.body)) if (!allowedFields.has(field)) return {
166
135
  status: 400,
167
- body: {
168
- ok: false,
169
- code: "invalid_body",
170
- message: `Unsupported field: ${field}`
171
- }
136
+ body: failure("invalid_body", `Unsupported field: ${field}`)
172
137
  };
173
138
  const idToken = normalizeOptionalTrimmedString(input.body.idToken);
174
139
  const walletId = normalizeOptionalTrimmedString(input.body.walletId);
@@ -176,30 +141,18 @@ async function handleEmailOtpDevOutboxRoute(input) {
176
141
  const challengeSubjectId = normalizeOptionalTrimmedString(input.body.challengeSubjectId);
177
142
  if (!idToken || !walletId) return {
178
143
  status: 400,
179
- body: {
180
- ok: false,
181
- code: "invalid_body",
182
- message: "Missing idToken or walletId"
183
- }
144
+ body: failure("invalid_body", "Missing idToken or walletId")
184
145
  };
185
146
  if (challengeSubjectId && !challengeId) return {
186
147
  status: 400,
187
- body: {
188
- ok: false,
189
- code: "invalid_body",
190
- message: "challengeSubjectId requires the exact challengeId it belongs to"
191
- }
148
+ body: failure("invalid_body", "challengeSubjectId requires the exact challengeId it belongs to")
192
149
  };
193
150
  const verified = await input.service.verifyGoogleLogin({ idToken });
194
151
  if (!verified.ok || !verified.verified || !verified.userId) {
195
152
  const code = verified.code || "not_verified";
196
153
  return {
197
154
  status: code === "internal" ? 500 : code === "not_configured" ? 501 : 401,
198
- body: {
199
- ok: false,
200
- code,
201
- message: verified.message || "Google login failed"
202
- }
155
+ body: failure(code, verified.message || "Google login failed")
203
156
  };
204
157
  }
205
158
  const result = await input.service.readEmailOtpOutboxEntry({