@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.
- package/THIRD_PARTY_NOTICES.md +1 -105
- package/artifact-manifest.json +21 -21
- package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/deriver-a/index_bg.wasm +0 -0
- package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/deriver-b/index_bg.wasm +0 -0
- package/cloudflare-router-ab/build/local-tools/darwin-arm64/router_ab_local_init +0 -0
- package/cloudflare-router-ab/build/local-tools/darwin-x64/router_ab_local_init +0 -0
- package/cloudflare-router-ab/build/local-tools/linux-x64/router_ab_local_init +0 -0
- package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/router/index_bg.wasm +0 -0
- package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/signing-worker/index_bg.wasm +0 -0
- package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/tenant-root-control-plane/index_bg.wasm +0 -0
- package/dist/esm/authorization/service.js +8 -0
- package/dist/esm/authorization/vaultProxyUse.js +2 -6
- package/dist/esm/cloud-host.js +4 -4
- package/dist/esm/core/IdentityStore.js +23 -110
- package/dist/esm/core/SessionService.js +7 -30
- package/dist/esm/core/ThresholdService/routerAbNormalSigningPolicy.js +3 -10
- package/dist/esm/core/ThresholdService/stores/WalletSessionStore.js +21 -97
- package/dist/esm/core/ThresholdService/stores/exportReplayGuard.js +7 -0
- package/dist/esm/core/WalletStore.js +4 -6
- package/dist/esm/core/authService/bytes.js +1 -4
- package/dist/esm/core/authService/emailOtpChallengeOperations.js +2 -5
- package/dist/esm/core/authService/emailOtpChallengeProof.js +9 -40
- package/dist/esm/core/authService/emailOtpChallengeVerification.js +19 -90
- package/dist/esm/core/authService/emailOtpChallenges.js +10 -45
- package/dist/esm/core/authService/emailOtpDelivery.js +10 -45
- package/dist/esm/core/authService/emailOtpEnrollment.js +9 -40
- package/dist/esm/core/authService/emailOtpGrant.js +9 -40
- package/dist/esm/core/authService/emailOtpRegistrationEnrollment.js +9 -40
- package/dist/esm/core/authService/emailOtpSeal.js +5 -20
- package/dist/esm/core/authService/emailOtpUnlock.js +20 -110
- package/dist/esm/core/authService/googleEmailOtpRegistration.js +28 -115
- package/dist/esm/core/authService/identity.js +5 -20
- package/dist/esm/core/authService/nearPublicKeyMetadata.js +6 -25
- package/dist/esm/core/authService/oidcVerification.js +22 -34
- package/dist/esm/core/authService/rateLimits.js +2 -5
- package/dist/esm/core/authService/thresholdEcdsaKeyInventory.js +2 -1
- package/dist/esm/core/authService/webauthn.js +37 -191
- package/dist/esm/core/authService/webauthnVerificationOutcomes.js +5 -24
- package/dist/esm/core/d1EcdsaSignerRead.js +76 -0
- package/dist/esm/core/d1IdentityStore.js +16 -75
- package/dist/esm/core/d1TenantStore.js +1 -1
- package/dist/esm/core/d1WalletStore.js +15 -25
- package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -5
- package/dist/esm/core/deviceLinking/linkedDeviceSessionApproval.js +1 -3
- package/dist/esm/core/deviceLinking/linkedDeviceSessionRecord.js +2 -8
- package/dist/esm/core/deviceLinking/requestProof.js +13 -4
- package/dist/esm/core/ecdsaMaterialReadSnapshot.js +85 -0
- package/dist/esm/core/nearRelayerAccountProvisioning.js +2 -5
- package/dist/esm/core/signingLanes/WalletExecutionLaneProjection.js +3 -6
- package/dist/esm/core/signingMaterial/ordinaryInactiveSignerMaterialReservation.js +2 -5
- package/dist/esm/core/storeBackends.js +1 -1
- package/dist/esm/core/thresholdEcdsaChainTarget.js +1 -3
- package/dist/esm/hosted-wallet-gateway.js +2 -2
- package/dist/esm/localHostedWalletGatewayHandler.js +13 -0
- package/dist/esm/localIntendedMaterialAdmissionFault.js +176 -0
- package/dist/esm/localIntendedPresignCancellation.js +44 -0
- package/dist/esm/router/auth/commonRouterUtils.js +24 -10
- package/dist/esm/router/auth/walletSessionFailure.js +2 -5
- package/dist/esm/router/auth/webAuthnCredentialCodecs.js +4 -15
- package/dist/esm/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.js +1 -0
- package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthBoundary.js +2 -6
- package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +5 -27
- package/dist/esm/router/cloudflare/d1/auth/walletSessionCredentialReaders.js +76 -0
- package/dist/esm/router/cloudflare/d1/authorization/authorizedOperationStatements.js +28 -21
- package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +209 -44
- package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +8 -12
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +50 -8
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/index.js +3 -3
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +12 -55
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +17 -80
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpDeliveryRuntime.js +6 -25
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +12 -47
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +24 -85
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRegistrationEnrollmentFinalizer.js +7 -30
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpServerSealRuntime.js +5 -20
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +23 -110
- package/dist/esm/router/cloudflare/d1/identity/d1IdentityService.js +9 -40
- package/dist/esm/router/cloudflare/d1/near/d1NearPublicKeyStore.js +3 -10
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +18 -91
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +6 -30
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +4 -15
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +2 -7
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpRecords.js +9 -13
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpService.js +11 -50
- package/dist/esm/router/cloudflare/d1/registration/d1EvmFamilyEcdsaRegistrationBranch.js +5 -20
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.js +4 -7
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +2 -1
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +7 -30
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +32 -22
- package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +1 -4
- package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +119 -25
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +31 -168
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +6 -9
- package/dist/esm/router/cloudflare/durableObjects/thresholdStore.js +59 -66
- package/dist/esm/router/cloudflare/runtime/routerAbPrewarm.js +2 -2
- package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +5 -20
- package/dist/esm/router/cloudflare/runtime/tenantRootCreationGrant.js +2 -9
- package/dist/esm/router/cloudflare/runtime/walletControlOps.js +2 -1
- package/dist/esm/router/cloudflare/signingLanes/cloudflareLaneCurveExecution.js +2 -1
- package/dist/esm/router/cloudflare/signingLanes/cloudflareLaneProtocolCommitter.js +2 -2
- package/dist/esm/router/cloudflare.js +2146 -1802
- package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPersistence.js +5 -8
- package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryWalletSessionAuthorization.js +3 -6
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.js +6 -25
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationSideEffectBoundary.js +39 -55
- package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +15 -62
- package/dist/esm/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.js +83 -74
- package/dist/esm/router/domains/signingOperations/routerAbNormalSigningAdmission.js +1 -0
- package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +1 -0
- package/dist/esm/router/domains/signingOperations/walletExecutionAdmission.js +1 -4
- package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +7 -13
- package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +41 -200
- package/dist/esm/router/express.js +317 -699
- package/dist/esm/router/framework/http.js +5 -1
- package/dist/esm/router/framework/runtimeSnapshotConsumer.js +8 -35
- package/dist/esm/router/transport/fetch/createFetchRouter.js +3 -6
- package/dist/esm/router/transport/fetch/routes/auth.js +9 -41
- package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +5 -22
- package/dist/esm/router/transport/fetch/routes/nearPublicKeys.js +4 -16
- package/dist/esm/router/transport/fetch/routes/sessions.js +1 -0
- package/dist/esm/router/transport/fetch/routes/syncAccount.js +8 -36
- package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +27 -79
- package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +4 -1
- package/dist/esm/router/transport/fetch/routes/webauthnAuthenticators.js +4 -16
- package/dist/esm/shared-ts/src/authorization/walletSignerActivationEquality.js +12 -0
- package/dist/esm/shared-ts/src/device-linking/committedSignerPackages.js +2 -5
- package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -5
- package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +12 -16
- package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +5 -8
- package/dist/esm/shared-ts/src/passkey-custody/primitives.js +5 -1
- package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +4 -8
- package/dist/esm/shared-ts/src/tenant-root/tenantRootIdentifier.js +12 -0
- package/dist/esm/shared-ts/src/tenant-root/tenantRootIdentity.js +2 -9
- package/dist/esm/shared-ts/src/tenant-root/tenantRootOperationRecord.js +1 -4
- package/dist/esm/shared-ts/src/utils/ecdsaKeyFactsInventory.js +2 -4
- package/dist/esm/shared-ts/src/utils/ecdsaServerTiming.js +0 -1
- package/dist/esm/shared-ts/src/utils/emailOtpDomain.js +3 -1
- package/dist/esm/shared-ts/src/utils/exactKeys.js +17 -0
- package/dist/esm/shared-ts/src/utils/failure.js +20 -0
- package/dist/esm/shared-ts/src/utils/registrationIntent.js +3 -12
- package/dist/esm/shared-ts/src/utils/registrationSignerPlan.js +2 -5
- package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -1
- package/dist/esm/shared-ts/src/utils/routerAbEd25519Yao.js +1 -1
- package/dist/esm/shared-ts/src/utils/thresholdEcdsaChainTarget.js +9 -0
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -4
- package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +10 -32
- package/dist/esm/threshold/session/signingSessionSeal/idempotencyBackends.js +3 -3
- package/dist/esm/threshold/session/signingSessionSeal/idempotencyRecords.js +3 -9
- package/dist/esm/threshold/session/signingSessionSeal/service.js +8 -35
- package/dist/esm/threshold/session/signingSessionSeal/transport/express.js +18 -94
- package/dist/esm/threshold/session/signingSessionSeal/transport/fetch.js +6 -30
- package/dist/esm/threshold/session/signingSessionSeal/transport/shared.js +5 -20
- package/dist/esm/wasm/evm_crypto/pkg/evm_crypto_bg.wasm +0 -0
- package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
- package/dist/types/shared-ts/src/authorization/delegatedAuthority.d.ts +2 -1
- package/dist/types/shared-ts/src/authorization/walletSessionIssuance.d.ts +9 -2
- package/dist/types/shared-ts/src/authorization/walletSignerActivationEquality.d.ts +4 -0
- package/dist/types/shared-ts/src/device-linking/committedSignerPackages.d.ts +3 -4
- package/dist/types/shared-ts/src/device-linking/contracts.d.ts +5 -63
- package/dist/types/shared-ts/src/device-linking/sourceContribution.d.ts +2 -0
- package/dist/types/shared-ts/src/passkey-custody/custodyEnvelope.d.ts +5 -12
- package/dist/types/shared-ts/src/passkey-custody/primitives.d.ts +9 -0
- package/dist/types/shared-ts/src/signing-lanes/execution.d.ts +11 -1
- package/dist/types/shared-ts/src/signing-lanes/ids.d.ts +1 -10
- package/dist/types/shared-ts/src/signing-lanes/rotation.d.ts +3 -5
- package/dist/types/shared-ts/src/tenant-root/tenantRootIdentifier.d.ts +3 -0
- package/dist/types/shared-ts/src/tenant-root/tenantRootOperationRecord.d.ts +2 -1
- package/dist/types/shared-ts/src/threshold/ecdsaDerivationRoleLocalBootstrap.d.ts +6 -0
- package/dist/types/shared-ts/src/threshold/signingRootScope.d.ts +1 -0
- package/dist/types/shared-ts/src/utils/ecdsaKeyFactsInventory.d.ts +2 -11
- package/dist/types/shared-ts/src/utils/eip1559TxWasmJson.d.ts +16 -0
- package/dist/types/shared-ts/src/utils/emailOtpDomain.d.ts +2 -0
- package/dist/types/shared-ts/src/utils/exactKeys.d.ts +11 -0
- package/dist/types/shared-ts/src/utils/failure.d.ts +12 -0
- package/dist/types/shared-ts/src/utils/jsonRpc.d.ts +3 -4
- package/dist/types/shared-ts/src/utils/nearRpcResults.d.ts +1 -0
- package/dist/types/shared-ts/src/utils/registrationAuthMethodInput.d.ts +3 -8
- package/dist/types/shared-ts/src/utils/registrationSignerPlan.d.ts +7 -19
- package/dist/types/shared-ts/src/utils/routerAbEcdsaDerivation.d.ts +3 -1
- package/dist/types/shared-ts/src/utils/routerAbEd25519Yao.d.ts +1 -0
- package/dist/types/shared-ts/src/utils/routerAbEd25519YaoDigests.d.ts +3 -4
- package/dist/types/shared-ts/src/utils/routerAbNormalSigningIdentity.d.ts +30 -8
- package/dist/types/shared-ts/src/utils/routerApiKeyAuth.d.ts +2 -0
- package/dist/types/shared-ts/src/utils/signingSessionSeal.d.ts +10 -11
- package/dist/types/shared-ts/src/utils/thresholdEcdsaChainTarget.d.ts +25 -0
- package/dist/types/shared-ts/src/utils/variant.d.ts +18 -0
- package/dist/types/shared-ts/src/utils/walletAuthMethodRecord.d.ts +3 -6
- package/dist/types/shared-ts/src/utils/webauthnDeviceInfo.d.ts +4 -2
- package/dist/types/shared-ts/src/wallet-recovery/recoveryEnvelopes.d.ts +3 -16
- package/dist/types/shared-ts/src/wallet-recovery/walletRecoveryPreparation.d.ts +15 -0
- package/dist/types/shared-ts/src/wallet-recovery/walletRecoveryTarget.d.ts +3 -4
- package/dist/types/wallet-server/src/authorization/domain.d.ts +13 -2
- package/dist/types/wallet-server/src/authorization/ecdsaWalletSessionAdmission.d.ts +27 -3
- package/dist/types/wallet-server/src/authorization/service.d.ts +19 -0
- package/dist/types/wallet-server/src/core/ThresholdService/stores/SessionStore.d.ts +2 -2
- package/dist/types/wallet-server/src/core/ThresholdService/stores/WalletSessionStore.d.ts +1 -1
- package/dist/types/wallet-server/src/core/ThresholdService/stores/exportReplayGuard.d.ts +3 -0
- package/dist/types/wallet-server/src/core/ThresholdService/validation.d.ts +8 -101
- package/dist/types/wallet-server/src/core/WebAuthnAuthenticatorStore.d.ts +8 -0
- package/dist/types/wallet-server/src/core/authService/bytes.d.ts +0 -1
- package/dist/types/wallet-server/src/core/authService/emailOtpChallenges.d.ts +2 -10
- package/dist/types/wallet-server/src/core/authService/emailOtpSeal.d.ts +1 -1
- package/dist/types/wallet-server/src/core/authService/emailOtpUnlock.d.ts +3 -10
- package/dist/types/wallet-server/src/core/d1EcdsaSignerRead.d.ts +39 -0
- package/dist/types/wallet-server/src/core/d1WalletStore.d.ts +10 -0
- package/dist/types/wallet-server/src/core/deviceLinking/linkedDeviceSessionRecord.d.ts +3 -4
- package/dist/types/wallet-server/src/core/ecdsaMaterialReadSnapshot.d.ts +19 -0
- package/dist/types/wallet-server/src/core/routerAbSigning/RouterAbNormalSigningRuntime.d.ts +3 -5
- package/dist/types/wallet-server/src/core/rpcClients/near/NearClient.d.ts +1 -2
- package/dist/types/wallet-server/src/core/signingLanes/WalletExecutionLaneProjection.d.ts +2 -11
- package/dist/types/wallet-server/src/core/signingLanes/signingWorkerLaneMaterialIdentity.d.ts +2 -19
- package/dist/types/wallet-server/src/core/thresholdEcdsaChainTarget.d.ts +3 -11
- package/dist/types/wallet-server/src/core/types.d.ts +2 -6
- package/dist/types/wallet-server/src/localIntendedMaterialAdmissionFault.d.ts +38 -0
- package/dist/types/wallet-server/src/localIntendedPresignCancellation.d.ts +4 -0
- package/dist/types/wallet-server/src/router/auth/authRequestValidation.d.ts +4 -9
- package/dist/types/wallet-server/src/router/auth/commonRouterUtils.d.ts +15 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RouterApiAuthBoundary.d.ts +0 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RouterApiAuthService.d.ts +1 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/auth/walletSessionCredentialReaders.d.ts +9 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/authorization/authorizedOperationStatements.d.ts +4 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/authorization/d1AuthorizationStore.d.ts +10 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.d.ts +19 -2
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.d.ts +2 -6
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.d.ts +5 -8
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpEnrollmentStore.d.ts +2 -8
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpRateLimitStore.d.ts +2 -9
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.d.ts +5 -5
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpServerSealRuntime.d.ts +4 -14
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.d.ts +2 -6
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationService.d.ts +8 -6
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.d.ts +14 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/webauthn/d1WebAuthnRecords.d.ts +10 -39
- package/dist/types/wallet-server/src/router/cloudflare/runtime/walletConsoleOps.d.ts +8 -34
- package/dist/types/wallet-server/src/router/domains/ecdsa/thresholdEcdsaRequestValidation.d.ts +3 -15
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/session/routerAbEd25519YaoWalletSession.d.ts +9 -50
- package/dist/types/wallet-server/src/router/domains/passkeyCustody/walletRecoveryKeyManifest.d.ts +1 -13
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.d.ts +8 -9
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbNormalSigningAdmission.d.ts +13 -0
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbOperationStepUp.d.ts +3 -4
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbPrivateSigningWorker.d.ts +7 -16
- package/dist/types/wallet-server/src/router/domains/syncAccount/syncAccountRequestValidation.d.ts +2 -7
- package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +3 -1
- package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +25 -4
- package/dist/types/wallet-server/src/router/framework/http.d.ts +1 -0
- package/dist/types/wallet-server/src/router/framework/ror/normalize.d.ts +1 -9
- package/dist/types/wallet-server/src/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.d.ts +3 -6
- package/dist/types/wallet-server/src/router/transport/fetch/routes/syncAccountBootstrap.d.ts +3 -5
- package/dist/types/wallet-server/src/router/transport/fetch/routes/thresholdEcdsa.d.ts +0 -1
- package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/idempotencyRecords.d.ts +1 -2
- package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/signingSessionSeal.types.d.ts +6 -8
- package/package.json +1 -1
- 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 (!
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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] &&
|
|
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] &&
|
|
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
|
-
|
|
222
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|