@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,5 +1,6 @@
|
|
|
1
1
|
import { normalizeOptionalTrimmedString } from "../shared-ts/src/utils/normalize.js";
|
|
2
2
|
import { isObject } from "../shared-ts/src/utils/validation.js";
|
|
3
|
+
import { failure } from "../shared-ts/src/utils/failure.js";
|
|
3
4
|
import { resolveStorePrefix } from "./d1TenantStore.js";
|
|
4
5
|
import { createKeyValueStore } from "./storeBackends.js";
|
|
5
6
|
import { D1IdentityStore, IDENTITY_D1_STORE, IDENTITY_STORE_D1_SCHEMA_SQL, ensureIdentityStoreD1Schema } from "./d1IdentityStore.js";
|
|
@@ -77,32 +78,16 @@ var InMemoryIdentityStore = class {
|
|
|
77
78
|
async linkSubjectToUserId(input) {
|
|
78
79
|
const userId = normalizeOptionalTrimmedString(input.userId);
|
|
79
80
|
const subject = normalizeOptionalTrimmedString(input.subject);
|
|
80
|
-
if (!userId) return
|
|
81
|
-
|
|
82
|
-
code: "invalid_args",
|
|
83
|
-
message: "Missing userId"
|
|
84
|
-
};
|
|
85
|
-
if (!subject) return {
|
|
86
|
-
ok: false,
|
|
87
|
-
code: "invalid_args",
|
|
88
|
-
message: "Missing subject"
|
|
89
|
-
};
|
|
81
|
+
if (!userId) return failure("invalid_args", "Missing userId");
|
|
82
|
+
if (!subject) return failure("invalid_args", "Missing subject");
|
|
90
83
|
const now = Date.now();
|
|
91
84
|
const existing = this.subjectToUser.get(this.subjectKey(subject)) || null;
|
|
92
85
|
if (existing && existing.userId !== userId) {
|
|
93
|
-
if (!input.allowMoveIfSoleIdentity) return
|
|
94
|
-
ok: false,
|
|
95
|
-
code: "already_linked",
|
|
96
|
-
message: "Subject is already linked to a different user"
|
|
97
|
-
};
|
|
86
|
+
if (!input.allowMoveIfSoleIdentity) return failure("already_linked", "Subject is already linked to a different user");
|
|
98
87
|
const sourceUser = existing.userId;
|
|
99
88
|
const source = this.userToSubjects.get(this.userKey(sourceUser)) || null;
|
|
100
89
|
const sourceSubjects = source?.subjects || [];
|
|
101
|
-
if (sourceSubjects.length !== 1 || sourceSubjects[0] !== subject) return
|
|
102
|
-
ok: false,
|
|
103
|
-
code: "already_linked",
|
|
104
|
-
message: "Subject is linked to a different user with other identities; merge is not allowed"
|
|
105
|
-
};
|
|
90
|
+
if (sourceSubjects.length !== 1 || sourceSubjects[0] !== subject) return failure("already_linked", "Subject is linked to a different user with other identities; merge is not allowed");
|
|
106
91
|
this.userToSubjects.set(this.userKey(sourceUser), {
|
|
107
92
|
version: "identity_user_v1",
|
|
108
93
|
userId: sourceUser,
|
|
@@ -158,29 +143,13 @@ var InMemoryIdentityStore = class {
|
|
|
158
143
|
async unlinkSubjectFromUserId(input) {
|
|
159
144
|
const userId = normalizeOptionalTrimmedString(input.userId);
|
|
160
145
|
const subject = normalizeOptionalTrimmedString(input.subject);
|
|
161
|
-
if (!userId) return
|
|
162
|
-
|
|
163
|
-
code: "invalid_args",
|
|
164
|
-
message: "Missing userId"
|
|
165
|
-
};
|
|
166
|
-
if (!subject) return {
|
|
167
|
-
ok: false,
|
|
168
|
-
code: "invalid_args",
|
|
169
|
-
message: "Missing subject"
|
|
170
|
-
};
|
|
146
|
+
if (!userId) return failure("invalid_args", "Missing userId");
|
|
147
|
+
if (!subject) return failure("invalid_args", "Missing subject");
|
|
171
148
|
const existing = this.subjectToUser.get(this.subjectKey(subject)) || null;
|
|
172
|
-
if (!existing || existing.userId !== userId) return
|
|
173
|
-
ok: false,
|
|
174
|
-
code: "not_found",
|
|
175
|
-
message: "Subject is not linked to this user"
|
|
176
|
-
};
|
|
149
|
+
if (!existing || existing.userId !== userId) return failure("not_found", "Subject is not linked to this user");
|
|
177
150
|
const userRec = this.userToSubjects.get(this.userKey(userId)) || null;
|
|
178
151
|
const subjects = userRec?.subjects || [];
|
|
179
|
-
if (subjects.length <= 1) return
|
|
180
|
-
ok: false,
|
|
181
|
-
code: "cannot_unlink_last_identity",
|
|
182
|
-
message: "Refusing to remove the last remaining identity"
|
|
183
|
-
};
|
|
152
|
+
if (subjects.length <= 1) return failure("cannot_unlink_last_identity", "Refusing to remove the last remaining identity");
|
|
184
153
|
this.subjectToUser.delete(this.subjectKey(subject));
|
|
185
154
|
const now = Date.now();
|
|
186
155
|
const nextSubjects = subjects.filter((s) => s !== subject);
|
|
@@ -197,22 +166,10 @@ var InMemoryIdentityStore = class {
|
|
|
197
166
|
async deleteSubjectLinkForDevCleanup(input) {
|
|
198
167
|
const userId = normalizeOptionalTrimmedString(input.userId);
|
|
199
168
|
const subject = normalizeOptionalTrimmedString(input.subject);
|
|
200
|
-
if (!userId) return
|
|
201
|
-
|
|
202
|
-
code: "invalid_args",
|
|
203
|
-
message: "Missing userId"
|
|
204
|
-
};
|
|
205
|
-
if (!subject) return {
|
|
206
|
-
ok: false,
|
|
207
|
-
code: "invalid_args",
|
|
208
|
-
message: "Missing subject"
|
|
209
|
-
};
|
|
169
|
+
if (!userId) return failure("invalid_args", "Missing userId");
|
|
170
|
+
if (!subject) return failure("invalid_args", "Missing subject");
|
|
210
171
|
const existing = this.subjectToUser.get(this.subjectKey(subject)) || null;
|
|
211
|
-
if (!existing || existing.userId !== userId) return
|
|
212
|
-
ok: false,
|
|
213
|
-
code: "not_found",
|
|
214
|
-
message: "Subject is not linked to this user"
|
|
215
|
-
};
|
|
172
|
+
if (!existing || existing.userId !== userId) return failure("not_found", "Subject is not linked to this user");
|
|
216
173
|
this.subjectToUser.delete(this.subjectKey(subject));
|
|
217
174
|
const now = Date.now();
|
|
218
175
|
const userRec = this.userToSubjects.get(this.userKey(userId)) || null;
|
|
@@ -255,32 +212,16 @@ var KeyValueIdentityStore = class {
|
|
|
255
212
|
async linkSubjectToUserId(input) {
|
|
256
213
|
const userId = normalizeOptionalTrimmedString(input.userId);
|
|
257
214
|
const subject = normalizeOptionalTrimmedString(input.subject);
|
|
258
|
-
if (!userId) return
|
|
259
|
-
|
|
260
|
-
code: "invalid_args",
|
|
261
|
-
message: "Missing userId"
|
|
262
|
-
};
|
|
263
|
-
if (!subject) return {
|
|
264
|
-
ok: false,
|
|
265
|
-
code: "invalid_args",
|
|
266
|
-
message: "Missing subject"
|
|
267
|
-
};
|
|
215
|
+
if (!userId) return failure("invalid_args", "Missing userId");
|
|
216
|
+
if (!subject) return failure("invalid_args", "Missing subject");
|
|
268
217
|
const now = Date.now();
|
|
269
218
|
const existingSubject = parseIdentitySubjectRecord(await this.records.get(this.subjectKey(subject)));
|
|
270
219
|
if (existingSubject && existingSubject.userId !== userId) {
|
|
271
|
-
if (!input.allowMoveIfSoleIdentity) return
|
|
272
|
-
ok: false,
|
|
273
|
-
code: "already_linked",
|
|
274
|
-
message: "Subject is already linked to a different user"
|
|
275
|
-
};
|
|
220
|
+
if (!input.allowMoveIfSoleIdentity) return failure("already_linked", "Subject is already linked to a different user");
|
|
276
221
|
const sourceUser = existingSubject.userId;
|
|
277
222
|
const sourceUserRec = parseIdentityUserRecord(await this.records.get(this.userKey(sourceUser)));
|
|
278
223
|
const sourceSubjects = sourceUserRec?.subjects || [];
|
|
279
|
-
if (sourceSubjects.length !== 1 || sourceSubjects[0] !== subject) return
|
|
280
|
-
ok: false,
|
|
281
|
-
code: "already_linked",
|
|
282
|
-
message: "Subject is linked to a different user with other identities; merge is not allowed"
|
|
283
|
-
};
|
|
224
|
+
if (sourceSubjects.length !== 1 || sourceSubjects[0] !== subject) return failure("already_linked", "Subject is linked to a different user with other identities; merge is not allowed");
|
|
284
225
|
const destUserRec = parseIdentityUserRecord(await this.records.get(this.userKey(userId)));
|
|
285
226
|
const destSubjects = Array.from(new Set([...destUserRec?.subjects || [], subject]));
|
|
286
227
|
destSubjects.sort();
|
|
@@ -332,29 +273,13 @@ var KeyValueIdentityStore = class {
|
|
|
332
273
|
async unlinkSubjectFromUserId(input) {
|
|
333
274
|
const userId = normalizeOptionalTrimmedString(input.userId);
|
|
334
275
|
const subject = normalizeOptionalTrimmedString(input.subject);
|
|
335
|
-
if (!userId) return
|
|
336
|
-
|
|
337
|
-
code: "invalid_args",
|
|
338
|
-
message: "Missing userId"
|
|
339
|
-
};
|
|
340
|
-
if (!subject) return {
|
|
341
|
-
ok: false,
|
|
342
|
-
code: "invalid_args",
|
|
343
|
-
message: "Missing subject"
|
|
344
|
-
};
|
|
276
|
+
if (!userId) return failure("invalid_args", "Missing userId");
|
|
277
|
+
if (!subject) return failure("invalid_args", "Missing subject");
|
|
345
278
|
const subjectRec = parseIdentitySubjectRecord(await this.records.get(this.subjectKey(subject)));
|
|
346
|
-
if (!subjectRec || subjectRec.userId !== userId) return
|
|
347
|
-
ok: false,
|
|
348
|
-
code: "not_found",
|
|
349
|
-
message: "Subject is not linked to this user"
|
|
350
|
-
};
|
|
279
|
+
if (!subjectRec || subjectRec.userId !== userId) return failure("not_found", "Subject is not linked to this user");
|
|
351
280
|
const userRec = parseIdentityUserRecord(await this.records.get(this.userKey(userId)));
|
|
352
281
|
const subjects = userRec?.subjects || [];
|
|
353
|
-
if (subjects.length <= 1) return
|
|
354
|
-
ok: false,
|
|
355
|
-
code: "cannot_unlink_last_identity",
|
|
356
|
-
message: "Refusing to remove the last remaining identity"
|
|
357
|
-
};
|
|
282
|
+
if (subjects.length <= 1) return failure("cannot_unlink_last_identity", "Refusing to remove the last remaining identity");
|
|
358
283
|
const nextSubjects = subjects.filter((s) => s !== subject);
|
|
359
284
|
nextSubjects.sort();
|
|
360
285
|
await this.records.set(this.userKey(userId), {
|
|
@@ -370,22 +295,10 @@ var KeyValueIdentityStore = class {
|
|
|
370
295
|
async deleteSubjectLinkForDevCleanup(input) {
|
|
371
296
|
const userId = normalizeOptionalTrimmedString(input.userId);
|
|
372
297
|
const subject = normalizeOptionalTrimmedString(input.subject);
|
|
373
|
-
if (!userId) return
|
|
374
|
-
|
|
375
|
-
code: "invalid_args",
|
|
376
|
-
message: "Missing userId"
|
|
377
|
-
};
|
|
378
|
-
if (!subject) return {
|
|
379
|
-
ok: false,
|
|
380
|
-
code: "invalid_args",
|
|
381
|
-
message: "Missing subject"
|
|
382
|
-
};
|
|
298
|
+
if (!userId) return failure("invalid_args", "Missing userId");
|
|
299
|
+
if (!subject) return failure("invalid_args", "Missing subject");
|
|
383
300
|
const subjectRec = parseIdentitySubjectRecord(await this.records.get(this.subjectKey(subject)));
|
|
384
|
-
if (!subjectRec || subjectRec.userId !== userId) return
|
|
385
|
-
ok: false,
|
|
386
|
-
code: "not_found",
|
|
387
|
-
message: "Subject is not linked to this user"
|
|
388
|
-
};
|
|
301
|
+
if (!subjectRec || subjectRec.userId !== userId) return failure("not_found", "Subject is not linked to this user");
|
|
389
302
|
const userRec = parseIdentityUserRecord(await this.records.get(this.userKey(userId)));
|
|
390
303
|
const nextSubjects = (userRec?.subjects || []).filter((s) => s !== subject);
|
|
391
304
|
if (nextSubjects.length > 0) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { failure } from "../shared-ts/src/utils/failure.js";
|
|
1
2
|
//#region src/core/SessionService.ts
|
|
2
3
|
function normalizeParsedCorsOrigin(url) {
|
|
3
4
|
const host = url.hostname.toLowerCase();
|
|
@@ -153,36 +154,16 @@ var SessionService = class {
|
|
|
153
154
|
async refresh(headers) {
|
|
154
155
|
try {
|
|
155
156
|
const token = this.extractTokenFromHeaders(headers);
|
|
156
|
-
if (!token) return
|
|
157
|
-
ok: false,
|
|
158
|
-
code: "unauthorized",
|
|
159
|
-
message: "No session token"
|
|
160
|
-
};
|
|
157
|
+
if (!token) return failure("unauthorized", "No session token");
|
|
161
158
|
const v = await this.verifyJwt(token);
|
|
162
159
|
if (!v.valid) {
|
|
163
|
-
if (v.reason === "expired") return
|
|
164
|
-
|
|
165
|
-
code: "wallet_session_expired",
|
|
166
|
-
message: "Wallet Session expired"
|
|
167
|
-
};
|
|
168
|
-
return {
|
|
169
|
-
ok: false,
|
|
170
|
-
code: "unauthorized",
|
|
171
|
-
message: "Invalid token"
|
|
172
|
-
};
|
|
160
|
+
if (v.reason === "expired") return failure("wallet_session_expired", "Wallet Session expired");
|
|
161
|
+
return failure("unauthorized", "Invalid token");
|
|
173
162
|
}
|
|
174
163
|
const payload = v.payload || {};
|
|
175
|
-
if (!this.isWithinRefreshWindow(payload)) return
|
|
176
|
-
ok: false,
|
|
177
|
-
code: "not_eligible",
|
|
178
|
-
message: "Not within refresh window"
|
|
179
|
-
};
|
|
164
|
+
if (!this.isWithinRefreshWindow(payload)) return failure("not_eligible", "Not within refresh window");
|
|
180
165
|
const sub = String(payload.sub || "");
|
|
181
|
-
if (!sub) return
|
|
182
|
-
ok: false,
|
|
183
|
-
code: "invalid_claims",
|
|
184
|
-
message: "Missing sub claim"
|
|
185
|
-
};
|
|
166
|
+
if (!sub) return failure("invalid_claims", "Missing sub claim");
|
|
186
167
|
const extra = {};
|
|
187
168
|
for (const [k, v] of Object.entries(payload || {})) {
|
|
188
169
|
if (k === "sub" || k === "exp" || k === "iat" || k === "nbf" || k === "jti" || k === "iss" || k === "aud") continue;
|
|
@@ -193,11 +174,7 @@ var SessionService = class {
|
|
|
193
174
|
jwt: await this.signJwt(sub, extra)
|
|
194
175
|
};
|
|
195
176
|
} catch (e) {
|
|
196
|
-
return
|
|
197
|
-
ok: false,
|
|
198
|
-
code: "internal",
|
|
199
|
-
message: e?.message || "Refresh failed"
|
|
200
|
-
};
|
|
177
|
+
return failure("internal", e?.message || "Refresh failed");
|
|
201
178
|
}
|
|
202
179
|
}
|
|
203
180
|
nowSeconds() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeOptionalTrimmedString } from "../../shared-ts/src/utils/normalize.js";
|
|
2
2
|
import "../../shared-ts/src/utils/validation.js";
|
|
3
|
+
import { failure } from "../../shared-ts/src/utils/failure.js";
|
|
3
4
|
//#region src/core/ThresholdService/routerAbNormalSigningPolicy.ts
|
|
4
5
|
function parseRouterAbNormalSigningServerPolicy(config) {
|
|
5
6
|
const signingWorkerId = normalizeOptionalTrimmedString(config.ROUTER_AB_NORMAL_SIGNING_WORKER_ID);
|
|
@@ -10,16 +11,8 @@ function parseRouterAbNormalSigningServerPolicy(config) {
|
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
function validateRouterAbNormalSigningServerPolicy(args) {
|
|
13
|
-
if (!args.requested) return
|
|
14
|
-
|
|
15
|
-
code: "unauthorized",
|
|
16
|
-
message: "sessionPolicy.routerAbNormalSigning is required for Router A/B normal signing"
|
|
17
|
-
};
|
|
18
|
-
if (args.requested.signingWorkerId !== args.policy.signingWorkerId) return {
|
|
19
|
-
ok: false,
|
|
20
|
-
code: "unauthorized",
|
|
21
|
-
message: "sessionPolicy.routerAbNormalSigning.signingWorkerId is not allowed for this threshold server"
|
|
22
|
-
};
|
|
14
|
+
if (!args.requested) return failure("unauthorized", "sessionPolicy.routerAbNormalSigning is required for Router A/B normal signing");
|
|
15
|
+
if (args.requested.signingWorkerId !== args.policy.signingWorkerId) return failure("unauthorized", "sessionPolicy.routerAbNormalSigning.signingWorkerId is not allowed for this threshold server");
|
|
23
16
|
return {
|
|
24
17
|
ok: true,
|
|
25
18
|
value: null
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { normalizeOptionalTrimmedString } from "../../../shared-ts/src/utils/normalize.js";
|
|
2
2
|
import { isPlainObject } from "../../../shared-ts/src/utils/validation.js";
|
|
3
|
+
import { failure } from "../../../shared-ts/src/utils/failure.js";
|
|
3
4
|
import { parseEcdsaWalletSessionRecord, parseEd25519WalletSessionRecord, toThresholdEcdsaPrefixFromBase, toThresholdEcdsaWalletSessionPrefix, toThresholdEd25519PrefixFromBase, toThresholdEd25519WalletSessionPrefix } from "../validation.js";
|
|
4
5
|
import { RedisTcpClient, UpstashRedisRestClient, redisGetJson, redisSetJson } from "../kv.js";
|
|
6
|
+
import { EXPORT_REPLAY_GUARD_CLOCK_SKEW_MS, EXPORT_REPLAY_GUARD_MIN_RETENTION_MS } from "./exportReplayGuard.js";
|
|
5
7
|
import { createCloudflareDurableObjectThresholdEcdsaStores, createCloudflareDurableObjectThresholdEd25519Stores } from "./CloudflareDurableObjectStore.js";
|
|
6
8
|
import { readNonDurableObjectThresholdStoreKind } from "./StoreConfig.js";
|
|
7
9
|
//#region src/core/ThresholdService/stores/WalletSessionStore.ts
|
|
8
|
-
const EXPORT_REPLAY_GUARD_CLOCK_SKEW_MS = 5 * 6e4;
|
|
9
|
-
const EXPORT_REPLAY_GUARD_MIN_RETENTION_MS = 1440 * 6e4;
|
|
10
10
|
/** A wallet session store's keys: record, use counter, consume-once markers, replay guards. */
|
|
11
11
|
var WalletSessionKeys = class {
|
|
12
12
|
constructor(keyPrefix) {
|
|
@@ -35,18 +35,10 @@ var InMemoryWalletSessionStore = class {
|
|
|
35
35
|
liveEntry(id) {
|
|
36
36
|
const key = this.keys.meta(id);
|
|
37
37
|
const entry = this.map.get(key);
|
|
38
|
-
if (!entry) return
|
|
39
|
-
ok: false,
|
|
40
|
-
code: "wallet_session_missing",
|
|
41
|
-
message: "Wallet Session is missing"
|
|
42
|
-
};
|
|
38
|
+
if (!entry) return failure("wallet_session_missing", "Wallet Session is missing");
|
|
43
39
|
if (entry.expiresAtMs <= Date.now()) {
|
|
44
40
|
this.map.delete(key);
|
|
45
|
-
return
|
|
46
|
-
ok: false,
|
|
47
|
-
code: "wallet_session_expired",
|
|
48
|
-
message: "Wallet Session expired"
|
|
49
|
-
};
|
|
41
|
+
return failure("wallet_session_expired", "Wallet Session expired");
|
|
50
42
|
}
|
|
51
43
|
return entry;
|
|
52
44
|
}
|
|
@@ -97,11 +89,7 @@ var InMemoryWalletSessionStore = class {
|
|
|
97
89
|
async consumeUseCount(id) {
|
|
98
90
|
const entry = this.liveEntry(id);
|
|
99
91
|
if ("ok" in entry) return entry;
|
|
100
|
-
if (entry.remainingUses <= 0) return
|
|
101
|
-
ok: false,
|
|
102
|
-
code: "wallet_budget_exhausted",
|
|
103
|
-
message: "Wallet Session exhausted"
|
|
104
|
-
};
|
|
92
|
+
if (entry.remainingUses <= 0) return failure("wallet_budget_exhausted", "Wallet Session exhausted");
|
|
105
93
|
entry.remainingUses -= 1;
|
|
106
94
|
return {
|
|
107
95
|
ok: true,
|
|
@@ -116,11 +104,7 @@ var InMemoryWalletSessionStore = class {
|
|
|
116
104
|
ok: true,
|
|
117
105
|
remainingUses: entry.remainingUses
|
|
118
106
|
};
|
|
119
|
-
if (entry.remainingUses <= 0) return
|
|
120
|
-
ok: false,
|
|
121
|
-
code: "wallet_budget_exhausted",
|
|
122
|
-
message: "Wallet Session exhausted"
|
|
123
|
-
};
|
|
107
|
+
if (entry.remainingUses <= 0) return failure("wallet_budget_exhausted", "Wallet Session exhausted");
|
|
124
108
|
entry.remainingUses -= 1;
|
|
125
109
|
if (consumeKey) entry.consumedIdempotencyKeys.add(consumeKey);
|
|
126
110
|
return {
|
|
@@ -152,11 +136,7 @@ var InMemoryWalletSessionStore = class {
|
|
|
152
136
|
};
|
|
153
137
|
/** A backend failure as an `internal` result: the error's message, else `fallback`. */
|
|
154
138
|
function walletSessionStoreFailure(error, fallback) {
|
|
155
|
-
return
|
|
156
|
-
ok: false,
|
|
157
|
-
code: "internal",
|
|
158
|
-
message: String(error && typeof error === "object" && "message" in error ? error.message : error || fallback)
|
|
159
|
-
};
|
|
139
|
+
return failure("internal", String(error && typeof error === "object" && "message" in error ? error.message : error || fallback));
|
|
160
140
|
}
|
|
161
141
|
/**
|
|
162
142
|
* A remote store's session status: the parsed record while it is live, with its remaining uses.
|
|
@@ -204,74 +184,38 @@ function replayGuardTtlMs(expiresAtMs, nowMs = Date.now()) {
|
|
|
204
184
|
return Math.max(EXPORT_REPLAY_GUARD_MIN_RETENTION_MS, Math.floor(retainUntilMs - nowMs));
|
|
205
185
|
}
|
|
206
186
|
function replayGuardInvalid() {
|
|
207
|
-
return
|
|
208
|
-
ok: false,
|
|
209
|
-
code: "invalid_body",
|
|
210
|
-
message: "Invalid replay guard key"
|
|
211
|
-
};
|
|
187
|
+
return failure("invalid_body", "Invalid replay guard key");
|
|
212
188
|
}
|
|
213
189
|
function replayGuardExpired() {
|
|
214
|
-
return
|
|
215
|
-
ok: false,
|
|
216
|
-
code: "export_authorization_expired",
|
|
217
|
-
message: "Export authorization expired"
|
|
218
|
-
};
|
|
190
|
+
return failure("export_authorization_expired", "Export authorization expired");
|
|
219
191
|
}
|
|
220
192
|
function replayGuardDuplicate() {
|
|
221
|
-
return
|
|
222
|
-
ok: false,
|
|
223
|
-
code: "export_nonce_replay",
|
|
224
|
-
message: "Export authorization nonce already used"
|
|
225
|
-
};
|
|
193
|
+
return failure("export_nonce_replay", "Export authorization nonce already used");
|
|
226
194
|
}
|
|
227
195
|
function parseRedisReplayGuardResult(raw) {
|
|
228
196
|
const text = String(raw ?? "").trim();
|
|
229
197
|
if (text === "ok") return { ok: true };
|
|
230
198
|
if (text === "duplicate") return replayGuardDuplicate();
|
|
231
199
|
if (text === "expired") return replayGuardExpired();
|
|
232
|
-
return
|
|
233
|
-
ok: false,
|
|
234
|
-
code: "internal",
|
|
235
|
-
message: "Redis replay guard returned invalid response"
|
|
236
|
-
};
|
|
200
|
+
return failure("internal", "Redis replay guard returned invalid response");
|
|
237
201
|
}
|
|
238
202
|
function parseRedisConsumeOnceResult(raw) {
|
|
239
203
|
const text = String(raw ?? "").trim();
|
|
240
204
|
if (text.startsWith("ok:")) {
|
|
241
205
|
const remainingUses = Number(text.slice(3));
|
|
242
|
-
if (!Number.isFinite(remainingUses)) return
|
|
243
|
-
ok: false,
|
|
244
|
-
code: "internal",
|
|
245
|
-
message: "Redis consume-once returned invalid uses"
|
|
246
|
-
};
|
|
206
|
+
if (!Number.isFinite(remainingUses)) return failure("internal", "Redis consume-once returned invalid uses");
|
|
247
207
|
return {
|
|
248
208
|
ok: true,
|
|
249
209
|
remainingUses
|
|
250
210
|
};
|
|
251
211
|
}
|
|
252
|
-
if (text === "wallet_session_missing") return
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
message: "Wallet Session is missing"
|
|
256
|
-
};
|
|
257
|
-
if (text === "wallet_budget_exhausted") return {
|
|
258
|
-
ok: false,
|
|
259
|
-
code: "wallet_budget_exhausted",
|
|
260
|
-
message: "Wallet Session signing budget is exhausted"
|
|
261
|
-
};
|
|
262
|
-
return {
|
|
263
|
-
ok: false,
|
|
264
|
-
code: "internal",
|
|
265
|
-
message: "Redis consume-once returned invalid response"
|
|
266
|
-
};
|
|
212
|
+
if (text === "wallet_session_missing") return failure("wallet_session_missing", "Wallet Session is missing");
|
|
213
|
+
if (text === "wallet_budget_exhausted") return failure("wallet_budget_exhausted", "Wallet Session signing budget is exhausted");
|
|
214
|
+
return failure("internal", "Redis consume-once returned invalid response");
|
|
267
215
|
}
|
|
268
216
|
function parseRedisConsumedUseResult(raw) {
|
|
269
217
|
const value = typeof raw === "number" ? raw : Number(String(raw ?? "").trim());
|
|
270
|
-
if (!Number.isFinite(value)) return
|
|
271
|
-
ok: false,
|
|
272
|
-
code: "internal",
|
|
273
|
-
message: "Redis consumed-use check returned invalid response"
|
|
274
|
-
};
|
|
218
|
+
if (!Number.isFinite(value)) return failure("internal", "Redis consumed-use check returned invalid response");
|
|
275
219
|
return {
|
|
276
220
|
ok: true,
|
|
277
221
|
consumed: value > 0
|
|
@@ -441,11 +385,7 @@ var RedisTcpWalletSessionStore = class {
|
|
|
441
385
|
"1",
|
|
442
386
|
this.keys.uses(id)
|
|
443
387
|
]);
|
|
444
|
-
if (resp.type === "error") return {
|
|
445
|
-
ok: false,
|
|
446
|
-
code: "internal",
|
|
447
|
-
message: `Redis EVAL error: ${resp.value}`
|
|
448
|
-
};
|
|
388
|
+
if (resp.type === "error") return failure("internal", `Redis EVAL error: ${resp.value}`);
|
|
449
389
|
return parseRedisConsumeOnceResult(redisRawValue(resp));
|
|
450
390
|
} catch (e) {
|
|
451
391
|
return walletSessionStoreFailure(e, "Failed to consume threshold session");
|
|
@@ -460,11 +400,7 @@ var RedisTcpWalletSessionStore = class {
|
|
|
460
400
|
this.keys.uses(id),
|
|
461
401
|
this.keys.consumeOnce(id, idempotencyKey)
|
|
462
402
|
]);
|
|
463
|
-
if (resp.type === "error") return {
|
|
464
|
-
ok: false,
|
|
465
|
-
code: "internal",
|
|
466
|
-
message: `Redis EVAL error: ${resp.value}`
|
|
467
|
-
};
|
|
403
|
+
if (resp.type === "error") return failure("internal", `Redis EVAL error: ${resp.value}`);
|
|
468
404
|
return parseRedisConsumeOnceResult(resp.type === "integer" ? String(resp.value) : resp.value);
|
|
469
405
|
} catch (e) {
|
|
470
406
|
return walletSessionStoreFailure(e, "Failed to consume threshold session");
|
|
@@ -478,11 +414,7 @@ var RedisTcpWalletSessionStore = class {
|
|
|
478
414
|
};
|
|
479
415
|
try {
|
|
480
416
|
const resp = await this.client.send(["EXISTS", this.keys.consumeOnce(id, consumeKey)]);
|
|
481
|
-
if (resp.type === "error") return {
|
|
482
|
-
ok: false,
|
|
483
|
-
code: "internal",
|
|
484
|
-
message: `Redis EXISTS error: ${resp.value}`
|
|
485
|
-
};
|
|
417
|
+
if (resp.type === "error") return failure("internal", `Redis EXISTS error: ${resp.value}`);
|
|
486
418
|
return parseRedisConsumedUseResult(resp.value);
|
|
487
419
|
} catch (e) {
|
|
488
420
|
return walletSessionStoreFailure(e, "Failed to check consumed threshold session operation");
|
|
@@ -500,18 +432,10 @@ var RedisTcpWalletSessionStore = class {
|
|
|
500
432
|
"EX",
|
|
501
433
|
String(Math.max(1, Math.ceil(ttlMs / 1e3)))
|
|
502
434
|
]);
|
|
503
|
-
if (resp.type === "error") return {
|
|
504
|
-
ok: false,
|
|
505
|
-
code: "internal",
|
|
506
|
-
message: `Redis SET error: ${resp.value}`
|
|
507
|
-
};
|
|
435
|
+
if (resp.type === "error") return failure("internal", `Redis SET error: ${resp.value}`);
|
|
508
436
|
if (resp.type === "bulk" && resp.value === null) return replayGuardDuplicate();
|
|
509
437
|
if (resp.type === "simple" && resp.value === "OK") return { ok: true };
|
|
510
|
-
return
|
|
511
|
-
ok: false,
|
|
512
|
-
code: "internal",
|
|
513
|
-
message: "Redis replay guard returned invalid response"
|
|
514
|
-
};
|
|
438
|
+
return failure("internal", "Redis replay guard returned invalid response");
|
|
515
439
|
} catch (e) {
|
|
516
440
|
return walletSessionStoreFailure(e, "Failed to reserve replay guard");
|
|
517
441
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/core/ThresholdService/stores/exportReplayGuard.ts
|
|
2
|
+
const EXPORT_REPLAY_GUARD_CLOCK_SKEW_MS = 5 * 6e4;
|
|
3
|
+
const EXPORT_REPLAY_GUARD_MIN_RETENTION_MS = 1440 * 6e4;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { EXPORT_REPLAY_GUARD_CLOCK_SKEW_MS, EXPORT_REPLAY_GUARD_MIN_RETENTION_MS };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=exportReplayGuard.js.map
|
|
@@ -4,10 +4,11 @@ import { isPlainObject } from "../shared-ts/src/utils/validation.js";
|
|
|
4
4
|
import { sameRouterAbMpcMaterialActivationRef } from "../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
|
|
5
5
|
import { derivationClientSharePublicKey33B64uFromString, ecdsaClientRootPublicKey33B64uFromString, parseSdkEcdsaDerivationThresholdKeyId } from "../shared-ts/src/threshold/ecdsaDerivationRoleLocalBootstrap.js";
|
|
6
6
|
import { normalizeRuntimePolicyScope } from "../shared-ts/src/threshold/signingRootScope.js";
|
|
7
|
-
import { parseRouterAbEcdsaDerivationActivationRefreshRequestV1, parseRouterAbEcdsaDerivationActivationRefreshResponseV1, parseRouterAbEcdsaDerivationPublicCapabilityV1, parseRouterAbEcdsaRegistrationActivationReceiptV1, sameRouterAbEcdsaDerivationPublicCapabilityV1, sameRouterAbEcdsaDerivationPublicIdentityV1
|
|
8
|
-
import { thresholdEcdsaChainTargetFromValue, thresholdEcdsaChainTargetKey } from "./thresholdEcdsaChainTarget.js";
|
|
7
|
+
import { parseRouterAbEcdsaDerivationActivationRefreshRequestV1, parseRouterAbEcdsaDerivationActivationRefreshResponseV1, parseRouterAbEcdsaDerivationPublicCapabilityV1, parseRouterAbEcdsaRegistrationActivationReceiptV1, sameRegistrationSignerSet, sameRouterAbEcdsaDerivationPublicCapabilityV1, sameRouterAbEcdsaDerivationPublicIdentityV1 } from "../shared-ts/src/utils/routerAbEcdsaDerivation.js";
|
|
9
8
|
import { resolveStorePrefix } from "./d1TenantStore.js";
|
|
10
9
|
import { createDurableObjectStore, postDurableObjectRequest } from "./storeBackends.js";
|
|
10
|
+
import { thresholdEcdsaChainTargetKey } from "../shared-ts/src/utils/thresholdEcdsaChainTarget.js";
|
|
11
|
+
import { thresholdEcdsaChainTargetFromValue } from "./thresholdEcdsaChainTarget.js";
|
|
11
12
|
import { D1WalletStore, WALLET_STORE_D1_SCHEMA_SQL, buildWalletEcdsaSignerRecord, ensureWalletStoreD1Schema, parseWalletEd25519SignerRecord } from "./d1WalletStore.js";
|
|
12
13
|
//#region src/core/WalletStore.ts
|
|
13
14
|
function parseWalletEcdsaPendingSessionActivationRecord(raw) {
|
|
@@ -47,11 +48,8 @@ function parseForwardedEcdsaRefreshResponse(raw) {
|
|
|
47
48
|
function ecdsaPublicCapabilitiesEqual(left, right) {
|
|
48
49
|
return sameRouterAbEcdsaDerivationPublicCapabilityV1(left, right);
|
|
49
50
|
}
|
|
50
|
-
function sameWalletEcdsaSignerSetV1(left, right) {
|
|
51
|
-
return left.signer_set_id === right.signer_set_id && left.policy === right.policy && left.signer_a.role === right.signer_a.role && left.signer_a.signer_id === right.signer_a.signer_id && left.signer_a.key_epoch === right.signer_a.key_epoch && left.signer_b.role === right.signer_b.role && left.signer_b.signer_id === right.signer_b.signer_id && left.signer_b.key_epoch === right.signer_b.key_epoch && sameRouterAbServerIdentityV1(left.selected_server, right.selected_server);
|
|
52
|
-
}
|
|
53
51
|
function ecdsaPostRegistrationRequestMatchesCapability(input) {
|
|
54
|
-
return input.request.client_id === input.capability.client_id && input.request.router_id === input.capability.router_id && input.request.context.application_binding_digest_b64u === input.capability.context.application_binding_digest_b64u && sameRouterAbEcdsaDerivationPublicIdentityV1(input.request.public_identity, input.capability.public_identity) &&
|
|
52
|
+
return input.request.client_id === input.capability.client_id && input.request.router_id === input.capability.router_id && input.request.context.application_binding_digest_b64u === input.capability.context.application_binding_digest_b64u && sameRouterAbEcdsaDerivationPublicIdentityV1(input.request.public_identity, input.capability.public_identity) && sameRegistrationSignerSet(input.request.signer_set, input.capability.signer_set);
|
|
55
53
|
}
|
|
56
54
|
function resolveWalletStoreNamespace(config) {
|
|
57
55
|
return resolveStorePrefix(config, ["WALLET_PREFIX"], "wallet:");
|
|
@@ -6,9 +6,6 @@ function randomBase64Url(bytes) {
|
|
|
6
6
|
crypto.getRandomValues(data);
|
|
7
7
|
return base64UrlEncode(data);
|
|
8
8
|
}
|
|
9
|
-
function randomOpaqueId(byteLength = 16) {
|
|
10
|
-
return randomBase64Url(byteLength);
|
|
11
|
-
}
|
|
12
9
|
function randomNumericCode(length) {
|
|
13
10
|
const bytes = new Uint8Array(length);
|
|
14
11
|
crypto.getRandomValues(bytes);
|
|
@@ -17,6 +14,6 @@ function randomNumericCode(length) {
|
|
|
17
14
|
return code;
|
|
18
15
|
}
|
|
19
16
|
//#endregion
|
|
20
|
-
export { randomBase64Url, randomNumericCode
|
|
17
|
+
export { randomBase64Url, randomNumericCode };
|
|
21
18
|
|
|
22
19
|
//# sourceMappingURL=bytes.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeOptionalTrimmedString } from "../../shared-ts/src/utils/normalize.js";
|
|
2
2
|
import "../../shared-ts/src/utils/validation.js";
|
|
3
|
+
import { failure } from "../../shared-ts/src/utils/failure.js";
|
|
3
4
|
import { WALLET_EMAIL_OTP_ACTIONS, WALLET_EMAIL_OTP_REGISTRATION_OPERATION, WALLET_EMAIL_OTP_UNLOCK_OPERATION } from "../../shared-ts/src/utils/emailOtpDomain.js";
|
|
4
5
|
import { randomBase64Url } from "./bytes.js";
|
|
5
6
|
//#region src/core/authService/emailOtpChallengeOperations.ts
|
|
@@ -11,11 +12,7 @@ function createGrantToken() {
|
|
|
11
12
|
return typeof crypto === "undefined" || typeof crypto.getRandomValues !== "function" ? null : randomBase64Url(24);
|
|
12
13
|
}
|
|
13
14
|
function unsupportedCryptoResult() {
|
|
14
|
-
return
|
|
15
|
-
ok: false,
|
|
16
|
-
code: "unsupported",
|
|
17
|
-
message: "crypto.getRandomValues is unavailable in this runtime"
|
|
18
|
-
};
|
|
15
|
+
return failure("unsupported", "crypto.getRandomValues is unavailable in this runtime");
|
|
19
16
|
}
|
|
20
17
|
async function createEmailOtpChallenge(input, request) {
|
|
21
18
|
const result = await input.createChallengeWithAction({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { parseChallengeSubjectId, parseEmailOtpChallengeId, parseEmailOtpRegistrationAttemptId, parseOrgId, parseProviderSubject, parseWalletId } from "../../shared-ts/src/utils/domainIds.js";
|
|
2
2
|
import { normalizeOptionalTrimmedString } from "../../shared-ts/src/utils/normalize.js";
|
|
3
3
|
import "../../shared-ts/src/utils/validation.js";
|
|
4
|
+
import { failure } from "../../shared-ts/src/utils/failure.js";
|
|
4
5
|
import { WALLET_EMAIL_OTP_ACTIONS, WALLET_EMAIL_OTP_EXPORT_OPERATION, WALLET_EMAIL_OTP_REGISTRATION_OPERATION, WALLET_EMAIL_OTP_TRANSACTION_SIGN_OPERATION, WALLET_EMAIL_OTP_UNLOCK_OPERATION } from "../../shared-ts/src/utils/emailOtpDomain.js";
|
|
5
6
|
//#region src/core/authService/emailOtpChallengeProof.ts
|
|
6
7
|
function assertNever(value) {
|
|
@@ -134,41 +135,17 @@ function buildVerifiedEmailOtpRegistrationChallengeProof(input) {
|
|
|
134
135
|
}
|
|
135
136
|
function parseRawEmailOtpRegistrationChallengeProofInput(request) {
|
|
136
137
|
const providerSubject = parseProviderSubject(request.providerSubject);
|
|
137
|
-
if (!providerSubject.ok) return
|
|
138
|
-
ok: false,
|
|
139
|
-
code: "invalid_body",
|
|
140
|
-
message: "Email OTP registration requires providerSubject"
|
|
141
|
-
};
|
|
138
|
+
if (!providerSubject.ok) return failure("invalid_body", "Email OTP registration requires providerSubject");
|
|
142
139
|
const challengeSubjectId = parseChallengeSubjectId(request.providerSubject);
|
|
143
|
-
if (!challengeSubjectId.ok) return
|
|
144
|
-
ok: false,
|
|
145
|
-
code: "invalid_body",
|
|
146
|
-
message: "Email OTP registration requires challengeSubjectId"
|
|
147
|
-
};
|
|
140
|
+
if (!challengeSubjectId.ok) return failure("invalid_body", "Email OTP registration requires challengeSubjectId");
|
|
148
141
|
const challengeId = parseEmailOtpChallengeId(request.challengeId);
|
|
149
|
-
if (!challengeId.ok) return
|
|
150
|
-
ok: false,
|
|
151
|
-
code: "invalid_body",
|
|
152
|
-
message: "Email OTP registration requires challengeId"
|
|
153
|
-
};
|
|
142
|
+
if (!challengeId.ok) return failure("invalid_body", "Email OTP registration requires challengeId");
|
|
154
143
|
const finalWalletId = parseWalletId(request.walletId);
|
|
155
|
-
if (!finalWalletId.ok) return
|
|
156
|
-
ok: false,
|
|
157
|
-
code: "invalid_body",
|
|
158
|
-
message: "Email OTP registration requires walletId"
|
|
159
|
-
};
|
|
144
|
+
if (!finalWalletId.ok) return failure("invalid_body", "Email OTP registration requires walletId");
|
|
160
145
|
const orgId = parseOrgId(request.orgId);
|
|
161
|
-
if (!orgId.ok) return
|
|
162
|
-
ok: false,
|
|
163
|
-
code: "invalid_body",
|
|
164
|
-
message: "Email OTP registration requires orgId"
|
|
165
|
-
};
|
|
146
|
+
if (!orgId.ok) return failure("invalid_body", "Email OTP registration requires orgId");
|
|
166
147
|
const ownerProofBindingDigest = normalizeOptionalTrimmedString(request.ownerProofBindingDigest);
|
|
167
|
-
if (!ownerProofBindingDigest) return
|
|
168
|
-
ok: false,
|
|
169
|
-
code: "invalid_body",
|
|
170
|
-
message: "Email OTP registration requires ownerProofBindingDigest"
|
|
171
|
-
};
|
|
148
|
+
if (!ownerProofBindingDigest) return failure("invalid_body", "Email OTP registration requires ownerProofBindingDigest");
|
|
172
149
|
const registrationAttemptId = parseEmailOtpRegistrationAttemptId(request.googleEmailOtpRegistrationAttemptId);
|
|
173
150
|
if (registrationAttemptId.ok) return {
|
|
174
151
|
ok: true,
|
|
@@ -183,17 +160,9 @@ function parseRawEmailOtpRegistrationChallengeProofInput(request) {
|
|
|
183
160
|
challengeId: challengeId.value
|
|
184
161
|
}
|
|
185
162
|
};
|
|
186
|
-
if (registrationAttemptId.error.code === "invalid") return
|
|
187
|
-
ok: false,
|
|
188
|
-
code: "invalid_body",
|
|
189
|
-
message: "googleEmailOtpRegistrationAttemptId must be a string"
|
|
190
|
-
};
|
|
163
|
+
if (registrationAttemptId.error.code === "invalid") return failure("invalid_body", "googleEmailOtpRegistrationAttemptId must be a string");
|
|
191
164
|
const proofEmail = normalizeOptionalTrimmedString(request.proofEmail)?.toLowerCase();
|
|
192
|
-
if (!proofEmail) return
|
|
193
|
-
ok: false,
|
|
194
|
-
code: "invalid_body",
|
|
195
|
-
message: "Email OTP registration requires proofEmail"
|
|
196
|
-
};
|
|
165
|
+
if (!proofEmail) return failure("invalid_body", "Email OTP registration requires proofEmail");
|
|
197
166
|
return {
|
|
198
167
|
ok: true,
|
|
199
168
|
input: {
|