@seams/wallet-server 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +1 -113
- package/artifact-manifest.json +78 -33
- package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/deriver-a/index.js +2 -2
- 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.js +2 -2
- 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.js +2 -2
- 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.js +2 -2
- 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.js +2 -2
- package/cloudflare-router-ab/build/tenant-root-control-plane/index_bg.wasm +0 -0
- package/cloudflare-router-ab/scripts/prepare-local-runtime-config.mjs +0 -2
- package/cloudflare-router-ab/scripts/start-local-role-workers.mjs +77 -20
- package/dist/esm/authorization/lifecycleRouting.js +62 -0
- package/dist/esm/authorization/service.js +43 -12
- package/dist/esm/authorization/vaultProxyUse.js +2 -6
- package/dist/esm/cloud-host.js +23 -25
- package/dist/esm/core/EmailOtpRecords.js +1 -217
- package/dist/esm/core/EmailOtpStores.js +0 -859
- package/dist/esm/core/IdentityStore.js +2 -426
- package/dist/esm/core/SessionService.js +7 -30
- package/dist/esm/core/ThresholdService/config.js +1 -9
- package/dist/esm/core/ThresholdService/index.js +0 -4
- package/dist/esm/core/ThresholdService/kv.js +1 -66
- package/dist/esm/core/ThresholdService/routerAb/ecdsaDerivationPoolFillHandlers.js +1 -13
- package/dist/esm/core/ThresholdService/routerAbNormalSigningPolicy.js +4 -21
- package/dist/esm/core/ThresholdService/stores/WalletSessionStore.js +0 -617
- package/dist/esm/core/ThresholdService/validation.js +2 -346
- package/dist/esm/core/WalletAuthMethodStore.js +2 -123
- package/dist/esm/core/WalletStore.js +6 -214
- package/dist/esm/core/WebAuthnAuthenticatorStore.js +0 -202
- package/dist/esm/core/WebAuthnCredentialBindingStore.js +2 -182
- package/dist/esm/core/WebAuthnLoginChallengeStore.js +0 -52
- package/dist/esm/core/WebAuthnSyncChallengeStore.js +0 -54
- package/dist/esm/core/authService/emailOtpConfig.js +1 -195
- package/dist/esm/core/authService/emailOtpEnrollment.js +0 -141
- package/dist/esm/core/authService/emailOtpSeal.js +0 -78
- package/dist/esm/core/authService/nearTransactions.js +3 -98
- package/dist/esm/core/authService/rateLimits.js +0 -87
- package/dist/esm/core/authService/thresholdEcdsaKeyInventory.js +2 -1
- package/dist/esm/core/authService/webauthn.js +14 -464
- package/dist/esm/core/authService/webauthnOidcHelpers.js +1 -24
- package/dist/esm/core/authService/webauthnVerificationOutcomes.js +5 -24
- package/dist/esm/core/authService/webauthnWalletBinding.js +0 -37
- package/dist/esm/core/config.js +1 -95
- package/dist/esm/core/d1EcdsaSignerRead.js +76 -0
- package/dist/esm/core/d1IdentityStore.js +17 -77
- package/dist/esm/core/d1TenantStore.js +1 -24
- package/dist/esm/core/d1WalletAuthMethodStore.js +2 -5
- package/dist/esm/core/d1WalletStore.js +15 -25
- package/dist/esm/core/deviceLinking/linkedDeviceBootstrap.js +13 -0
- package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -5
- package/dist/esm/core/deviceLinking/linkedDeviceSession.js +20 -14
- 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 +22 -10
- package/dist/esm/core/ecdsaMaterialReadSnapshot.js +85 -0
- package/dist/esm/core/emailOtpD1Statements.js +107 -94
- package/dist/esm/core/keyMaterialBrands.js +2 -12
- package/dist/esm/core/nearKeys.js +0 -1
- package/dist/esm/core/nearRelayerAccountProvisioning.js +8 -14
- package/dist/esm/core/passkeyCredentialClaims.js +8 -0
- package/dist/esm/core/routerAbSigning/RouterAbEcdsaPresignRuntime.js +2 -6
- package/dist/esm/core/routerAbSigning/RouterAbNormalSigningRuntime.js +2 -30
- package/dist/esm/core/signingLanes/WalletExecutionLaneProjection.js +3 -6
- package/dist/esm/core/signingMaterial/ordinaryInactiveSignerMaterialReservation.js +2 -5
- package/dist/esm/core/thresholdEcdsaChainTarget.js +2 -7
- package/dist/esm/hosted-wallet-gateway.js +68 -45
- package/dist/esm/index.js +6 -19
- package/dist/esm/localHostedWalletGatewayHandler.js +25 -0
- package/dist/esm/localIntendedMaterialAdmissionFault.js +176 -0
- package/dist/esm/localIntendedPresignCancellation.js +44 -0
- package/dist/esm/localRegistrationSetupAuthority.js +89 -0
- package/dist/esm/router/auth/authRequestValidation.js +8 -16
- 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 -16
- package/dist/esm/router/cloudflare/d1/auth/d1AuthorizationAssembly.js +87 -0
- 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/d1RouterApiAuthConfig.js +12 -2
- package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +37 -308
- package/dist/esm/router/cloudflare/d1/auth/walletSessionCredentialReaders.js +76 -0
- package/dist/esm/router/cloudflare/d1/authorization/authorizedOperationStatements.js +52 -43
- package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +217 -50
- package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +8 -12
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +62 -21
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEd25519ExportRootStore.js +6 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEmailOtpGrantStore.js +12 -2
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEmailOtpTargetFactor.js +4 -4
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceRequestProofNonceStore.js +3 -9
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceRouteService.js +2 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.js +89 -7
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +24 -15
- package/dist/esm/router/cloudflare/d1/deviceLinking/index.js +3 -3
- package/dist/esm/router/cloudflare/d1/ed25519Yao/d1Ed25519YaoCapabilityPersistence.js +9 -6
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +12 -56
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +17 -81
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeVerifier.js +0 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpDeliveryRuntime.js +6 -25
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpEnrollmentStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpGrantStore.js +1 -7
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRateLimitStore.js +19 -13
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +12 -48
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +24 -86
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRegistrationEnrollmentFinalizer.js +9 -32
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpServerSealRuntime.js +5 -21
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationAttemptStore.js +44 -12
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationRecords.js +1 -49
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +37 -136
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleRegistrationCompletion.js +85 -0
- package/dist/esm/router/cloudflare/d1/identity/d1IdentityRecords.js +0 -1
- package/dist/esm/router/cloudflare/d1/identity/d1IdentityService.js +9 -88
- package/dist/esm/router/cloudflare/d1/near/d1SponsoredNearAccount.js +242 -0
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +18 -92
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +4 -55
- package/dist/esm/router/cloudflare/d1/oidc/googleOidcToken.js +41 -0
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +9 -15
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +36 -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 +13 -10
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +9 -14
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.js +25 -13
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +7 -31
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationSetupSupport.js +74 -0
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +7 -1
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +101 -260
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetup.js +12 -56
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +155 -0
- package/dist/esm/router/cloudflare/d1/registration/walletRegistrationEstablishedSessionIssuer.js +1 -3
- package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +1 -4
- package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +131 -31
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerFinalizeRecord.js +68 -0
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerService.js +7 -54
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +9 -8
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorityStore.js +2 -142
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +55 -171
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +10 -79
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnStore.js +23 -7
- package/dist/esm/router/cloudflare/runtime/routerAbPrewarm.js +2 -2
- package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +6 -20
- package/dist/esm/router/cloudflare/runtime/tenantRootCreationGrant.js +2 -9
- package/dist/esm/router/cloudflare/runtime/walletConsoleOps.js +1 -0
- package/dist/esm/router/cloudflare/runtime/walletConsoleOpsClient.js +5 -0
- package/dist/esm/router/cloudflare/runtime/walletControlOps.js +2 -1
- package/dist/esm/router/cloudflare/runtime/walletGateway.js +1 -1
- package/dist/esm/router/cloudflare/runtime/walletRuntimeOps.js +16 -4
- package/dist/esm/router/cloudflare-adaptor.js +1 -2
- package/dist/esm/router/cloudflare.js +3390 -3437
- package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistration.js +11 -8
- package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPartitionedStateStore.js +3 -2
- package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPartitioning.js +6 -6
- package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPersistence.js +5 -8
- package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.js +6 -6
- package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExportRequestScopedCloudflare.js +3 -0
- package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryRequestScopedCloudflare.js +8 -0
- 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/emailOtpRequestValidation.js +0 -1
- package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +15 -62
- package/dist/esm/router/domains/passkeyCustody/passkeyCustodyEnvelopeRetrieval.js +2 -8
- package/dist/esm/router/domains/passkeyCustody/walletCustodyRegistrationCommit.js +2 -8
- 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/routerAbPrivateSigningWorker.js +5 -19
- package/dist/esm/router/domains/signingOperations/walletExecutionAdmission.js +3 -7
- package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +7 -13
- package/dist/esm/router/domains/walletRegistration/walletRegistrationReservation.js +70 -0
- package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +10 -11
- package/dist/esm/router/domains/walletRegistration/walletRegistrationSetupPayload.js +2 -3
- package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +55 -200
- package/dist/esm/router/express.js +858 -1145
- package/dist/esm/router/framework/http.js +7 -1
- package/dist/esm/router/framework/registrationSetupDispatch.js +14 -0
- package/dist/esm/router/framework/ror/normalize.js +0 -1
- package/dist/esm/router/framework/ror/options.js +0 -1
- package/dist/esm/router/framework/ror/provider.js +0 -1
- package/dist/esm/router/framework/ror/staticProvider.js +0 -1
- package/dist/esm/router/framework/routeDefinitions.js +1 -2
- package/dist/esm/router/framework/routerApiWebhooks.js +0 -1
- package/dist/esm/router/framework/runtimeSnapshotConsumer.js +8 -35
- package/dist/esm/router/ror.js +0 -1
- package/dist/esm/router/transport/fetch/createFetchRouter.js +3 -8
- package/dist/esm/router/transport/fetch/routes/auth.js +11 -41
- package/dist/esm/router/transport/fetch/routes/deviceLinking.js +36 -147
- package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +7 -23
- package/dist/esm/router/transport/fetch/routes/deviceLinkingResponses.js +130 -0
- package/dist/esm/router/transport/fetch/routes/ecdsaOperationStepUpFactor.js +171 -0
- package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +1 -0
- package/dist/esm/router/transport/fetch/routes/sessions.js +1 -0
- package/dist/esm/router/transport/fetch/routes/syncAccount.js +15 -38
- package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +46 -194
- package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +4 -1
- package/dist/esm/router/transport/fetch/routes/walletRegistration.js +3 -1
- package/dist/esm/router/transport/fetch/routes/webauthnAuthenticators.js +4 -16
- package/dist/esm/shared-ts/src/authorization/walletSessionIssuance.js +0 -1
- package/dist/esm/shared-ts/src/authorization/walletSignerActivationEquality.js +12 -0
- package/dist/esm/shared-ts/src/device-linking/authorityActivation.js +0 -2
- package/dist/esm/shared-ts/src/device-linking/committedSignerPackages.js +2 -5
- package/dist/esm/shared-ts/src/device-linking/contracts.js +16 -1
- package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -5
- package/dist/esm/shared-ts/src/device-linking/digests.js +1 -8
- 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/near/actions.js +0 -1
- package/dist/esm/shared-ts/src/near/nearClient.js +0 -2
- package/dist/esm/shared-ts/src/passkey-custody/primitives.js +5 -1
- package/dist/esm/shared-ts/src/signing-lanes/evmFamilySigningKeySlotId.js +1 -1
- package/dist/esm/shared-ts/src/signing-lanes/index.js +1 -6
- package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +5 -9
- package/dist/esm/shared-ts/src/signing-lanes/participantDigest.js +2 -81
- package/dist/esm/shared-ts/src/signing-lanes/participants.js +1 -219
- package/dist/esm/shared-ts/src/signing-lanes/recordParsers.js +0 -3
- 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 +2 -6
- package/dist/esm/shared-ts/src/threshold/ecdsaDerivationRoleLocalBootstrap.js +0 -1
- package/dist/esm/shared-ts/src/threshold/keyMaterialBrands.js +1 -22
- package/dist/esm/shared-ts/src/threshold/participants.js +0 -1
- package/dist/esm/shared-ts/src/threshold/signingRootScope.js +0 -1
- package/dist/esm/shared-ts/src/utils/addWalletAuthMethod.js +4 -13
- package/dist/esm/shared-ts/src/utils/canonicalPrimitives.js +1 -7
- package/dist/esm/shared-ts/src/utils/domainIds.js +1 -16
- package/dist/esm/shared-ts/src/utils/ecdsaCapabilityActivation.js +1 -11
- package/dist/esm/shared-ts/src/utils/ecdsaKeyFactsInventory.js +2 -5
- 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/errors.js +1 -19
- 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/near.js +1 -1
- package/dist/esm/shared-ts/src/utils/registrationEstablishedSession.js +1 -1
- package/dist/esm/shared-ts/src/utils/registrationIds.js +1 -5
- package/dist/esm/shared-ts/src/utils/registrationIntent.js +3 -13
- package/dist/esm/shared-ts/src/utils/registrationSetupOperation.js +8 -0
- package/dist/esm/shared-ts/src/utils/registrationSignerPlan.js +3 -6
- package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -2
- 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/utils/validation.js +1 -5
- package/dist/esm/shared-ts/src/utils/walletAuthAuthority.js +0 -1
- package/dist/esm/shared-ts/src/utils/walletManagementProtocol.js +6 -0
- package/dist/esm/shared-ts/src/utils/wireSchema.js +2 -13
- package/dist/esm/shared-ts/src/wallet-recovery/backupAcknowledgement.js +6 -24
- package/dist/esm/shared-ts/src/wallet-recovery/recoveryCodeLocator.js +0 -1
- package/dist/esm/shared-ts/src/wallet-recovery/recoveryKeyId.js +5 -6
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -4
- package/dist/esm/storage/d1Sql.js +1 -7
- package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +10 -33
- package/dist/esm/threshold/session/signingSessionSeal/guards/backends.js +1 -2
- package/dist/esm/threshold/session/signingSessionSeal/idempotencyBackends.js +3 -4
- package/dist/esm/threshold/session/signingSessionSeal/idempotencyRecords.js +3 -10
- package/dist/esm/threshold/session/signingSessionSeal/options.js +0 -1
- 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.js +0 -611
- package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
- package/dist/esm/wasm/shamir3pass_runtime/pkg/shamir3pass_runtime_bg.wasm +0 -0
- package/dist/types/shared-ts/src/authorization/capabilityKinds.d.ts +0 -4
- 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 +6 -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/evmFamilySigningKeySlotId.d.ts +0 -2
- package/dist/types/shared-ts/src/signing-lanes/execution.d.ts +11 -12
- package/dist/types/shared-ts/src/signing-lanes/ids.d.ts +3 -17
- package/dist/types/shared-ts/src/signing-lanes/index.d.ts +0 -4
- package/dist/types/shared-ts/src/signing-lanes/ownerContinuity.d.ts +0 -1
- package/dist/types/shared-ts/src/signing-lanes/participantDigest.d.ts +0 -18
- package/dist/types/shared-ts/src/signing-lanes/participants.d.ts +6 -35
- package/dist/types/shared-ts/src/signing-lanes/rotation.d.ts +6 -845
- 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/keyMaterialBrands.d.ts +0 -10
- package/dist/types/shared-ts/src/threshold/participants.d.ts +1 -1
- package/dist/types/shared-ts/src/threshold/signingRootScope.d.ts +1 -0
- package/dist/types/shared-ts/src/utils/addWalletAuthMethod.d.ts +1 -133
- package/dist/types/shared-ts/src/utils/addWalletAuthMethod.typecheck.d.ts +4 -18
- package/dist/types/shared-ts/src/utils/domainIds.d.ts +0 -12
- 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/errors.d.ts +0 -4
- 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/near.d.ts +0 -20
- package/dist/types/shared-ts/src/utils/nearRpcResults.d.ts +1 -0
- package/dist/types/shared-ts/src/utils/normalize.d.ts +0 -2
- package/dist/types/shared-ts/src/utils/registrationAuthMethodInput.d.ts +3 -8
- package/dist/types/shared-ts/src/utils/registrationSetupOperation.d.ts +3 -0
- 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/validation.d.ts +1 -3
- 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/walletCapabilityBindings.d.ts +0 -1
- package/dist/types/shared-ts/src/utils/walletManagementProtocol.d.ts +3 -0
- package/dist/types/shared-ts/src/utils/webauthnDeviceInfo.d.ts +4 -2
- package/dist/types/shared-ts/src/utils/wireSchema.d.ts +0 -2
- package/dist/types/shared-ts/src/wallet-recovery/backupAcknowledgement.d.ts +0 -1
- package/dist/types/shared-ts/src/wallet-recovery/recoveryCodeReservation.d.ts +1 -10
- package/dist/types/shared-ts/src/wallet-recovery/recoveryCodes.d.ts +1 -3
- package/dist/types/shared-ts/src/wallet-recovery/recoveryEnvelopes.d.ts +3 -16
- package/dist/types/shared-ts/src/wallet-recovery/recoveryKeyId.d.ts +5 -21
- 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/lifecycleRouting.d.ts +32 -0
- package/dist/types/wallet-server/src/authorization/lifecycleRouting.typecheck.d.ts +2 -0
- package/dist/types/wallet-server/src/authorization/recoveryRouting.d.ts +22 -0
- package/dist/types/wallet-server/src/authorization/recoveryRouting.typecheck.d.ts +2 -0
- package/dist/types/wallet-server/src/authorization/service.d.ts +27 -1
- package/dist/types/wallet-server/src/authorization/sessionRouting.d.ts +20 -0
- package/dist/types/wallet-server/src/authorization/sessionRouting.typecheck.d.ts +2 -0
- package/dist/types/wallet-server/src/cloud-host.d.ts +31 -9
- package/dist/types/wallet-server/src/core/EmailOtpRecords.d.ts +1 -22
- package/dist/types/wallet-server/src/core/EmailOtpStores.d.ts +1 -79
- package/dist/types/wallet-server/src/core/IdentityStore.d.ts +0 -10
- package/dist/types/wallet-server/src/core/RegistrationCeremonyStore.d.ts +0 -1
- package/dist/types/wallet-server/src/core/ThresholdService/config.d.ts +0 -2
- package/dist/types/wallet-server/src/core/ThresholdService/index.d.ts +1 -3
- package/dist/types/wallet-server/src/core/ThresholdService/kv.d.ts +0 -7
- package/dist/types/wallet-server/src/core/ThresholdService/routerAb/ecdsaDerivationPoolFillHandlers.d.ts +0 -3
- package/dist/types/wallet-server/src/core/ThresholdService/routerAbNormalSigningPolicy.d.ts +0 -1
- package/dist/types/wallet-server/src/core/ThresholdService/stores/WalletSessionStore.d.ts +6 -18
- package/dist/types/wallet-server/src/core/ThresholdService/validation.d.ts +0 -127
- package/dist/types/wallet-server/src/core/WalletAuthMethodStore.d.ts +1 -5
- package/dist/types/wallet-server/src/core/WalletStore.d.ts +0 -3
- package/dist/types/wallet-server/src/core/WebAuthnAuthenticatorStore.d.ts +8 -20
- package/dist/types/wallet-server/src/core/WebAuthnCredentialBindingStore.d.ts +1 -27
- package/dist/types/wallet-server/src/core/WebAuthnLoginChallengeStore.d.ts +2 -16
- package/dist/types/wallet-server/src/core/WebAuthnSyncChallengeStore.d.ts +22 -14
- package/dist/types/wallet-server/src/core/authService/emailOtpConfig.d.ts +0 -24
- package/dist/types/wallet-server/src/core/authService/emailOtpEnrollment.d.ts +1 -70
- package/dist/types/wallet-server/src/core/authService/emailOtpSeal.d.ts +1 -14
- package/dist/types/wallet-server/src/core/authService/githubOAuth.d.ts +2 -1
- package/dist/types/wallet-server/src/core/authService/nearTransactions.d.ts +1 -39
- package/dist/types/wallet-server/src/core/authService/rateLimits.d.ts +0 -17
- package/dist/types/wallet-server/src/core/authService/webauthn.d.ts +0 -125
- package/dist/types/wallet-server/src/core/authService/webauthnOidcHelpers.d.ts +0 -3
- package/dist/types/wallet-server/src/core/authService/webauthnVerificationOutcomes.d.ts +1 -1
- package/dist/types/wallet-server/src/core/authService/webauthnWalletBinding.d.ts +0 -12
- package/dist/types/wallet-server/src/core/config.d.ts +0 -10
- package/dist/types/wallet-server/src/core/d1EcdsaSignerRead.d.ts +39 -0
- package/dist/types/wallet-server/src/core/d1IdentityStore.d.ts +0 -2
- package/dist/types/wallet-server/src/core/d1TenantStore.d.ts +0 -7
- package/dist/types/wallet-server/src/core/d1WalletAuthMethodStore.d.ts +0 -1
- package/dist/types/wallet-server/src/core/d1WalletStore.d.ts +10 -0
- package/dist/types/wallet-server/src/core/deviceLinking/linkedDeviceBootstrap.d.ts +19 -0
- package/dist/types/wallet-server/src/core/deviceLinking/linkedDeviceSession.d.ts +8 -6
- package/dist/types/wallet-server/src/core/deviceLinking/linkedDeviceSessionRecord.d.ts +3 -4
- package/dist/types/wallet-server/src/core/deviceLinking/requestProof.d.ts +2 -5
- package/dist/types/wallet-server/src/core/ecdsaMaterialReadSnapshot.d.ts +19 -0
- package/dist/types/wallet-server/src/core/emailOtpD1Statements.d.ts +10 -7
- package/dist/types/wallet-server/src/core/keyMaterialBrands.d.ts +1 -5
- package/dist/types/wallet-server/src/core/nearRelayerAccountProvisioning.d.ts +0 -1
- package/dist/types/wallet-server/src/core/passkeyCredentialClaims.d.ts +9 -0
- package/dist/types/wallet-server/src/core/routerAbSigning/RouterAbEcdsaPresignRuntime.d.ts +0 -2
- package/dist/types/wallet-server/src/core/routerAbSigning/RouterAbNormalSigningRuntime.d.ts +3 -7
- 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/threeRouteRegistrationContracts.d.ts +1 -92
- package/dist/types/wallet-server/src/core/threeRouteRegistrationContracts.typecheck.d.ts +4 -52
- package/dist/types/wallet-server/src/core/thresholdEcdsaChainTarget.d.ts +3 -12
- package/dist/types/wallet-server/src/core/types.d.ts +2 -305
- package/dist/types/wallet-server/src/hosted-wallet-gateway.d.ts +15 -3
- package/dist/types/wallet-server/src/index.d.ts +8 -13
- 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/localRegistrationSetupAuthority.d.ts +13 -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/d1AuthorizationAssembly.d.ts +23 -0
- 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/d1RouterApiAuthConfig.d.ts +25 -3
- 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 +11 -2
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.d.ts +22 -3
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEmailOtpGrantStore.d.ts +7 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceRequestProofNonceStore.d.ts +1 -10
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceRouteService.d.ts +4 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.d.ts +8 -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/deviceLinking/d1LinkedDeviceTargetPlanner.d.ts +1 -13
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.d.ts +2 -2
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeStore.d.ts +1 -1
- 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/d1EmailOtpGrantStore.d.ts +0 -2
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1EmailOtpRateLimitStore.d.ts +20 -11
- 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/emailOtp/d1GoogleEmailOtpRegistrationAttemptStore.d.ts +29 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationRecords.d.ts +3 -16
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.d.ts +7 -2
- package/dist/types/wallet-server/src/router/cloudflare/d1/emailOtp/d1GoogleRegistrationCompletion.d.ts +23 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/identity/d1IdentityService.d.ts +0 -12
- package/dist/types/wallet-server/src/router/cloudflare/d1/near/d1SponsoredNearAccount.d.ts +24 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/near/d1SponsoredNearAccount.typecheck.d.ts +2 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/oidc/d1OidcVerificationService.d.ts +0 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/oidc/googleOidcToken.d.ts +4 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.d.ts +5 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.d.ts +9 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.d.ts +3 -7
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.d.ts +10 -11
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.d.ts +3 -2
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationSetupSupport.d.ts +51 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.d.ts +3 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationService.d.ts +35 -50
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationSetup.d.ts +3 -30
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.d.ts +11 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.d.ts +14 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAddSignerFinalizeRecord.d.ts +27 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAddSignerService.d.ts +1 -10
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAuthMethodService.d.ts +2 -2
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAuthorityStore.d.ts +0 -4
- package/dist/types/wallet-server/src/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.d.ts +3 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/webauthn/d1WebAuthnRecords.d.ts +8 -50
- package/dist/types/wallet-server/src/router/cloudflare/d1/webauthn/d1WebAuthnStore.d.ts +23 -10
- package/dist/types/wallet-server/src/router/cloudflare/d1/webauthn/d1WebAuthnStore.typecheck.d.ts +2 -0
- package/dist/types/wallet-server/src/router/cloudflare/runtime/cloudflare.types.d.ts +0 -2
- package/dist/types/wallet-server/src/router/cloudflare/runtime/walletConsoleOps.d.ts +9 -34
- package/dist/types/wallet-server/src/router/cloudflare/runtime/walletConsoleOpsClient.d.ts +2 -0
- package/dist/types/wallet-server/src/router/cloudflare/runtime/walletGateway.d.ts +1 -1
- package/dist/types/wallet-server/src/router/cloudflare/runtime/walletRuntimeOps.d.ts +3 -0
- package/dist/types/wallet-server/src/router/cloudflare-adaptor.d.ts +0 -1
- package/dist/types/wallet-server/src/router/domains/ecdsa/thresholdEcdsaRequestValidation.d.ts +3 -15
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistration.d.ts +1 -1
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPartitioning.d.ts +2 -2
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.d.ts +2 -2
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.typecheck.d.ts +2 -0
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/export/routerAbEd25519YaoExportRequestScopedCloudflare.d.ts +2 -0
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryRequestScopedCloudflare.d.ts +2 -0
- package/dist/types/wallet-server/src/router/domains/ed25519Yao/session/routerAbEd25519YaoWalletSession.d.ts +9 -50
- package/dist/types/wallet-server/src/router/domains/passkeyCustody/passkeyCustodyEnvelopeRetrieval.d.ts +0 -2
- package/dist/types/wallet-server/src/router/domains/passkeyCustody/walletCustodyRegistrationCommit.d.ts +0 -3
- 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 -33
- package/dist/types/wallet-server/src/router/domains/signingOperations/walletExecutionAdmission.d.ts +1 -2
- package/dist/types/wallet-server/src/router/domains/syncAccount/syncAccountRequestValidation.d.ts +2 -7
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationInputs.d.ts +1 -0
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationReservation.d.ts +51 -0
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationRoutes.d.ts +2 -10
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationSetupPayload.d.ts +2 -2
- package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +3 -1
- package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +39 -38
- package/dist/types/wallet-server/src/router/framework/googleLoginResolution.typecheck.d.ts +2 -0
- package/dist/types/wallet-server/src/router/framework/http.d.ts +1 -0
- package/dist/types/wallet-server/src/router/framework/registrationSetupDispatch.d.ts +13 -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/deviceLinking.d.ts +1 -1
- 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/deviceLinkingResponses.d.ts +17 -0
- package/dist/types/wallet-server/src/router/transport/fetch/routes/ecdsaOperationStepUpFactor.d.ts +37 -0
- 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/storage/d1Sql.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/migrations/d1-signer/0040_namespace_home_challenges.sql +16 -0
- package/migrations/d1-signer/0041_step_up_admission_expiry.sql +28 -0
- package/migrations/d1-signer/0042_deployment_resource_challenges.sql +4 -0
- package/migrations/d1-signer/0043_google_registration_candidate_claim.sql +2 -0
- package/migrations/d1-signer/0044_linked_device_bootstrap_imports.sql +6 -0
- package/migrations/d1-signer/0045_wallet_owned_capability_receipts.sql +29 -0
- package/migrations/d1-signer/0046_wallet_owned_signing_abuse.sql +41 -0
- package/migrations/d1-signer/0047_remove_unused_near_public_keys.sql +2 -0
- package/migrations/d1-signer/0048_operation_owner_scope.sql +45 -0
- package/package.json +2 -3
- package/src/README.md +11 -3
- package/dist/esm/core/AuthService.js +0 -2
- package/dist/esm/core/NearPublicKeyStore.js +0 -200
- package/dist/esm/core/ThresholdService/stores/CloudflareDurableObjectStore.js +0 -397
- package/dist/esm/core/ThresholdService/stores/KeyStore.js +0 -140
- package/dist/esm/core/ThresholdService/stores/SessionStore.js +0 -361
- package/dist/esm/core/ThresholdService/stores/StoreConfig.js +0 -13
- package/dist/esm/core/authService/AuthService.js +0 -594
- package/dist/esm/core/authService/bytes.js +0 -22
- package/dist/esm/core/authService/configValues.js +0 -15
- package/dist/esm/core/authService/emailOtpChallengeOperations.js +0 -126
- package/dist/esm/core/authService/emailOtpChallengeProof.js +0 -214
- package/dist/esm/core/authService/emailOtpChallengeVerification.js +0 -335
- package/dist/esm/core/authService/emailOtpChallenges.js +0 -260
- package/dist/esm/core/authService/emailOtpDelivery.js +0 -169
- package/dist/esm/core/authService/emailOtpGrant.js +0 -74
- package/dist/esm/core/authService/emailOtpRegistrationEnrollment.js +0 -175
- package/dist/esm/core/authService/emailOtpUnlock.js +0 -264
- package/dist/esm/core/authService/googleEmailOtpOperations.js +0 -141
- package/dist/esm/core/authService/googleEmailOtpRegistration.js +0 -674
- package/dist/esm/core/authService/identity.js +0 -57
- package/dist/esm/core/authService/identityOperations.js +0 -32
- package/dist/esm/core/authService/nearAccountOperations.js +0 -229
- package/dist/esm/core/authService/nearPublicKeyMetadata.js +0 -127
- package/dist/esm/core/authService/oidcVerification.js +0 -261
- package/dist/esm/core/authService/registrationThresholdHelpers.js +0 -30
- package/dist/esm/core/authService/runtime.js +0 -45
- package/dist/esm/core/authService/storeRegistry.js +0 -102
- package/dist/esm/core/authService/thresholdStoreSummary.js +0 -32
- package/dist/esm/core/authService/webauthnAuthority.js +0 -17
- package/dist/esm/core/defaultConfigsServer.js +0 -9
- package/dist/esm/core/hostedAccountIds.js +0 -225
- package/dist/esm/core/routerAbSigning/createRouterAbSigningRuntimes.js +0 -84
- package/dist/esm/core/signingLanes/LaneAggregateRevocationApplicationService.js +0 -86
- package/dist/esm/core/signingLanes/LaneEnrollmentActivation.js +0 -324
- package/dist/esm/core/signingLanes/LaneEnrollmentRevocation.js +0 -173
- package/dist/esm/core/signingLanes/LaneLifecycleApplicationService.js +0 -198
- package/dist/esm/core/signingLanes/ecdsaServerRetirement.js +0 -73
- package/dist/esm/core/signingLanes/ed25519ServerRetirement.js +0 -68
- package/dist/esm/core/signingLanes/signingWorkerLaneMaterialIdentity.js +0 -0
- package/dist/esm/core/storeBackends.js +0 -208
- package/dist/esm/core/utils.js +0 -14
- package/dist/esm/core/webAuthnStoreBackends.js +0 -198
- package/dist/esm/router/cloudflare/d1/near/d1NearPublicKeyStore.js +0 -56
- package/dist/esm/router/cloudflare/d1/signingLanes/d1EcdsaLanePrivateBindingResolver.js +0 -10
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneAggregateRevocationApplicationService.js +0 -22
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneEffectJournalStore.js +0 -166
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneEnrollmentGateway.js +0 -38
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneLifecycleApplicationService.js +0 -20
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneLifecycleStore.js +0 -1459
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneLockStore.js +0 -114
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneProtocolCommitter.js +0 -16
- package/dist/esm/router/cloudflare/d1/signingLanes/d1LaneRecords.js +0 -171
- package/dist/esm/router/cloudflare/d1/signingLanes/index.js +0 -10
- package/dist/esm/router/cloudflare/durableObjects/thresholdStore.js +0 -404
- package/dist/esm/router/cloudflare/signingLanes/cloudflareLaneCurveExecution.js +0 -596
- package/dist/esm/router/cloudflare/signingLanes/cloudflareLaneProtocolCommitter.js +0 -273
- package/dist/esm/router/cloudflare/signingLanes/index.js +0 -4
- package/dist/esm/router/cloudflare/signingLanes/linkedDeviceEd25519CeremonyBinding.js +0 -32
- package/dist/esm/router/transport/fetch/routes/nearPublicKeys.js +0 -39
- package/dist/esm/shared-ts/src/signing-lanes/rotation.js +0 -8
- package/dist/esm/shared-ts/src/signing-lanes/rotationDigests.js +0 -358
- package/dist/esm/shared-ts/src/signing-lanes/rotationLifecycle.js +0 -313
- package/dist/esm/shared-ts/src/signing-lanes/rotationParsers.js +0 -532
- package/dist/esm/shared-ts/src/signing-lanes/rotationProtocolParsers.js +0 -323
- package/dist/esm/shared-ts/src/signing-lanes/rotationWireFields.js +0 -59
- package/dist/esm/wasm/router_ab_ecdsa_signing_worker/pkg/router_ab_ecdsa_signing_worker_bg.wasm +0 -0
- package/dist/types/shared-ts/src/signing-lanes/participantDigest.typecheck.d.ts +0 -2
- package/dist/types/shared-ts/src/signing-lanes/rotation.typecheck.d.ts +0 -2
- package/dist/types/shared-ts/src/signing-lanes/rotationDigests.d.ts +0 -13
- package/dist/types/shared-ts/src/signing-lanes/rotationLifecycle.d.ts +0 -78
- package/dist/types/shared-ts/src/signing-lanes/rotationParsers.d.ts +0 -27
- package/dist/types/shared-ts/src/signing-lanes/rotationProtocolParsers.d.ts +0 -6
- package/dist/types/shared-ts/src/signing-lanes/rotationWireFields.d.ts +0 -20
- package/dist/types/shared-ts/src/wallet-recovery/recoveryCodeAttempt.d.ts +0 -59
- package/dist/types/wallet-server/src/core/AuthService.d.ts +0 -3
- package/dist/types/wallet-server/src/core/NearPublicKeyStore.d.ts +0 -48
- package/dist/types/wallet-server/src/core/ThresholdService/stores/CloudflareDurableObjectStore.d.ts +0 -21
- package/dist/types/wallet-server/src/core/ThresholdService/stores/KeyStore.d.ts +0 -40
- package/dist/types/wallet-server/src/core/ThresholdService/stores/SessionStore.d.ts +0 -98
- package/dist/types/wallet-server/src/core/ThresholdService/stores/StoreConfig.d.ts +0 -4
- package/dist/types/wallet-server/src/core/ThresholdService/stores/ThresholdStoreConfig.typecheck.d.ts +0 -2
- package/dist/types/wallet-server/src/core/authService/AuthService.d.ts +0 -490
- package/dist/types/wallet-server/src/core/authService/bytes.d.ts +0 -4
- package/dist/types/wallet-server/src/core/authService/configValues.d.ts +0 -7
- package/dist/types/wallet-server/src/core/authService/emailOtpChallengeOperations.d.ts +0 -109
- package/dist/types/wallet-server/src/core/authService/emailOtpChallengeProof.d.ts +0 -169
- package/dist/types/wallet-server/src/core/authService/emailOtpChallengeVerification.d.ts +0 -47
- package/dist/types/wallet-server/src/core/authService/emailOtpChallenges.d.ts +0 -94
- package/dist/types/wallet-server/src/core/authService/emailOtpDelivery.d.ts +0 -66
- package/dist/types/wallet-server/src/core/authService/emailOtpGrant.d.ts +0 -43
- package/dist/types/wallet-server/src/core/authService/emailOtpRegistrationEnrollment.d.ts +0 -49
- package/dist/types/wallet-server/src/core/authService/emailOtpUnlock.d.ts +0 -71
- package/dist/types/wallet-server/src/core/authService/googleEmailOtpOperations.d.ts +0 -126
- package/dist/types/wallet-server/src/core/authService/googleEmailOtpRegistration.d.ts +0 -169
- package/dist/types/wallet-server/src/core/authService/identity.d.ts +0 -25
- package/dist/types/wallet-server/src/core/authService/identityOperations.d.ts +0 -19
- package/dist/types/wallet-server/src/core/authService/nearAccountOperations.d.ts +0 -55
- package/dist/types/wallet-server/src/core/authService/nearPublicKeyMetadata.d.ts +0 -44
- package/dist/types/wallet-server/src/core/authService/oidcVerification.d.ts +0 -66
- package/dist/types/wallet-server/src/core/authService/registrationThresholdHelpers.d.ts +0 -11
- package/dist/types/wallet-server/src/core/authService/runtime.d.ts +0 -20
- package/dist/types/wallet-server/src/core/authService/storeRegistry.d.ts +0 -53
- package/dist/types/wallet-server/src/core/authService/thresholdStoreSummary.d.ts +0 -3
- package/dist/types/wallet-server/src/core/authService/webauthnAuthority.d.ts +0 -5
- package/dist/types/wallet-server/src/core/defaultConfigsServer.d.ts +0 -5
- package/dist/types/wallet-server/src/core/hostedAccountIds.d.ts +0 -16
- package/dist/types/wallet-server/src/core/routerAbSigning/createRouterAbSigningRuntimes.d.ts +0 -16
- package/dist/types/wallet-server/src/core/signingLanes/LaneAggregateRevocationApplicationService.d.ts +0 -36
- package/dist/types/wallet-server/src/core/signingLanes/LaneEffectJournalStore.d.ts +0 -62
- package/dist/types/wallet-server/src/core/signingLanes/LaneEnrollmentActivation.d.ts +0 -13
- package/dist/types/wallet-server/src/core/signingLanes/LaneEnrollmentRevocation.d.ts +0 -24
- package/dist/types/wallet-server/src/core/signingLanes/LaneLifecycleApplicationService.d.ts +0 -141
- package/dist/types/wallet-server/src/core/signingLanes/LaneLifecycleStore.d.ts +0 -228
- package/dist/types/wallet-server/src/core/signingLanes/ecdsaServerRetirement.d.ts +0 -58
- package/dist/types/wallet-server/src/core/signingLanes/ed25519ServerRetirement.d.ts +0 -30
- package/dist/types/wallet-server/src/core/signingLanes/signingWorkerLaneMaterialIdentity.d.ts +0 -21
- package/dist/types/wallet-server/src/core/storeBackends.d.ts +0 -83
- package/dist/types/wallet-server/src/core/utils.d.ts +0 -3
- package/dist/types/wallet-server/src/core/webAuthnStoreBackends.d.ts +0 -96
- package/dist/types/wallet-server/src/router/cloudflare/d1/near/d1NearPublicKeyStore.d.ts +0 -29
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1EcdsaLanePrivateBindingResolver.d.ts +0 -4
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneAggregateRevocationApplicationService.d.ts +0 -4
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneEffectJournalStore.d.ts +0 -24
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneEnrollmentGateway.d.ts +0 -20
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneLifecycleApplicationService.d.ts +0 -13
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneLifecycleStore.d.ts +0 -51
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneLockStore.d.ts +0 -28
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneProtocolCommitter.d.ts +0 -5
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/d1LaneRecords.d.ts +0 -107
- package/dist/types/wallet-server/src/router/cloudflare/d1/signingLanes/index.d.ts +0 -10
- package/dist/types/wallet-server/src/router/cloudflare/durableObjects/thresholdStore.d.ts +0 -18
- package/dist/types/wallet-server/src/router/cloudflare/signingLanes/cloudflareLaneCurveExecution.d.ts +0 -217
- package/dist/types/wallet-server/src/router/cloudflare/signingLanes/cloudflareLaneProtocolCommitter.d.ts +0 -73
- package/dist/types/wallet-server/src/router/cloudflare/signingLanes/index.d.ts +0 -4
- package/dist/types/wallet-server/src/router/cloudflare/signingLanes/linkedDeviceEd25519CeremonyBinding.d.ts +0 -6
- package/dist/types/wallet-server/src/router/transport/fetch/routes/nearPublicKeys.d.ts +0 -3
- /package/dist/esm/{core/signingLanes/LaneEffectJournalStore.js → authorization/recoveryRouting.js} +0 -0
- /package/dist/esm/{core/signingLanes/LaneLifecycleStore.js → authorization/sessionRouting.js} +0 -0
|
@@ -1,1459 +0,0 @@
|
|
|
1
|
-
import { mpcMaterialActivationRefsEqual } from "../../../../shared-ts/src/utils/domainIds.js";
|
|
2
|
-
import { base64UrlEncode } from "../../../../shared-ts/src/utils/base64.js";
|
|
3
|
-
import { sha256Bytes } from "../../../../shared-ts/src/utils/digests.js";
|
|
4
|
-
import { d1ChangedRows } from "../../../../storage/d1Sql.js";
|
|
5
|
-
import { buildLaneProductEpochPendingVisibilityV1, buildLaneProductEpochRevokedV1, parseAggregateLaneActivationReceiptV1, parseAggregateLaneRevocationReceiptV1, parseCompleteSigningLaneRevocationV1, parseLaneEnrollmentManifestV1, parseLaneHolderDeliveryReceiptV1, parseLaneProductEpochRecordV1, parseLaneProtocolCommitReceiptV1, parseLaneRefreshPredecessorRetirementV1, parseLaneServerActivationReceiptV1, parseLaneServerRetirementReceiptV1, parseRevokeSigningLaneV1 } from "../../../../shared-ts/src/signing-lanes/rotationParsers.js";
|
|
6
|
-
import { computeLaneParticipantSetBindingDigestV1 } from "../../../../shared-ts/src/signing-lanes/participantDigest.js";
|
|
7
|
-
import { computeAggregateLaneActivationReceiptDigestV1, computeAggregateLaneRevocationReceiptDigestV1, computeEcdsaServerRetirementReceiptDigestV1, computeEd25519ServerRetirementReceiptDigestV1, computeLaneEnrollmentManifestDigestV1, computeRevokeSigningLaneDigestV1, encodeLaneHolderDeliveryReceiptV1, encodeLaneProtocolCommitReceiptV1, encodeLaneServerActivationReceiptV1 } from "../../../../shared-ts/src/signing-lanes/rotationDigests.js";
|
|
8
|
-
import { activateLaneProductEpochV1, beginLaneProductEpochRevocationV1, completeLaneProductEpochRevocationV1, retireFencedLaneProductEpochV1, transitionLaneEnrollmentLifecycleV1 } from "../../../../shared-ts/src/signing-lanes/rotationLifecycle.js";
|
|
9
|
-
import { LANE_CAS_GUARD_SQL, assertD1Success, digestLaneEnrollmentRevocationCommand, equalLaneRecords, firstBatchResult, parseEnrollmentRow, parseJsonRecord, parseProductEpochRow, parseProtocolRow, parseRequiredString, parseVersion, requireD1LaneStoreOptions, scopeValues } from "./d1LaneRecords.js";
|
|
10
|
-
//#region src/router/cloudflare/d1/signingLanes/d1LaneLifecycleStore.ts
|
|
11
|
-
const ENROLLMENT_TABLE = "lane_enrollments";
|
|
12
|
-
const OPERATION_TABLE = "lane_protocol_operations";
|
|
13
|
-
const PRODUCT_TABLE = "lane_product_epochs";
|
|
14
|
-
const RECEIPT_TABLE = "lane_receipts";
|
|
15
|
-
var CloudflareD1LaneLifecycleStore = class {
|
|
16
|
-
constructor(options) {
|
|
17
|
-
const normalized = requireD1LaneStoreOptions(options);
|
|
18
|
-
this.database = normalized.database;
|
|
19
|
-
this.scope = normalized.scope;
|
|
20
|
-
this.now = normalized.now;
|
|
21
|
-
}
|
|
22
|
-
async getEnrollment(enrollmentId) {
|
|
23
|
-
const row = await this.database.prepare(`SELECT enrollment_id, wallet_id, manifest_digest_b64u, manifest_json,
|
|
24
|
-
lifecycle_json, version, command_digest_b64u, created_at_ms, updated_at_ms
|
|
25
|
-
FROM ${ENROLLMENT_TABLE}
|
|
26
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
27
|
-
AND enrollment_id = ?5`).bind(...scopeValues(this.scope), String(enrollmentId)).first();
|
|
28
|
-
if (!row) return null;
|
|
29
|
-
const parsed = parseEnrollmentRow(row);
|
|
30
|
-
return {
|
|
31
|
-
version: parsed.version,
|
|
32
|
-
commandDigestB64u: parsed.commandDigestB64u,
|
|
33
|
-
value: {
|
|
34
|
-
manifest: parsed.manifest,
|
|
35
|
-
lifecycle: parsed.lifecycle
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
async getProtocol(operationId) {
|
|
40
|
-
const row = await this.database.prepare(`SELECT operation_id, enrollment_id, wallet_id, wallet_key_id,
|
|
41
|
-
source_lane_id, source_lane_share_epoch, source_revocation_epoch,
|
|
42
|
-
target_lane_id, target_lane_share_epoch, target_material_activation_id,
|
|
43
|
-
job_json, lifecycle_json, version, command_digest_b64u,
|
|
44
|
-
created_at_ms, updated_at_ms
|
|
45
|
-
FROM ${OPERATION_TABLE}
|
|
46
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
47
|
-
AND operation_id = ?5`).bind(...scopeValues(this.scope), String(operationId)).first();
|
|
48
|
-
if (!row) return null;
|
|
49
|
-
const parsed = parseProtocolRow(row);
|
|
50
|
-
return {
|
|
51
|
-
version: parsed.version,
|
|
52
|
-
commandDigestB64u: parsed.commandDigestB64u,
|
|
53
|
-
value: parsed.record
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Reads the committed protocol receipt only after verifying its persisted
|
|
58
|
-
* digest, receipt identity, and active protocol lifecycle binding.
|
|
59
|
-
*/
|
|
60
|
-
async getProtocolCommitReceipt(operationId) {
|
|
61
|
-
const row = await this.database.prepare(`SELECT receipt_id, receipt_digest_b64u, receipt_json
|
|
62
|
-
FROM ${RECEIPT_TABLE}
|
|
63
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
64
|
-
AND operation_id = ?5 AND receipt_kind = 'lane_protocol_commit'`).bind(...scopeValues(this.scope), String(operationId)).first();
|
|
65
|
-
if (!row) return null;
|
|
66
|
-
const protocol = await this.getProtocol(operationId);
|
|
67
|
-
if (!protocol || protocol.value.lifecycle.state !== "active") throw new Error("lane protocol commit receipt has no active protocol lifecycle");
|
|
68
|
-
if (parseRequiredString(row.receipt_id, "lane protocol commit receipt id") !== `${String(operationId)}:lane_protocol_commit`) throw new Error("lane protocol commit receipt id is invalid");
|
|
69
|
-
const receipt = parseLaneProtocolCommitReceiptV1(parseJsonRecord(row.receipt_json, "lane protocol commit receipt"));
|
|
70
|
-
assertProtocolCommitReceiptIdentity(protocol.value, receipt);
|
|
71
|
-
const digest = await exactReceiptDigest("lane_protocol_commit", receipt);
|
|
72
|
-
if (parseRequiredString(row.receipt_digest_b64u, "lane protocol commit receipt digest") !== digest) throw new Error("lane protocol commit receipt digest is invalid");
|
|
73
|
-
if (protocol.value.lifecycle.protocolCommitReceiptDigestB64u !== digest) throw new Error("lane protocol commit receipt differs from its protocol lifecycle");
|
|
74
|
-
return receipt;
|
|
75
|
-
}
|
|
76
|
-
async putEnrollmentAdmission(input) {
|
|
77
|
-
const manifest = parseLaneEnrollmentManifestV1(input.manifest);
|
|
78
|
-
if (manifest.orderedChildren.length !== input.children.length) throw new Error("lane enrollment manifest and protocol child count differ");
|
|
79
|
-
validateChildrenAgainstManifest(manifest, input.children);
|
|
80
|
-
const existing = await this.getEnrollment(manifest.enrollmentId);
|
|
81
|
-
if (existing) {
|
|
82
|
-
if (existing.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(existing.value.manifest, manifest) && equalLaneRecords(existing.value.lifecycle, input.lifecycle) && await admissionChildrenMatch(this, input.children)) return {
|
|
83
|
-
outcome: "replayed",
|
|
84
|
-
version: existing.version,
|
|
85
|
-
commandDigestB64u: existing.commandDigestB64u,
|
|
86
|
-
value: existing.value
|
|
87
|
-
};
|
|
88
|
-
return {
|
|
89
|
-
outcome: "conflict",
|
|
90
|
-
expectedVersion: null,
|
|
91
|
-
actualVersion: existing.version,
|
|
92
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
93
|
-
storedCommandDigestB64u: existing.commandDigestB64u
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
const now = this.now();
|
|
97
|
-
const manifestJson = JSON.stringify(manifest);
|
|
98
|
-
const lifecycleJson = JSON.stringify(input.lifecycle);
|
|
99
|
-
const statementValues = scopeValues(this.scope);
|
|
100
|
-
const statements = [this.database.prepare(`INSERT INTO ${ENROLLMENT_TABLE} (
|
|
101
|
-
namespace, org_id, project_id, env_id, enrollment_id, wallet_id,
|
|
102
|
-
manifest_digest_b64u, manifest_json, lifecycle_json, version,
|
|
103
|
-
command_digest_b64u, created_at_ms, updated_at_ms
|
|
104
|
-
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, 1, ?10, ?11, ?11)`).bind(...statementValues, String(manifest.enrollmentId), String(manifest.walletId), input.commandDigestB64u, manifestJson, lifecycleJson, input.commandDigestB64u, now), this.database.prepare(LANE_CAS_GUARD_SQL)];
|
|
105
|
-
for (const child of input.children) {
|
|
106
|
-
statements.push(this.protocolInsertStatement(child, input.commandDigestB64u, now));
|
|
107
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
108
|
-
}
|
|
109
|
-
try {
|
|
110
|
-
const results = await this.database.batch(statements);
|
|
111
|
-
for (let index = 0; index < results.length; index += 1) assertD1Success(firstBatchResult(results, index), `lane enrollment admission statement ${index}`);
|
|
112
|
-
} catch (error) {
|
|
113
|
-
const raced = await this.getEnrollment(manifest.enrollmentId);
|
|
114
|
-
if (raced && raced.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(raced.value.manifest, manifest)) return {
|
|
115
|
-
outcome: "replayed",
|
|
116
|
-
version: raced.version,
|
|
117
|
-
commandDigestB64u: raced.commandDigestB64u,
|
|
118
|
-
value: raced.value
|
|
119
|
-
};
|
|
120
|
-
if (raced) return {
|
|
121
|
-
outcome: "conflict",
|
|
122
|
-
expectedVersion: null,
|
|
123
|
-
actualVersion: raced.version,
|
|
124
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
125
|
-
storedCommandDigestB64u: raced.commandDigestB64u
|
|
126
|
-
};
|
|
127
|
-
for (const child of input.children) {
|
|
128
|
-
const racedChild = await this.getProtocol(child.job.operationId);
|
|
129
|
-
if (racedChild) return {
|
|
130
|
-
outcome: "conflict",
|
|
131
|
-
expectedVersion: null,
|
|
132
|
-
actualVersion: racedChild.version,
|
|
133
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
134
|
-
storedCommandDigestB64u: racedChild.commandDigestB64u
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
throw error;
|
|
138
|
-
}
|
|
139
|
-
return {
|
|
140
|
-
outcome: "applied",
|
|
141
|
-
version: 1,
|
|
142
|
-
commandDigestB64u: input.commandDigestB64u,
|
|
143
|
-
value: {
|
|
144
|
-
manifest,
|
|
145
|
-
lifecycle: input.lifecycle
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
async putProtocolAdmission(input) {
|
|
150
|
-
const record = input.record;
|
|
151
|
-
const existing = await this.getProtocol(record.job.operationId);
|
|
152
|
-
if (existing) {
|
|
153
|
-
if (existing.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(existing.value, record)) return {
|
|
154
|
-
outcome: "replayed",
|
|
155
|
-
version: existing.version,
|
|
156
|
-
commandDigestB64u: existing.commandDigestB64u,
|
|
157
|
-
value: existing.value
|
|
158
|
-
};
|
|
159
|
-
return {
|
|
160
|
-
outcome: "conflict",
|
|
161
|
-
expectedVersion: null,
|
|
162
|
-
actualVersion: existing.version,
|
|
163
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
164
|
-
storedCommandDigestB64u: existing.commandDigestB64u
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
const now = this.now();
|
|
168
|
-
const statements = [this.protocolInsertStatement(record, input.commandDigestB64u, now), this.database.prepare(LANE_CAS_GUARD_SQL)];
|
|
169
|
-
try {
|
|
170
|
-
assertD1Success(firstBatchResult(await this.database.batch(statements), 0), "lane protocol admission");
|
|
171
|
-
} catch (error) {
|
|
172
|
-
const raced = await this.getProtocol(record.job.operationId);
|
|
173
|
-
if (raced && raced.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(raced.value, record)) return {
|
|
174
|
-
outcome: "replayed",
|
|
175
|
-
version: raced.version,
|
|
176
|
-
commandDigestB64u: raced.commandDigestB64u,
|
|
177
|
-
value: raced.value
|
|
178
|
-
};
|
|
179
|
-
if (raced) return {
|
|
180
|
-
outcome: "conflict",
|
|
181
|
-
expectedVersion: null,
|
|
182
|
-
actualVersion: raced.version,
|
|
183
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
184
|
-
storedCommandDigestB64u: raced.commandDigestB64u
|
|
185
|
-
};
|
|
186
|
-
throw error;
|
|
187
|
-
}
|
|
188
|
-
return {
|
|
189
|
-
outcome: "applied",
|
|
190
|
-
version: 1,
|
|
191
|
-
commandDigestB64u: input.commandDigestB64u,
|
|
192
|
-
value: record
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
async compareAndSetProtocolLifecycle(input) {
|
|
196
|
-
const current = await this.getProtocol(input.operationId);
|
|
197
|
-
if (!current) return {
|
|
198
|
-
outcome: "conflict",
|
|
199
|
-
expectedVersion: input.expectedVersion,
|
|
200
|
-
actualVersion: 0,
|
|
201
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
202
|
-
storedCommandDigestB64u: ""
|
|
203
|
-
};
|
|
204
|
-
if (current.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(current.value.lifecycle, input.lifecycle)) return {
|
|
205
|
-
outcome: "replayed",
|
|
206
|
-
version: current.version,
|
|
207
|
-
commandDigestB64u: current.commandDigestB64u,
|
|
208
|
-
record: current.value
|
|
209
|
-
};
|
|
210
|
-
if (!await this.updateProtocolLifecycle(input)) {
|
|
211
|
-
const raced = await this.getProtocol(input.operationId);
|
|
212
|
-
if (!raced) return {
|
|
213
|
-
outcome: "conflict",
|
|
214
|
-
expectedVersion: input.expectedVersion,
|
|
215
|
-
actualVersion: 0,
|
|
216
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
217
|
-
storedCommandDigestB64u: ""
|
|
218
|
-
};
|
|
219
|
-
if (raced.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(raced.value.lifecycle, input.lifecycle)) return {
|
|
220
|
-
outcome: "replayed",
|
|
221
|
-
version: raced.version,
|
|
222
|
-
commandDigestB64u: raced.commandDigestB64u,
|
|
223
|
-
record: raced.value
|
|
224
|
-
};
|
|
225
|
-
return {
|
|
226
|
-
outcome: "conflict",
|
|
227
|
-
expectedVersion: input.expectedVersion,
|
|
228
|
-
actualVersion: raced.version,
|
|
229
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
230
|
-
storedCommandDigestB64u: raced.commandDigestB64u
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
const result = await this.getProtocol(input.operationId);
|
|
234
|
-
if (!result) throw new Error("lane protocol disappeared after CAS");
|
|
235
|
-
return {
|
|
236
|
-
outcome: "applied",
|
|
237
|
-
version: result.version,
|
|
238
|
-
commandDigestB64u: result.commandDigestB64u,
|
|
239
|
-
record: result.value
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
async compareAndSetEnrollmentLifecycle(input) {
|
|
243
|
-
const current = await this.getEnrollment(input.enrollmentId);
|
|
244
|
-
if (!current) return {
|
|
245
|
-
outcome: "conflict",
|
|
246
|
-
expectedVersion: input.expectedVersion,
|
|
247
|
-
actualVersion: 0,
|
|
248
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
249
|
-
storedCommandDigestB64u: ""
|
|
250
|
-
};
|
|
251
|
-
if (current.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(current.value.lifecycle, input.lifecycle)) return {
|
|
252
|
-
outcome: "replayed",
|
|
253
|
-
version: current.version,
|
|
254
|
-
commandDigestB64u: current.commandDigestB64u,
|
|
255
|
-
value: current.value
|
|
256
|
-
};
|
|
257
|
-
if (!await this.updateEnrollmentLifecycle(input)) {
|
|
258
|
-
const raced = await this.getEnrollment(input.enrollmentId);
|
|
259
|
-
if (!raced) return {
|
|
260
|
-
outcome: "conflict",
|
|
261
|
-
expectedVersion: input.expectedVersion,
|
|
262
|
-
actualVersion: 0,
|
|
263
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
264
|
-
storedCommandDigestB64u: ""
|
|
265
|
-
};
|
|
266
|
-
if (raced.commandDigestB64u === input.commandDigestB64u && equalLaneRecords(raced.value.lifecycle, input.lifecycle)) return {
|
|
267
|
-
outcome: "replayed",
|
|
268
|
-
version: raced.version,
|
|
269
|
-
commandDigestB64u: raced.commandDigestB64u,
|
|
270
|
-
value: raced.value
|
|
271
|
-
};
|
|
272
|
-
return {
|
|
273
|
-
outcome: "conflict",
|
|
274
|
-
expectedVersion: input.expectedVersion,
|
|
275
|
-
actualVersion: raced.version,
|
|
276
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
277
|
-
storedCommandDigestB64u: raced.commandDigestB64u
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
const result = await this.getEnrollment(input.enrollmentId);
|
|
281
|
-
if (!result) throw new Error("lane enrollment disappeared after CAS");
|
|
282
|
-
return {
|
|
283
|
-
outcome: "applied",
|
|
284
|
-
version: result.version,
|
|
285
|
-
commandDigestB64u: result.commandDigestB64u,
|
|
286
|
-
value: result.value
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
async putProtocolCommitReceipt(receipt, commandDigestB64u) {
|
|
290
|
-
const protocol = await this.getProtocol(receipt.operationId);
|
|
291
|
-
if (!protocol) throw new Error("protocol commit receipt names an unknown operation");
|
|
292
|
-
assertProtocolCommitReceiptIdentity(protocol.value, receipt);
|
|
293
|
-
if (protocol.value.lifecycle.state !== "awaiting_protocol_commitment" && protocol.value.lifecycle.state !== "committed_awaiting_holder_delivery" && protocol.value.lifecycle.state !== "awaiting_server_activation" && protocol.value.lifecycle.state !== "ready_for_parent_visibility" && protocol.value.lifecycle.state !== "active") throw new Error("protocol commit receipt is not valid for this lifecycle");
|
|
294
|
-
return await this.putReceipt(receipt.operationId, receipt.enrollmentId, "lane_protocol_commit", receipt, commandDigestB64u);
|
|
295
|
-
}
|
|
296
|
-
async putHolderDeliveryReceipt(receipt, commandDigestB64u) {
|
|
297
|
-
const protocol = await this.getProtocol(receipt.operationId);
|
|
298
|
-
if (!protocol) throw new Error("holder delivery receipt names an unknown operation");
|
|
299
|
-
const commitReceipt = await this.readReceipt(receipt.operationId, "lane_protocol_commit");
|
|
300
|
-
if (commitReceipt?.kind !== "lane_protocol_commit_receipt_v1") throw new Error("holder delivery requires its committed protocol receipt");
|
|
301
|
-
assertHolderDeliveryReceiptIdentity(protocol.value, receipt, commitReceipt);
|
|
302
|
-
return await this.putReceipt(receipt.operationId, receipt.enrollmentId, "lane_holder_delivery", receipt, commandDigestB64u);
|
|
303
|
-
}
|
|
304
|
-
async putServerActivationReceipt(receipt, commandDigestB64u) {
|
|
305
|
-
const protocol = await this.getProtocol(receipt.operationId);
|
|
306
|
-
if (!protocol) throw new Error("server activation receipt names an unknown operation");
|
|
307
|
-
const commitReceipt = await this.readReceipt(receipt.operationId, "lane_protocol_commit");
|
|
308
|
-
const holderReceipt = await this.readReceipt(receipt.operationId, "lane_holder_delivery");
|
|
309
|
-
if (commitReceipt?.kind !== "lane_protocol_commit_receipt_v1" || holderReceipt?.kind !== "lane_holder_delivery_receipt_v1") throw new Error("server activation requires protocol and holder receipts");
|
|
310
|
-
assertServerActivationReceiptIdentity(protocol.value, receipt, commitReceipt, holderReceipt);
|
|
311
|
-
const commitReceiptDigest = await exactReceiptDigest("lane_protocol_commit", commitReceipt);
|
|
312
|
-
const holderReceiptDigest = await exactReceiptDigest("lane_holder_delivery", holderReceipt);
|
|
313
|
-
if (protocol.value.lifecycle.state !== "awaiting_server_activation" && protocol.value.lifecycle.state !== "ready_for_parent_visibility" && protocol.value.lifecycle.state !== "active" || protocol.value.lifecycle.protocolCommitReceiptDigestB64u !== commitReceiptDigest || protocol.value.lifecycle.holderDeliveryReceiptDigestB64u !== holderReceiptDigest) throw new Error("server activation receipts do not match the committed protocol lifecycle");
|
|
314
|
-
const enrollment = await this.getEnrollment(receipt.enrollmentId);
|
|
315
|
-
if (!enrollment) throw new Error("server activation receipt names an unknown enrollment");
|
|
316
|
-
const pending = await buildPendingProductEpoch({
|
|
317
|
-
protocol: protocol.value,
|
|
318
|
-
protocolReceipt: commitReceipt,
|
|
319
|
-
holderReceipt,
|
|
320
|
-
serverReceipt: receipt,
|
|
321
|
-
manifestDigestB64u: await computeLaneEnrollmentManifestDigestV1(enrollment.value.manifest)
|
|
322
|
-
});
|
|
323
|
-
const result = await this.putReceipt(receipt.operationId, receipt.enrollmentId, "lane_server_activation", receipt, commandDigestB64u);
|
|
324
|
-
if ((await this.putProductEpochPending(pending, commandDigestB64u)).outcome === "conflict") throw new Error("server activation receipt conflicts with the stored lane product epoch");
|
|
325
|
-
return result;
|
|
326
|
-
}
|
|
327
|
-
async putProductEpochPending(productEpoch, commandDigestB64u) {
|
|
328
|
-
if (await this.getProductEpoch({
|
|
329
|
-
walletId: productEpoch.walletId,
|
|
330
|
-
walletKeyId: productEpoch.walletKeyId,
|
|
331
|
-
laneId: productEpoch.laneId,
|
|
332
|
-
laneShareEpoch: productEpoch.laneShareEpoch
|
|
333
|
-
})) {
|
|
334
|
-
const stored = await this.getProductEpochStored({
|
|
335
|
-
walletId: productEpoch.walletId,
|
|
336
|
-
walletKeyId: productEpoch.walletKeyId,
|
|
337
|
-
laneId: productEpoch.laneId,
|
|
338
|
-
laneShareEpoch: productEpoch.laneShareEpoch
|
|
339
|
-
});
|
|
340
|
-
if (stored && stored.commandDigestB64u === commandDigestB64u && equalLaneRecords(stored.product, productEpoch)) return {
|
|
341
|
-
outcome: "replayed",
|
|
342
|
-
version: stored.version,
|
|
343
|
-
commandDigestB64u: stored.commandDigestB64u,
|
|
344
|
-
value: stored.product
|
|
345
|
-
};
|
|
346
|
-
return {
|
|
347
|
-
outcome: "conflict",
|
|
348
|
-
expectedVersion: null,
|
|
349
|
-
actualVersion: stored?.version ?? 1,
|
|
350
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
351
|
-
storedCommandDigestB64u: stored?.commandDigestB64u ?? ""
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
const now = this.now();
|
|
355
|
-
const values = scopeValues(this.scope);
|
|
356
|
-
const insert = this.database.prepare(`INSERT INTO ${PRODUCT_TABLE} (
|
|
357
|
-
namespace, org_id, project_id, env_id, wallet_id, wallet_key_id,
|
|
358
|
-
lane_id, lane_share_epoch, enrollment_id, operation_id,
|
|
359
|
-
target_material_activation_id, material_activation_json,
|
|
360
|
-
holder_participant_json, signing_worker_participant_json,
|
|
361
|
-
participant_set_binding_digest_b64u, revocation_epoch,
|
|
362
|
-
lane_kind, key_family, public_identity_digest_b64u, state, product_json,
|
|
363
|
-
version, command_digest_b64u, created_at_ms, updated_at_ms
|
|
364
|
-
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, 1, ?22, ?23, ?23)`).bind(...values, String(productEpoch.walletId), String(productEpoch.walletKeyId), String(productEpoch.laneId), String(productEpoch.laneShareEpoch), String(productEpoch.enrollmentId), String(productEpoch.operationId), String(productEpoch.targetMaterialActivationId), JSON.stringify(productEpoch.materialActivation), JSON.stringify(productEpoch.holderParticipant), JSON.stringify(productEpoch.signingWorkerParticipant), productEpoch.participantSetBindingDigestB64u, productEpoch.revocationEpoch, productEpoch.laneKind, productEpoch.keyFamily, productEpoch.publicIdentityDigestB64u, productEpoch.state, JSON.stringify(productEpoch), commandDigestB64u, now);
|
|
365
|
-
try {
|
|
366
|
-
assertD1Success(firstBatchResult(await this.database.batch([insert, this.database.prepare(LANE_CAS_GUARD_SQL)]), 0), "lane product epoch admission");
|
|
367
|
-
} catch (error) {
|
|
368
|
-
const raced = await this.getProductEpochStored({
|
|
369
|
-
walletId: productEpoch.walletId,
|
|
370
|
-
walletKeyId: productEpoch.walletKeyId,
|
|
371
|
-
laneId: productEpoch.laneId,
|
|
372
|
-
laneShareEpoch: productEpoch.laneShareEpoch
|
|
373
|
-
});
|
|
374
|
-
if (raced && raced.commandDigestB64u === commandDigestB64u && equalLaneRecords(raced.product, productEpoch)) return {
|
|
375
|
-
outcome: "replayed",
|
|
376
|
-
version: raced.version,
|
|
377
|
-
commandDigestB64u: raced.commandDigestB64u,
|
|
378
|
-
value: raced.product
|
|
379
|
-
};
|
|
380
|
-
if (raced) return {
|
|
381
|
-
outcome: "conflict",
|
|
382
|
-
expectedVersion: null,
|
|
383
|
-
actualVersion: raced.version,
|
|
384
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
385
|
-
storedCommandDigestB64u: raced.commandDigestB64u
|
|
386
|
-
};
|
|
387
|
-
throw error;
|
|
388
|
-
}
|
|
389
|
-
return {
|
|
390
|
-
outcome: "applied",
|
|
391
|
-
version: 1,
|
|
392
|
-
commandDigestB64u,
|
|
393
|
-
value: productEpoch
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
async getProductEpoch(lookup) {
|
|
397
|
-
return (await this.getProductEpochStored(lookup))?.product ?? null;
|
|
398
|
-
}
|
|
399
|
-
async getProductEpochStored(lookup) {
|
|
400
|
-
const row = await this.database.prepare(`SELECT product_json, version, command_digest_b64u
|
|
401
|
-
FROM ${PRODUCT_TABLE}
|
|
402
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
403
|
-
AND wallet_id = ?5 AND wallet_key_id = ?6 AND lane_id = ?7 AND lane_share_epoch = ?8`).bind(...scopeValues(this.scope), String(lookup.walletId), String(lookup.walletKeyId), String(lookup.laneId), String(lookup.laneShareEpoch)).first();
|
|
404
|
-
if (!row) return null;
|
|
405
|
-
return {
|
|
406
|
-
product: parseProductEpochRow(row),
|
|
407
|
-
version: parseVersion(row.version, "lane product epoch version"),
|
|
408
|
-
commandDigestB64u: parseRequiredString(row.command_digest_b64u, "lane product epoch command digest")
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
async getActiveProductEpoch(lookup) {
|
|
412
|
-
const value = await this.getProductEpoch(lookup);
|
|
413
|
-
if (!value || value.state !== "active") return null;
|
|
414
|
-
if (!mpcMaterialActivationRefsEqual(value.materialActivation, lookup.materialActivation)) return null;
|
|
415
|
-
return value;
|
|
416
|
-
}
|
|
417
|
-
async listEnrollmentProductEpochs(enrollmentId) {
|
|
418
|
-
return ((await this.database.prepare(`SELECT product_json
|
|
419
|
-
FROM ${PRODUCT_TABLE}
|
|
420
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
421
|
-
AND enrollment_id = ?5
|
|
422
|
-
ORDER BY wallet_key_id, lane_id, lane_share_epoch`).bind(...scopeValues(this.scope), String(enrollmentId)).all()).results ?? []).map(parseProductEpochRow);
|
|
423
|
-
}
|
|
424
|
-
async commitEnrollmentVisibility(input) {
|
|
425
|
-
const parent = await this.getEnrollment(input.enrollmentId);
|
|
426
|
-
const manifestDigest = parent ? await computeLaneEnrollmentManifestDigestV1(parent.value.manifest) : "";
|
|
427
|
-
if (!parent || String(parent.value.manifest.walletId) !== String(input.walletId) || parent.commandDigestB64u !== input.manifestDigestB64u && manifestDigest !== input.manifestDigestB64u) return {
|
|
428
|
-
outcome: "conflict",
|
|
429
|
-
enrollmentId: input.enrollmentId,
|
|
430
|
-
expectedVersion: 1,
|
|
431
|
-
actualVersion: parent?.version ?? 0,
|
|
432
|
-
requestedCommandDigestB64u: input.manifestDigestB64u,
|
|
433
|
-
storedCommandDigestB64u: parent?.commandDigestB64u ?? ""
|
|
434
|
-
};
|
|
435
|
-
const receipt = parseAggregateLaneActivationReceiptV1({
|
|
436
|
-
kind: "aggregate_lane_activation_receipt_v1",
|
|
437
|
-
enrollmentId: input.enrollmentId,
|
|
438
|
-
walletId: input.walletId,
|
|
439
|
-
manifestDigestB64u: input.manifestDigestB64u,
|
|
440
|
-
orderedChildReceipts: input.orderedChildReceipts,
|
|
441
|
-
activatedAtMs: input.activatedAtMs
|
|
442
|
-
});
|
|
443
|
-
validateActivationReceiptAgainstManifest(parent.value.manifest, receipt);
|
|
444
|
-
const aggregateDigest = await computeAggregateLaneActivationReceiptDigestV1(receipt);
|
|
445
|
-
if (parent.value.lifecycle.state === "active") {
|
|
446
|
-
if (parent.value.lifecycle.aggregateReceiptDigestB64u === aggregateDigest) {
|
|
447
|
-
await this.verifyStoredRefreshPredecessorRetirements(input);
|
|
448
|
-
const productEpochs = await activeProductEpochs(this, input.enrollmentId);
|
|
449
|
-
if (productEpochs.length === 0) throw new Error("active enrollment has no product epochs");
|
|
450
|
-
return {
|
|
451
|
-
outcome: "replayed",
|
|
452
|
-
version: parent.version,
|
|
453
|
-
commandDigestB64u: aggregateDigest,
|
|
454
|
-
receipt,
|
|
455
|
-
lifecycle: parent.value.lifecycle,
|
|
456
|
-
productEpochs
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
return {
|
|
460
|
-
outcome: "conflict",
|
|
461
|
-
enrollmentId: input.enrollmentId,
|
|
462
|
-
expectedVersion: parent.version,
|
|
463
|
-
actualVersion: parent.version,
|
|
464
|
-
requestedCommandDigestB64u: aggregateDigest,
|
|
465
|
-
storedCommandDigestB64u: parent.value.lifecycle.aggregateReceiptDigestB64u
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
const readyLifecycle = resolveReadyEnrollmentLifecycle(parent.value.lifecycle, input, aggregateDigest);
|
|
469
|
-
if (!readyLifecycle) return {
|
|
470
|
-
outcome: "conflict",
|
|
471
|
-
enrollmentId: input.enrollmentId,
|
|
472
|
-
expectedVersion: parent.version,
|
|
473
|
-
actualVersion: parent.version,
|
|
474
|
-
requestedCommandDigestB64u: aggregateDigest,
|
|
475
|
-
storedCommandDigestB64u: parent.commandDigestB64u
|
|
476
|
-
};
|
|
477
|
-
if (readyLifecycle.aggregateReceiptDigestB64u !== aggregateDigest) return {
|
|
478
|
-
outcome: "conflict",
|
|
479
|
-
enrollmentId: input.enrollmentId,
|
|
480
|
-
expectedVersion: parent.version,
|
|
481
|
-
actualVersion: parent.version,
|
|
482
|
-
requestedCommandDigestB64u: aggregateDigest,
|
|
483
|
-
storedCommandDigestB64u: readyLifecycle.aggregateReceiptDigestB64u
|
|
484
|
-
};
|
|
485
|
-
const activeLifecycle = transitionLaneEnrollmentLifecycleV1(readyLifecycle, {
|
|
486
|
-
action: "activate",
|
|
487
|
-
activatedAtMs: input.activatedAtMs
|
|
488
|
-
});
|
|
489
|
-
if (activeLifecycle.state !== "active") throw new Error("lane visibility transition did not produce active enrollment");
|
|
490
|
-
const protocols = [];
|
|
491
|
-
const products = await this.listEnrollmentProductEpochs(input.enrollmentId);
|
|
492
|
-
const retirements = [];
|
|
493
|
-
let refreshRetirementIndex = 0;
|
|
494
|
-
for (const child of input.orderedChildReceipts) {
|
|
495
|
-
const protocol = await this.getProtocol(child.operationId);
|
|
496
|
-
if (!protocol || protocol.value.lifecycle.state !== "ready_for_parent_visibility") throw new Error("lane child is not ready for parent visibility");
|
|
497
|
-
const readyLifecycle = protocol.value.lifecycle;
|
|
498
|
-
if (String(protocol.value.job.walletId) !== String(input.walletId) || String(protocol.value.job.walletKeyId) !== String(child.walletKeyId) || String(protocol.value.job.target.laneId) !== String(child.targetLaneId) || String(protocol.value.job.target.laneShareEpoch) !== String(child.targetLaneShareEpoch) || String(protocol.value.job.targetMaterialActivationId) !== String(child.targetMaterialActivation.activationId) || readyLifecycle.protocolCommitReceiptDigestB64u !== child.protocolCommitReceiptDigestB64u || readyLifecycle.holderDeliveryReceiptDigestB64u !== child.holderDeliveryReceiptDigestB64u || readyLifecycle.serverActivationReceiptDigestB64u !== child.serverActivationReceiptDigestB64u) throw new Error("lane child identity or receipt digest differs from aggregate receipt");
|
|
499
|
-
const product = products.find((candidate) => String(candidate.operationId) === String(child.operationId));
|
|
500
|
-
if (!product || product.state !== "pending_visibility" || String(product.walletId) !== String(input.walletId) || String(product.walletKeyId) !== String(child.walletKeyId) || String(product.laneId) !== String(child.targetLaneId) || String(product.laneShareEpoch) !== String(child.targetLaneShareEpoch) || String(product.targetMaterialActivationId) !== String(child.targetMaterialActivation.activationId) || !mpcMaterialActivationRefsEqual(product.materialActivation, child.targetMaterialActivation)) throw new Error("lane child product epoch is not pending or differs from aggregate receipt");
|
|
501
|
-
if (protocol.value.job.target.operation === "refresh_lane") {
|
|
502
|
-
const previous = await this.getFencedProductEpochByActivation(protocol.value.job.walletKeyId, protocol.value.job.target.laneId, protocol.value.job.target.priorMaterialActivation.activationId);
|
|
503
|
-
if (!previous) throw new Error("lane refresh target has no fenced prior product epoch");
|
|
504
|
-
const refresh = input.orderedPredecessorRetirements[refreshRetirementIndex];
|
|
505
|
-
if (!refresh) throw new Error("lane refresh target has no exact predecessor retirement result");
|
|
506
|
-
const parsedRefresh = parseLaneRefreshPredecessorRetirementV1(refresh);
|
|
507
|
-
const verifiedRetirement = await verifyRefreshPredecessorRetirementV1({
|
|
508
|
-
previous: previous.product,
|
|
509
|
-
previousProtocol: await this.getProtocol(previous.product.operationId),
|
|
510
|
-
refreshProtocol: protocol,
|
|
511
|
-
refresh: parsedRefresh,
|
|
512
|
-
activatedAtMs: input.activatedAtMs
|
|
513
|
-
});
|
|
514
|
-
retirements.push({
|
|
515
|
-
previous: previous.product,
|
|
516
|
-
version: previous.version,
|
|
517
|
-
refresh: parsedRefresh,
|
|
518
|
-
receiptDigestB64u: verifiedRetirement.receiptDigestB64u,
|
|
519
|
-
retiredAtMs: verifiedRetirement.retiredAtMs
|
|
520
|
-
});
|
|
521
|
-
refreshRetirementIndex += 1;
|
|
522
|
-
}
|
|
523
|
-
protocols.push({
|
|
524
|
-
operationId: child.operationId,
|
|
525
|
-
row: protocol
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
if (refreshRetirementIndex !== input.orderedPredecessorRetirements.length) throw new Error("predecessor retirement results do not match refresh children exactly");
|
|
529
|
-
const now = this.now();
|
|
530
|
-
const values = scopeValues(this.scope);
|
|
531
|
-
const statements = [];
|
|
532
|
-
statements.push(this.database.prepare(`UPDATE ${ENROLLMENT_TABLE} SET lifecycle_json = ?5, version = version + 1, command_digest_b64u = ?6, updated_at_ms = ?7 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND enrollment_id = ?8 AND version = ?9 AND lifecycle_json = ?10`).bind(...values, JSON.stringify(activeLifecycle), aggregateDigest, now, String(input.enrollmentId), parent.version, JSON.stringify(parent.value.lifecycle)));
|
|
533
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
534
|
-
for (const protocol of protocols) {
|
|
535
|
-
const readyLifecycle = protocol.row.value.lifecycle;
|
|
536
|
-
if (readyLifecycle.state !== "ready_for_parent_visibility") throw new Error("lane child lifecycle changed before visibility commit");
|
|
537
|
-
const lifecycle = {
|
|
538
|
-
state: "active",
|
|
539
|
-
transcriptHashB64u: readyLifecycle.transcriptHashB64u,
|
|
540
|
-
protocolCommitReceiptDigestB64u: readyLifecycle.protocolCommitReceiptDigestB64u,
|
|
541
|
-
holderDeliveryReceiptDigestB64u: readyLifecycle.holderDeliveryReceiptDigestB64u,
|
|
542
|
-
serverActivationReceiptDigestB64u: readyLifecycle.serverActivationReceiptDigestB64u,
|
|
543
|
-
aggregateActivationReceiptDigestB64u: aggregateDigest,
|
|
544
|
-
activatedAtMs: input.activatedAtMs
|
|
545
|
-
};
|
|
546
|
-
statements.push(this.database.prepare(`UPDATE ${OPERATION_TABLE} SET lifecycle_json = ?5, version = version + 1, command_digest_b64u = ?6, updated_at_ms = ?7 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?8 AND version = ?9`).bind(...values, JSON.stringify(lifecycle), aggregateDigest, now, String(protocol.operationId), protocol.row.version));
|
|
547
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
548
|
-
}
|
|
549
|
-
for (const retirement of retirements) {
|
|
550
|
-
const retired = retireFencedLaneProductEpochV1(retirement.previous, {
|
|
551
|
-
retirementReceiptDigestB64u: retirement.receiptDigestB64u,
|
|
552
|
-
retiredAtMs: retirement.retiredAtMs
|
|
553
|
-
});
|
|
554
|
-
statements.push(this.database.prepare(`UPDATE ${PRODUCT_TABLE} SET state = 'retired', product_json = ?5, version = version + 1, command_digest_b64u = ?6, updated_at_ms = ?7 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND wallet_key_id = ?8 AND lane_id = ?9 AND target_material_activation_id = ?10 AND version = ?11 AND state = 'revocation_pending'`).bind(...values, JSON.stringify(retired), aggregateDigest, now, String(retirement.previous.walletKeyId), String(retirement.previous.laneId), String(retirement.previous.targetMaterialActivationId), retirement.version));
|
|
555
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
556
|
-
statements.push(this.database.prepare(`INSERT INTO ${RECEIPT_TABLE} (namespace, org_id, project_id, env_id, receipt_id, enrollment_id, operation_id, receipt_kind, receipt_digest_b64u, receipt_json, created_at_ms) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, 'lane_refresh_predecessor_retirement', ?8, ?9, ?10)`).bind(...values, refreshPredecessorRetirementReceiptId(retirement.refresh), String(input.enrollmentId), String(retirement.refresh.refreshOperationId), retirement.receiptDigestB64u, JSON.stringify(retirement.refresh.retirementReceipt), input.activatedAtMs));
|
|
557
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
558
|
-
}
|
|
559
|
-
for (const child of input.orderedChildReceipts) {
|
|
560
|
-
const pending = products.find((candidate) => String(candidate.operationId) === String(child.operationId));
|
|
561
|
-
if (!pending || pending.state !== "pending_visibility") throw new Error("lane product epoch is not pending");
|
|
562
|
-
const active = activateLaneProductEpochV1(pending, {
|
|
563
|
-
aggregateActivationReceiptDigestB64u: aggregateDigest,
|
|
564
|
-
activatedAtMs: input.activatedAtMs
|
|
565
|
-
});
|
|
566
|
-
statements.push(this.database.prepare(`UPDATE ${PRODUCT_TABLE} SET state = 'active', product_json = ?5, version = version + 1, command_digest_b64u = ?6, updated_at_ms = ?7 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?8 AND state = 'pending_visibility'`).bind(...values, JSON.stringify(active), aggregateDigest, now, String(child.operationId)));
|
|
567
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
568
|
-
}
|
|
569
|
-
statements.push(this.database.prepare(`INSERT INTO ${RECEIPT_TABLE} (namespace, org_id, project_id, env_id, receipt_id, enrollment_id, operation_id, receipt_kind, receipt_digest_b64u, receipt_json, created_at_ms) VALUES (?1, ?2, ?3, ?4, ?5, ?6, NULL, 'aggregate_activation', ?7, ?8, ?9)`).bind(...values, `${String(input.enrollmentId)}:aggregate_activation`, String(input.enrollmentId), aggregateDigest, JSON.stringify(receipt), input.activatedAtMs));
|
|
570
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
571
|
-
try {
|
|
572
|
-
const results = await this.database.batch(statements);
|
|
573
|
-
for (let index = 0; index < results.length; index += 1) assertD1Success(firstBatchResult(results, index), `lane visibility statement ${index}`);
|
|
574
|
-
} catch (error) {
|
|
575
|
-
const raced = await this.getEnrollment(input.enrollmentId);
|
|
576
|
-
if (raced?.value.lifecycle.state === "active" && raced.value.lifecycle.aggregateReceiptDigestB64u === aggregateDigest) {
|
|
577
|
-
await this.verifyStoredRefreshPredecessorRetirements(input);
|
|
578
|
-
const productEpochs = await activeProductEpochs(this, input.enrollmentId);
|
|
579
|
-
if (productEpochs.length === 0) throw error;
|
|
580
|
-
return {
|
|
581
|
-
outcome: "replayed",
|
|
582
|
-
version: raced.version,
|
|
583
|
-
commandDigestB64u: aggregateDigest,
|
|
584
|
-
receipt,
|
|
585
|
-
lifecycle: raced.value.lifecycle,
|
|
586
|
-
productEpochs
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
throw error;
|
|
590
|
-
}
|
|
591
|
-
const productEpochs = await activeProductEpochs(this, input.enrollmentId);
|
|
592
|
-
if (productEpochs.length === 0) throw new Error("lane visibility commit produced no active product epochs");
|
|
593
|
-
return {
|
|
594
|
-
outcome: "applied",
|
|
595
|
-
version: parent.version + 1,
|
|
596
|
-
commandDigestB64u: aggregateDigest,
|
|
597
|
-
receipt,
|
|
598
|
-
lifecycle: activeLifecycle,
|
|
599
|
-
productEpochs
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
async fenceLaneRevocation(input) {
|
|
603
|
-
const command = parseRevokeSigningLaneV1(input);
|
|
604
|
-
const commandDigestB64u = await computeRevokeSigningLaneDigestV1(command);
|
|
605
|
-
const row = await this.database.prepare(`SELECT product_json, version, command_digest_b64u
|
|
606
|
-
FROM ${PRODUCT_TABLE}
|
|
607
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
608
|
-
AND wallet_key_id = ?5 AND lane_id = ?6 AND lane_share_epoch = ?7`).bind(...scopeValues(this.scope), String(command.walletKeyId), String(command.laneId), String(command.laneShareEpoch)).first();
|
|
609
|
-
if (!row) return {
|
|
610
|
-
outcome: "conflict",
|
|
611
|
-
expectedVersion: 1,
|
|
612
|
-
actualVersion: 0,
|
|
613
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
614
|
-
storedCommandDigestB64u: ""
|
|
615
|
-
};
|
|
616
|
-
const product = parseProductEpochRecordV1(row.product_json);
|
|
617
|
-
const version = parseVersion(row.version, "lane product epoch version");
|
|
618
|
-
const storedDigest = parseRequiredString(row.command_digest_b64u, "lane product epoch command digest");
|
|
619
|
-
if (String(product.walletId) !== String(command.walletId)) return {
|
|
620
|
-
outcome: "conflict",
|
|
621
|
-
expectedVersion: version,
|
|
622
|
-
actualVersion: version,
|
|
623
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
624
|
-
storedCommandDigestB64u: storedDigest
|
|
625
|
-
};
|
|
626
|
-
if (product.state === "revoked") {
|
|
627
|
-
if (storedDigest === commandDigestB64u) return {
|
|
628
|
-
outcome: "already_completed",
|
|
629
|
-
version,
|
|
630
|
-
commandDigestB64u: storedDigest,
|
|
631
|
-
productEpoch: product,
|
|
632
|
-
retirementReceipt: await this.readAndVerifyServerRetirementReceipt(product, command)
|
|
633
|
-
};
|
|
634
|
-
return {
|
|
635
|
-
outcome: "conflict",
|
|
636
|
-
expectedVersion: version,
|
|
637
|
-
actualVersion: version,
|
|
638
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
639
|
-
storedCommandDigestB64u: storedDigest
|
|
640
|
-
};
|
|
641
|
-
}
|
|
642
|
-
if (product.state === "revocation_pending") {
|
|
643
|
-
if (storedDigest === commandDigestB64u) return {
|
|
644
|
-
outcome: "replayed",
|
|
645
|
-
version,
|
|
646
|
-
commandDigestB64u: storedDigest,
|
|
647
|
-
productEpoch: product
|
|
648
|
-
};
|
|
649
|
-
return {
|
|
650
|
-
outcome: "conflict",
|
|
651
|
-
expectedVersion: version,
|
|
652
|
-
actualVersion: version,
|
|
653
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
654
|
-
storedCommandDigestB64u: storedDigest
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
return await this.commitLaneRevocationFence({
|
|
658
|
-
command,
|
|
659
|
-
expectedVersion: version,
|
|
660
|
-
commandDigestB64u
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
|
-
async fenceEnrollmentRevocation(input) {
|
|
664
|
-
const commandDigestB64u = await digestLaneEnrollmentRevocationCommand(input);
|
|
665
|
-
const parent = await this.getEnrollment(input.enrollmentId);
|
|
666
|
-
if (!parent) return {
|
|
667
|
-
outcome: "conflict",
|
|
668
|
-
expectedVersion: 1,
|
|
669
|
-
actualVersion: 0,
|
|
670
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
671
|
-
storedCommandDigestB64u: ""
|
|
672
|
-
};
|
|
673
|
-
if (String(parent.value.manifest.walletId) !== String(input.walletId)) return {
|
|
674
|
-
outcome: "conflict",
|
|
675
|
-
expectedVersion: parent.version,
|
|
676
|
-
actualVersion: parent.version,
|
|
677
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
678
|
-
storedCommandDigestB64u: parent.commandDigestB64u
|
|
679
|
-
};
|
|
680
|
-
const manifestDigest = await computeLaneEnrollmentManifestDigestV1(parent.value.manifest);
|
|
681
|
-
if (manifestDigest !== input.manifestDigestB64u) return {
|
|
682
|
-
outcome: "conflict",
|
|
683
|
-
expectedVersion: parent.version,
|
|
684
|
-
actualVersion: parent.version,
|
|
685
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
686
|
-
storedCommandDigestB64u: manifestDigest
|
|
687
|
-
};
|
|
688
|
-
const storedFenceDigest = await this.getEnrollmentRevocationFenceDigest(input.enrollmentId);
|
|
689
|
-
if (parent.value.lifecycle.state === "revoked") {
|
|
690
|
-
if (storedFenceDigest !== commandDigestB64u) return {
|
|
691
|
-
outcome: "conflict",
|
|
692
|
-
expectedVersion: parent.version,
|
|
693
|
-
actualVersion: parent.version,
|
|
694
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
695
|
-
storedCommandDigestB64u: storedFenceDigest ?? parent.commandDigestB64u
|
|
696
|
-
};
|
|
697
|
-
return {
|
|
698
|
-
outcome: "replayed",
|
|
699
|
-
version: parent.version,
|
|
700
|
-
commandDigestB64u,
|
|
701
|
-
value: parent.value
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
const reason = input.reason === "cancelled_after_commit" || input.reason === "expired_after_commit" || input.reason === "revoked_during_activation" ? input.reason : "revoked_during_activation";
|
|
705
|
-
let lifecycle;
|
|
706
|
-
switch (parent.value.lifecycle.state) {
|
|
707
|
-
case "committed_completion_required":
|
|
708
|
-
case "ready_for_visibility":
|
|
709
|
-
case "active":
|
|
710
|
-
lifecycle = transitionLaneEnrollmentLifecycleV1(parent.value.lifecycle, {
|
|
711
|
-
action: "begin_revocation",
|
|
712
|
-
reason,
|
|
713
|
-
markedAtMs: input.requestedAtMs
|
|
714
|
-
});
|
|
715
|
-
break;
|
|
716
|
-
case "revoking_committed_targets":
|
|
717
|
-
if (parent.value.lifecycle.reason === reason && parent.value.lifecycle.manifestDigestB64u === input.manifestDigestB64u && storedFenceDigest === commandDigestB64u) return {
|
|
718
|
-
outcome: "replayed",
|
|
719
|
-
version: parent.version,
|
|
720
|
-
commandDigestB64u,
|
|
721
|
-
value: parent.value
|
|
722
|
-
};
|
|
723
|
-
return {
|
|
724
|
-
outcome: "conflict",
|
|
725
|
-
expectedVersion: parent.version,
|
|
726
|
-
actualVersion: parent.version,
|
|
727
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
728
|
-
storedCommandDigestB64u: storedFenceDigest ?? parent.commandDigestB64u
|
|
729
|
-
};
|
|
730
|
-
case "preparing":
|
|
731
|
-
case "cancelled_precommit": return {
|
|
732
|
-
outcome: "conflict",
|
|
733
|
-
expectedVersion: parent.version,
|
|
734
|
-
actualVersion: parent.version,
|
|
735
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
736
|
-
storedCommandDigestB64u: parent.commandDigestB64u
|
|
737
|
-
};
|
|
738
|
-
default: return assertNeverEnrollmentLifecycle(parent.value.lifecycle);
|
|
739
|
-
}
|
|
740
|
-
if (lifecycle.state !== "revoking_committed_targets") throw new Error("lane enrollment revocation fence did not produce revoking state");
|
|
741
|
-
if (!await this.updateEnrollmentRevocationFence(input.enrollmentId, parent.version, commandDigestB64u, lifecycle)) {
|
|
742
|
-
const raced = await this.getEnrollment(input.enrollmentId);
|
|
743
|
-
const racedFenceDigest = await this.getEnrollmentRevocationFenceDigest(input.enrollmentId);
|
|
744
|
-
if (raced?.value.lifecycle.state === "revoking_committed_targets" && raced.value.lifecycle.reason === reason && raced.value.lifecycle.manifestDigestB64u === input.manifestDigestB64u && racedFenceDigest === commandDigestB64u) return {
|
|
745
|
-
outcome: "replayed",
|
|
746
|
-
version: raced.version,
|
|
747
|
-
commandDigestB64u,
|
|
748
|
-
value: raced.value
|
|
749
|
-
};
|
|
750
|
-
return {
|
|
751
|
-
outcome: "conflict",
|
|
752
|
-
expectedVersion: parent.version,
|
|
753
|
-
actualVersion: raced?.version ?? 0,
|
|
754
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
755
|
-
storedCommandDigestB64u: racedFenceDigest ?? raced?.commandDigestB64u ?? ""
|
|
756
|
-
};
|
|
757
|
-
}
|
|
758
|
-
const result = await this.getEnrollment(input.enrollmentId);
|
|
759
|
-
if (!result) throw new Error("lane enrollment disappeared after revocation fence");
|
|
760
|
-
return {
|
|
761
|
-
outcome: "applied",
|
|
762
|
-
version: result.version,
|
|
763
|
-
commandDigestB64u,
|
|
764
|
-
value: result.value
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
async commitLaneRevocationFence(input) {
|
|
768
|
-
const command = parseRevokeSigningLaneV1(input.command);
|
|
769
|
-
const row = await this.database.prepare(`SELECT product_json, version, command_digest_b64u FROM ${PRODUCT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND wallet_key_id = ?5 AND lane_id = ?6 AND lane_share_epoch = ?7`).bind(...scopeValues(this.scope), String(command.walletKeyId), String(command.laneId), String(command.laneShareEpoch)).first();
|
|
770
|
-
if (!row) return {
|
|
771
|
-
outcome: "conflict",
|
|
772
|
-
expectedVersion: input.expectedVersion,
|
|
773
|
-
actualVersion: 0,
|
|
774
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
775
|
-
storedCommandDigestB64u: ""
|
|
776
|
-
};
|
|
777
|
-
const product = parseProductEpochRecordV1(row.product_json);
|
|
778
|
-
const currentVersion = Number(row.version);
|
|
779
|
-
const storedDigest = typeof row.command_digest_b64u === "string" ? row.command_digest_b64u : "";
|
|
780
|
-
if (String(product.walletId) !== String(command.walletId)) return {
|
|
781
|
-
outcome: "conflict",
|
|
782
|
-
expectedVersion: input.expectedVersion,
|
|
783
|
-
actualVersion: Number.isSafeInteger(currentVersion) ? currentVersion : 0,
|
|
784
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
785
|
-
storedCommandDigestB64u: storedDigest
|
|
786
|
-
};
|
|
787
|
-
if (product.state === "revoked" && storedDigest === input.commandDigestB64u) return {
|
|
788
|
-
outcome: "already_completed",
|
|
789
|
-
version: currentVersion,
|
|
790
|
-
commandDigestB64u: storedDigest,
|
|
791
|
-
productEpoch: product,
|
|
792
|
-
retirementReceipt: await this.readAndVerifyServerRetirementReceipt(product, command)
|
|
793
|
-
};
|
|
794
|
-
if (product.state === "revocation_pending" && storedDigest === input.commandDigestB64u) return {
|
|
795
|
-
outcome: "replayed",
|
|
796
|
-
version: currentVersion,
|
|
797
|
-
commandDigestB64u: storedDigest,
|
|
798
|
-
productEpoch: product
|
|
799
|
-
};
|
|
800
|
-
if (product.state !== "revoked" && product.state !== "revocation_pending" && product.revocationEpoch !== command.expectedRevocationEpoch) return {
|
|
801
|
-
outcome: "conflict",
|
|
802
|
-
expectedVersion: input.expectedVersion,
|
|
803
|
-
actualVersion: Number.isSafeInteger(currentVersion) ? currentVersion : 0,
|
|
804
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
805
|
-
storedCommandDigestB64u: storedDigest
|
|
806
|
-
};
|
|
807
|
-
if (!Number.isSafeInteger(currentVersion) || currentVersion < 1 || currentVersion !== input.expectedVersion) return {
|
|
808
|
-
outcome: "conflict",
|
|
809
|
-
expectedVersion: input.expectedVersion,
|
|
810
|
-
actualVersion: Number.isSafeInteger(currentVersion) ? currentVersion : 0,
|
|
811
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
812
|
-
storedCommandDigestB64u: storedDigest
|
|
813
|
-
};
|
|
814
|
-
if (product.state !== "active" && product.state !== "pending_visibility") return {
|
|
815
|
-
outcome: "conflict",
|
|
816
|
-
expectedVersion: input.expectedVersion,
|
|
817
|
-
actualVersion: currentVersion,
|
|
818
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
819
|
-
storedCommandDigestB64u: storedDigest
|
|
820
|
-
};
|
|
821
|
-
const pending = beginLaneProductEpochRevocationV1(product, {
|
|
822
|
-
revocationEpoch: command.expectedRevocationEpoch + 1,
|
|
823
|
-
revocationReason: command.reason,
|
|
824
|
-
retirementEffectBindingDigestB64u: command.retirementEffectBindingDigestB64u,
|
|
825
|
-
revocationRequestedAtMs: command.requestedAtMs
|
|
826
|
-
});
|
|
827
|
-
if (d1ChangedRows(await this.database.prepare(`UPDATE ${PRODUCT_TABLE} SET state = 'revocation_pending', revocation_epoch = ?5, product_json = ?6, version = version + 1, command_digest_b64u = ?7, updated_at_ms = ?8 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND wallet_key_id = ?9 AND lane_id = ?10 AND lane_share_epoch = ?11 AND version = ?12 AND state IN ('active', 'pending_visibility')`).bind(...scopeValues(this.scope), command.expectedRevocationEpoch + 1, JSON.stringify(pending), input.commandDigestB64u, command.requestedAtMs, String(command.walletKeyId), String(command.laneId), String(command.laneShareEpoch), input.expectedVersion).run()) !== 1) {
|
|
828
|
-
const raced = await this.database.prepare(`SELECT product_json, version, command_digest_b64u FROM ${PRODUCT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND wallet_key_id = ?5 AND lane_id = ?6 AND lane_share_epoch = ?7`).bind(...scopeValues(this.scope), String(command.walletKeyId), String(command.laneId), String(command.laneShareEpoch)).first();
|
|
829
|
-
const racedProduct = raced ? parseProductEpochRecordV1(raced.product_json) : null;
|
|
830
|
-
const racedDigest = typeof raced?.command_digest_b64u === "string" ? raced.command_digest_b64u : "";
|
|
831
|
-
if (racedProduct?.state === "revocation_pending" && racedDigest === input.commandDigestB64u) return {
|
|
832
|
-
outcome: "replayed",
|
|
833
|
-
version: Number(raced?.version),
|
|
834
|
-
commandDigestB64u: racedDigest,
|
|
835
|
-
productEpoch: racedProduct
|
|
836
|
-
};
|
|
837
|
-
return {
|
|
838
|
-
outcome: "conflict",
|
|
839
|
-
expectedVersion: input.expectedVersion,
|
|
840
|
-
actualVersion: Number(raced?.version ?? 0),
|
|
841
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
842
|
-
storedCommandDigestB64u: racedDigest
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
return {
|
|
846
|
-
outcome: "applied",
|
|
847
|
-
version: input.expectedVersion + 1,
|
|
848
|
-
commandDigestB64u: input.commandDigestB64u,
|
|
849
|
-
productEpoch: pending
|
|
850
|
-
};
|
|
851
|
-
}
|
|
852
|
-
async commitLaneRevocation(input) {
|
|
853
|
-
const completion = parseCompleteSigningLaneRevocationV1(input.completion);
|
|
854
|
-
const command = parseRevokeSigningLaneV1(completion.command);
|
|
855
|
-
if (await computeRevokeSigningLaneDigestV1(command) !== completion.commandDigestB64u) throw new Error("lane revocation completion command digest is invalid");
|
|
856
|
-
const row = await this.database.prepare(`SELECT product_json, version, command_digest_b64u FROM ${PRODUCT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND wallet_key_id = ?5 AND lane_id = ?6 AND lane_share_epoch = ?7`).bind(...scopeValues(this.scope), String(command.walletKeyId), String(command.laneId), String(command.laneShareEpoch)).first();
|
|
857
|
-
if (!row) return {
|
|
858
|
-
outcome: "conflict",
|
|
859
|
-
expectedVersion: completion.expectedVersion,
|
|
860
|
-
actualVersion: 0,
|
|
861
|
-
requestedCommandDigestB64u: completion.commandDigestB64u,
|
|
862
|
-
storedCommandDigestB64u: ""
|
|
863
|
-
};
|
|
864
|
-
const product = parseLaneProductEpochRecordV1(parseJsonRecord(row.product_json, "product_json"));
|
|
865
|
-
const currentVersion = parseVersion(row.version, "lane product epoch version");
|
|
866
|
-
const storedDigest = parseRequiredString(row.command_digest_b64u, "lane product epoch command digest");
|
|
867
|
-
if (product.state !== "revocation_pending" && product.state !== "revoked") return {
|
|
868
|
-
outcome: "conflict",
|
|
869
|
-
expectedVersion: completion.expectedVersion,
|
|
870
|
-
actualVersion: currentVersion,
|
|
871
|
-
requestedCommandDigestB64u: completion.commandDigestB64u,
|
|
872
|
-
storedCommandDigestB64u: storedDigest
|
|
873
|
-
};
|
|
874
|
-
const retirementReceipt = parseLaneServerRetirementReceiptV1(completion.retirementReceipt, "lane revocation completion retirement receipt");
|
|
875
|
-
const retirementReceiptDigestB64u = await verifyServerRetirementReceiptV1({
|
|
876
|
-
store: this,
|
|
877
|
-
product,
|
|
878
|
-
command,
|
|
879
|
-
receipt: retirementReceipt
|
|
880
|
-
});
|
|
881
|
-
if (product.state === "revoked" && storedDigest === completion.commandDigestB64u && product.retirementEffectBindingDigestB64u === command.retirementEffectBindingDigestB64u && product.revocationReceiptDigestB64u === retirementReceiptDigestB64u) {
|
|
882
|
-
const storedReceipt = await this.readAndVerifyServerRetirementReceipt(product, command);
|
|
883
|
-
if (!equalLaneRecords(storedReceipt, retirementReceipt)) return {
|
|
884
|
-
outcome: "conflict",
|
|
885
|
-
expectedVersion: completion.expectedVersion,
|
|
886
|
-
actualVersion: currentVersion,
|
|
887
|
-
requestedCommandDigestB64u: retirementReceiptDigestB64u,
|
|
888
|
-
storedCommandDigestB64u: product.revocationReceiptDigestB64u
|
|
889
|
-
};
|
|
890
|
-
return {
|
|
891
|
-
outcome: "replayed",
|
|
892
|
-
version: currentVersion,
|
|
893
|
-
commandDigestB64u: storedDigest,
|
|
894
|
-
productEpoch: product,
|
|
895
|
-
retirementReceipt: storedReceipt
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
if (product.state !== "revocation_pending" || currentVersion !== completion.expectedVersion || storedDigest !== completion.commandDigestB64u || product.retirementEffectBindingDigestB64u !== command.retirementEffectBindingDigestB64u || product.revocationEpoch !== command.expectedRevocationEpoch + 1) return {
|
|
899
|
-
outcome: "conflict",
|
|
900
|
-
expectedVersion: completion.expectedVersion,
|
|
901
|
-
actualVersion: currentVersion,
|
|
902
|
-
requestedCommandDigestB64u: completion.commandDigestB64u,
|
|
903
|
-
storedCommandDigestB64u: storedDigest
|
|
904
|
-
};
|
|
905
|
-
const revoked = parseLaneProductEpochRecordV1(completeLaneProductEpochRevocationV1(product, {
|
|
906
|
-
revocationReceiptDigestB64u: retirementReceiptDigestB64u,
|
|
907
|
-
revokedAtMs: completion.revokedAtMs
|
|
908
|
-
}));
|
|
909
|
-
if (revoked.state !== "revoked") throw new Error("lane revocation completion state changed");
|
|
910
|
-
const update = this.database.prepare(`UPDATE ${PRODUCT_TABLE} SET state = 'revoked', product_json = ?5, version = version + 1, updated_at_ms = ?6 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND wallet_key_id = ?7 AND lane_id = ?8 AND lane_share_epoch = ?9 AND version = ?10 AND state = 'revocation_pending' AND command_digest_b64u = ?11`).bind(...scopeValues(this.scope), JSON.stringify(revoked), completion.revokedAtMs, String(command.walletKeyId), String(command.laneId), String(command.laneShareEpoch), completion.expectedVersion, completion.commandDigestB64u);
|
|
911
|
-
const receiptInsert = this.database.prepare(`INSERT INTO ${RECEIPT_TABLE} (namespace, org_id, project_id, env_id, receipt_id, enrollment_id, operation_id, receipt_kind, receipt_digest_b64u, receipt_json, created_at_ms) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)`).bind(...scopeValues(this.scope), serverRetirementReceiptId(product), String(product.enrollmentId), String(product.operationId), serverRetirementReceiptKind(product), retirementReceiptDigestB64u, JSON.stringify(retirementReceipt), completion.revokedAtMs);
|
|
912
|
-
let applied = false;
|
|
913
|
-
try {
|
|
914
|
-
const results = await this.database.batch([
|
|
915
|
-
update,
|
|
916
|
-
this.database.prepare(LANE_CAS_GUARD_SQL),
|
|
917
|
-
receiptInsert,
|
|
918
|
-
this.database.prepare(LANE_CAS_GUARD_SQL)
|
|
919
|
-
]);
|
|
920
|
-
assertD1Success(firstBatchResult(results, 0), "lane revocation completion");
|
|
921
|
-
assertD1Success(firstBatchResult(results, 2), "lane retirement receipt persistence");
|
|
922
|
-
applied = d1ChangedRows(firstBatchResult(results, 0)) === 1;
|
|
923
|
-
} catch {
|
|
924
|
-
applied = false;
|
|
925
|
-
}
|
|
926
|
-
if (!applied) {
|
|
927
|
-
const raced = await this.getProductEpoch({
|
|
928
|
-
walletId: command.walletId,
|
|
929
|
-
walletKeyId: command.walletKeyId,
|
|
930
|
-
laneId: command.laneId,
|
|
931
|
-
laneShareEpoch: command.laneShareEpoch
|
|
932
|
-
});
|
|
933
|
-
if (raced?.state === "revoked" && raced.retirementEffectBindingDigestB64u === command.retirementEffectBindingDigestB64u && raced.revocationReceiptDigestB64u === retirementReceiptDigestB64u) {
|
|
934
|
-
const storedReceipt = await this.readAndVerifyServerRetirementReceipt(raced, command);
|
|
935
|
-
if (!equalLaneRecords(storedReceipt, retirementReceipt)) throw new Error("stored lane retirement receipt differs from completion receipt");
|
|
936
|
-
return {
|
|
937
|
-
outcome: "replayed",
|
|
938
|
-
version: completion.expectedVersion + 1,
|
|
939
|
-
commandDigestB64u: completion.commandDigestB64u,
|
|
940
|
-
productEpoch: raced,
|
|
941
|
-
retirementReceipt: storedReceipt
|
|
942
|
-
};
|
|
943
|
-
}
|
|
944
|
-
return {
|
|
945
|
-
outcome: "conflict",
|
|
946
|
-
expectedVersion: completion.expectedVersion,
|
|
947
|
-
actualVersion: completion.expectedVersion,
|
|
948
|
-
requestedCommandDigestB64u: completion.commandDigestB64u,
|
|
949
|
-
storedCommandDigestB64u: storedDigest
|
|
950
|
-
};
|
|
951
|
-
}
|
|
952
|
-
return {
|
|
953
|
-
outcome: "applied",
|
|
954
|
-
version: completion.expectedVersion + 1,
|
|
955
|
-
commandDigestB64u: completion.commandDigestB64u,
|
|
956
|
-
productEpoch: revoked,
|
|
957
|
-
retirementReceipt
|
|
958
|
-
};
|
|
959
|
-
}
|
|
960
|
-
async commitEnrollmentRevocation(input) {
|
|
961
|
-
const parent = await this.getEnrollment(input.command.enrollmentId);
|
|
962
|
-
if (!parent) return {
|
|
963
|
-
outcome: "conflict",
|
|
964
|
-
enrollmentId: input.command.enrollmentId,
|
|
965
|
-
expectedVersion: input.expectedVersion,
|
|
966
|
-
actualVersion: 0,
|
|
967
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
968
|
-
storedCommandDigestB64u: ""
|
|
969
|
-
};
|
|
970
|
-
const receipt = parseAggregateLaneRevocationReceiptV1(input.command.receipt);
|
|
971
|
-
const aggregateDigest = await computeAggregateLaneRevocationReceiptDigestV1(receipt);
|
|
972
|
-
if (parent.value.lifecycle.state === "revoked") {
|
|
973
|
-
if (parent.value.lifecycle.aggregateRevocationReceiptDigestB64u === aggregateDigest) {
|
|
974
|
-
const productEpochs = await revokedProductEpochs(this, input.command.enrollmentId);
|
|
975
|
-
if (productEpochs.length === 0) throw new Error("revoked enrollment has no product epochs");
|
|
976
|
-
return {
|
|
977
|
-
outcome: "replayed",
|
|
978
|
-
version: parent.version,
|
|
979
|
-
commandDigestB64u: input.commandDigestB64u,
|
|
980
|
-
receipt,
|
|
981
|
-
lifecycle: parent.value.lifecycle,
|
|
982
|
-
productEpochs
|
|
983
|
-
};
|
|
984
|
-
}
|
|
985
|
-
return {
|
|
986
|
-
outcome: "conflict",
|
|
987
|
-
enrollmentId: input.command.enrollmentId,
|
|
988
|
-
expectedVersion: input.expectedVersion,
|
|
989
|
-
actualVersion: parent.version,
|
|
990
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
991
|
-
storedCommandDigestB64u: parent.value.lifecycle.aggregateRevocationReceiptDigestB64u
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
if (parent.version !== input.expectedVersion) return {
|
|
995
|
-
outcome: "conflict",
|
|
996
|
-
enrollmentId: input.command.enrollmentId,
|
|
997
|
-
expectedVersion: input.expectedVersion,
|
|
998
|
-
actualVersion: parent.version,
|
|
999
|
-
requestedCommandDigestB64u: input.commandDigestB64u,
|
|
1000
|
-
storedCommandDigestB64u: parent.commandDigestB64u
|
|
1001
|
-
};
|
|
1002
|
-
const productEpochs = (await this.listEnrollmentProductEpochs(input.command.enrollmentId)).filter((product) => product.state !== "retired");
|
|
1003
|
-
if (productEpochs.length !== receipt.orderedChildReceipts.length) throw new Error("revocation receipt child count differs from enrollment");
|
|
1004
|
-
const revoked = [];
|
|
1005
|
-
for (const product of productEpochs) {
|
|
1006
|
-
const child = receipt.orderedChildReceipts.find((candidate) => String(candidate.operationId) === String(product.operationId));
|
|
1007
|
-
if (!child) throw new Error("revocation receipt omits a product epoch");
|
|
1008
|
-
const expectedRevocationEpoch = product.state === "revocation_pending" || product.state === "revoked" ? product.revocationEpoch : product.revocationEpoch + 1;
|
|
1009
|
-
if (String(child.walletKeyId) !== String(product.walletKeyId) || String(child.targetLaneId) !== String(product.laneId) || String(child.targetLaneShareEpoch) !== String(product.laneShareEpoch) || !mpcMaterialActivationRefsEqual(child.targetMaterialActivation, product.materialActivation) || child.revocationEpoch !== expectedRevocationEpoch) throw new Error("revocation receipt child differs from its product epoch");
|
|
1010
|
-
if (product.state === "revoked") {
|
|
1011
|
-
if (product.revocationEpoch !== child.revocationEpoch || product.revocationReceiptDigestB64u !== child.retirementReceiptDigestB64u) throw new Error("revocation receipt differs from the already revoked product epoch");
|
|
1012
|
-
revoked.push(product);
|
|
1013
|
-
continue;
|
|
1014
|
-
}
|
|
1015
|
-
revoked.push(buildLaneProductEpochRevokedV1({
|
|
1016
|
-
walletId: product.walletId,
|
|
1017
|
-
walletKeyId: product.walletKeyId,
|
|
1018
|
-
laneId: product.laneId,
|
|
1019
|
-
laneKind: product.laneKind,
|
|
1020
|
-
laneShareEpoch: product.laneShareEpoch,
|
|
1021
|
-
keyFamily: product.keyFamily,
|
|
1022
|
-
enrollmentId: product.enrollmentId,
|
|
1023
|
-
operationId: product.operationId,
|
|
1024
|
-
targetMaterialActivationId: product.targetMaterialActivationId,
|
|
1025
|
-
materialActivation: product.materialActivation,
|
|
1026
|
-
publicIdentityDigestB64u: product.publicIdentityDigestB64u,
|
|
1027
|
-
holderParticipant: product.holderParticipant,
|
|
1028
|
-
signingWorkerParticipant: product.signingWorkerParticipant,
|
|
1029
|
-
participantSetBindingDigestB64u: product.participantSetBindingDigestB64u,
|
|
1030
|
-
createdAtMs: product.createdAtMs,
|
|
1031
|
-
revocationEpoch: child.revocationEpoch,
|
|
1032
|
-
revocationReason: "user_revoked",
|
|
1033
|
-
retirementEffectBindingDigestB64u: product.state === "revocation_pending" ? product.retirementEffectBindingDigestB64u : aggregateDigest,
|
|
1034
|
-
revocationReceiptDigestB64u: child.retirementReceiptDigestB64u,
|
|
1035
|
-
revokedAtMs: input.command.revokedAtMs
|
|
1036
|
-
}));
|
|
1037
|
-
}
|
|
1038
|
-
const lifecycle = {
|
|
1039
|
-
state: "revoked",
|
|
1040
|
-
manifestDigestB64u: input.command.manifestDigestB64u,
|
|
1041
|
-
aggregateRevocationReceiptDigestB64u: aggregateDigest,
|
|
1042
|
-
revokedAtMs: input.command.revokedAtMs
|
|
1043
|
-
};
|
|
1044
|
-
const values = scopeValues(this.scope);
|
|
1045
|
-
const statements = [this.database.prepare(`UPDATE ${ENROLLMENT_TABLE} SET lifecycle_json = ?5, version = version + 1, command_digest_b64u = ?6, updated_at_ms = ?7 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND enrollment_id = ?8 AND version = ?9`).bind(...values, JSON.stringify(lifecycle), input.commandDigestB64u, input.command.revokedAtMs, String(input.command.enrollmentId), input.expectedVersion), this.database.prepare(LANE_CAS_GUARD_SQL)];
|
|
1046
|
-
for (const product of revoked) {
|
|
1047
|
-
if (productEpochs.find((candidate) => String(candidate.operationId) === String(product.operationId))?.state === "revoked") continue;
|
|
1048
|
-
statements.push(this.database.prepare(`UPDATE ${PRODUCT_TABLE} SET state = 'revoked', revocation_epoch = ?5, product_json = ?6, version = version + 1, command_digest_b64u = ?7, updated_at_ms = ?8 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND wallet_key_id = ?9 AND lane_id = ?10 AND lane_share_epoch = ?11 AND state IN ('active', 'pending_visibility')`).bind(...values, product.revocationEpoch, JSON.stringify(product), input.commandDigestB64u, input.command.revokedAtMs, String(product.walletKeyId), String(product.laneId), String(product.laneShareEpoch)));
|
|
1049
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
1050
|
-
}
|
|
1051
|
-
statements.push(this.database.prepare(`INSERT INTO ${RECEIPT_TABLE} (namespace, org_id, project_id, env_id, receipt_id, enrollment_id, operation_id, receipt_kind, receipt_digest_b64u, receipt_json, created_at_ms) VALUES (?1, ?2, ?3, ?4, ?5, ?6, NULL, 'aggregate_revocation', ?7, ?8, ?9)`).bind(...values, `${String(input.command.enrollmentId)}:aggregate_revocation`, String(input.command.enrollmentId), aggregateDigest, JSON.stringify(receipt), input.command.revokedAtMs));
|
|
1052
|
-
statements.push(this.database.prepare(LANE_CAS_GUARD_SQL));
|
|
1053
|
-
try {
|
|
1054
|
-
const results = await this.database.batch(statements);
|
|
1055
|
-
for (let index = 0; index < results.length; index += 1) assertD1Success(firstBatchResult(results, index), `lane revocation statement ${index}`);
|
|
1056
|
-
} catch (error) {
|
|
1057
|
-
const raced = await this.getEnrollment(input.command.enrollmentId);
|
|
1058
|
-
if (raced?.value.lifecycle.state === "revoked" && raced.value.lifecycle.aggregateRevocationReceiptDigestB64u === aggregateDigest) {
|
|
1059
|
-
const active = await revokedProductEpochs(this, input.command.enrollmentId);
|
|
1060
|
-
if (active.length === 0) throw error;
|
|
1061
|
-
return {
|
|
1062
|
-
outcome: "replayed",
|
|
1063
|
-
version: raced.version,
|
|
1064
|
-
commandDigestB64u: input.commandDigestB64u,
|
|
1065
|
-
receipt,
|
|
1066
|
-
lifecycle: raced.value.lifecycle,
|
|
1067
|
-
productEpochs: active
|
|
1068
|
-
};
|
|
1069
|
-
}
|
|
1070
|
-
throw error;
|
|
1071
|
-
}
|
|
1072
|
-
const outputEpochs = await revokedProductEpochs(this, input.command.enrollmentId);
|
|
1073
|
-
if (outputEpochs.length === 0) throw new Error("lane revocation commit produced no product epochs");
|
|
1074
|
-
return {
|
|
1075
|
-
outcome: "applied",
|
|
1076
|
-
version: input.expectedVersion + 1,
|
|
1077
|
-
commandDigestB64u: input.commandDigestB64u,
|
|
1078
|
-
receipt,
|
|
1079
|
-
lifecycle,
|
|
1080
|
-
productEpochs: outputEpochs
|
|
1081
|
-
};
|
|
1082
|
-
}
|
|
1083
|
-
async getFencedProductEpochByActivation(walletKeyId, laneId, activationId) {
|
|
1084
|
-
const row = await this.database.prepare(`SELECT product_json, version
|
|
1085
|
-
FROM ${PRODUCT_TABLE}
|
|
1086
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
1087
|
-
AND wallet_key_id = ?5 AND lane_id = ?6 AND target_material_activation_id = ?7
|
|
1088
|
-
AND state = 'revocation_pending'`).bind(...scopeValues(this.scope), String(walletKeyId), String(laneId), activationId).first();
|
|
1089
|
-
if (!row) return null;
|
|
1090
|
-
const product = parseProductEpochRecordV1(row.product_json);
|
|
1091
|
-
if (product.state !== "revocation_pending") return null;
|
|
1092
|
-
return {
|
|
1093
|
-
product,
|
|
1094
|
-
version: parseVersion(row.version, "prior lane product epoch version")
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
|
-
protocolInsertStatement(record, commandDigestB64u, now) {
|
|
1098
|
-
const job = record.job;
|
|
1099
|
-
return this.database.prepare(`INSERT INTO ${OPERATION_TABLE} (
|
|
1100
|
-
namespace, org_id, project_id, env_id, operation_id, enrollment_id, wallet_id,
|
|
1101
|
-
wallet_key_id, source_lane_id, source_lane_share_epoch, source_revocation_epoch,
|
|
1102
|
-
target_lane_id, target_lane_share_epoch, target_material_activation_id,
|
|
1103
|
-
key_family, job_json, lifecycle_json, version, command_digest_b64u, created_at_ms, updated_at_ms
|
|
1104
|
-
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, 1, ?18, ?19, ?19)`).bind(...scopeValues(this.scope), String(job.operationId), String(job.enrollmentId), String(job.walletId), String(job.walletKeyId), String(job.source.laneId), String(job.source.laneShareEpoch), job.source.revocationEpoch, String(job.target.laneId), String(job.target.laneShareEpoch), String(job.targetMaterialActivationId), job.keyFamily, JSON.stringify(job), JSON.stringify(record.lifecycle), commandDigestB64u, now);
|
|
1105
|
-
}
|
|
1106
|
-
async updateProtocolLifecycle(input) {
|
|
1107
|
-
return d1ChangedRows(await this.database.prepare(`UPDATE ${OPERATION_TABLE} SET lifecycle_json = ?5, version = version + 1, command_digest_b64u = ?6, updated_at_ms = ?7 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?8 AND version = ?9`).bind(...scopeValues(this.scope), JSON.stringify(input.lifecycle), input.commandDigestB64u, this.now(), String(input.operationId), input.expectedVersion).run()) === 1;
|
|
1108
|
-
}
|
|
1109
|
-
async updateEnrollmentLifecycle(input) {
|
|
1110
|
-
return d1ChangedRows(await this.database.prepare(`UPDATE ${ENROLLMENT_TABLE} SET lifecycle_json = ?5, version = version + 1, command_digest_b64u = ?6, updated_at_ms = ?7 WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND enrollment_id = ?8 AND version = ?9`).bind(...scopeValues(this.scope), JSON.stringify(input.lifecycle), input.commandDigestB64u, this.now(), String(input.enrollmentId), input.expectedVersion).run()) === 1;
|
|
1111
|
-
}
|
|
1112
|
-
async getEnrollmentRevocationFenceDigest(enrollmentId) {
|
|
1113
|
-
const row = await this.database.prepare(`SELECT revocation_fence_command_digest_b64u
|
|
1114
|
-
FROM ${ENROLLMENT_TABLE}
|
|
1115
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
1116
|
-
AND enrollment_id = ?5`).bind(...scopeValues(this.scope), String(enrollmentId)).first();
|
|
1117
|
-
if (!row || row.revocation_fence_command_digest_b64u === null) return null;
|
|
1118
|
-
return parseRequiredString(row.revocation_fence_command_digest_b64u, "revocation fence command digest");
|
|
1119
|
-
}
|
|
1120
|
-
async updateEnrollmentRevocationFence(enrollmentId, expectedVersion, commandDigestB64u, lifecycle) {
|
|
1121
|
-
const values = scopeValues(this.scope);
|
|
1122
|
-
try {
|
|
1123
|
-
assertD1Success(firstBatchResult(await this.database.batch([this.database.prepare(`UPDATE ${ENROLLMENT_TABLE}
|
|
1124
|
-
SET lifecycle_json = ?5,
|
|
1125
|
-
version = version + 1,
|
|
1126
|
-
command_digest_b64u = ?6,
|
|
1127
|
-
revocation_fence_command_digest_b64u = ?7,
|
|
1128
|
-
updated_at_ms = ?8
|
|
1129
|
-
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
1130
|
-
AND enrollment_id = ?9 AND version = ?10`).bind(...values, JSON.stringify(lifecycle), commandDigestB64u, commandDigestB64u, this.now(), String(enrollmentId), expectedVersion), this.database.prepare(LANE_CAS_GUARD_SQL)]), 0), "lane enrollment revocation fence");
|
|
1131
|
-
return true;
|
|
1132
|
-
} catch {
|
|
1133
|
-
return false;
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
async putReceipt(operationId, enrollmentId, kind, receipt, commandDigestB64u) {
|
|
1137
|
-
const row = await this.database.prepare(`SELECT receipt_id, receipt_kind, receipt_digest_b64u, receipt_json FROM ${RECEIPT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?5 AND receipt_kind = ?6`).bind(...scopeValues(this.scope), String(operationId), kind).first();
|
|
1138
|
-
const digest = await exactReceiptDigest(kind, receipt);
|
|
1139
|
-
if (row) {
|
|
1140
|
-
if (parseRequiredString(row.receipt_digest_b64u, "receipt digest") === digest && equalLaneRecords(parseJsonRecord(row.receipt_json, "receipt"), receipt)) return {
|
|
1141
|
-
outcome: "replayed",
|
|
1142
|
-
version: 1,
|
|
1143
|
-
commandDigestB64u,
|
|
1144
|
-
value: receipt
|
|
1145
|
-
};
|
|
1146
|
-
return {
|
|
1147
|
-
outcome: "conflict",
|
|
1148
|
-
expectedVersion: null,
|
|
1149
|
-
actualVersion: 1,
|
|
1150
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
1151
|
-
storedCommandDigestB64u: parseRequiredString(row.receipt_digest_b64u, "receipt digest")
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
1154
|
-
const insert = this.database.prepare(`INSERT INTO ${RECEIPT_TABLE} (namespace, org_id, project_id, env_id, receipt_id, enrollment_id, operation_id, receipt_kind, receipt_digest_b64u, receipt_json, created_at_ms) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)`).bind(...scopeValues(this.scope), `${String(operationId)}:${kind}`, String(enrollmentId), String(operationId), kind, digest, JSON.stringify(receipt), this.now());
|
|
1155
|
-
try {
|
|
1156
|
-
assertD1Success(firstBatchResult(await this.database.batch([insert, this.database.prepare(LANE_CAS_GUARD_SQL)]), 0), `lane ${kind} receipt admission`);
|
|
1157
|
-
return {
|
|
1158
|
-
outcome: "applied",
|
|
1159
|
-
version: 1,
|
|
1160
|
-
commandDigestB64u,
|
|
1161
|
-
value: receipt
|
|
1162
|
-
};
|
|
1163
|
-
} catch (error) {
|
|
1164
|
-
const raced = await this.database.prepare(`SELECT receipt_digest_b64u, receipt_json FROM ${RECEIPT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?5 AND receipt_kind = ?6`).bind(...scopeValues(this.scope), String(operationId), kind).first();
|
|
1165
|
-
if (raced && parseRequiredString(raced.receipt_digest_b64u, "receipt digest") === digest) return {
|
|
1166
|
-
outcome: "replayed",
|
|
1167
|
-
version: 1,
|
|
1168
|
-
commandDigestB64u,
|
|
1169
|
-
value: receipt
|
|
1170
|
-
};
|
|
1171
|
-
if (raced) return {
|
|
1172
|
-
outcome: "conflict",
|
|
1173
|
-
expectedVersion: null,
|
|
1174
|
-
actualVersion: 1,
|
|
1175
|
-
requestedCommandDigestB64u: commandDigestB64u,
|
|
1176
|
-
storedCommandDigestB64u: parseRequiredString(raced.receipt_digest_b64u, "receipt digest")
|
|
1177
|
-
};
|
|
1178
|
-
throw error;
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
async readAndVerifyServerRetirementReceipt(product, command) {
|
|
1182
|
-
const row = await this.database.prepare(`SELECT receipt_id, receipt_digest_b64u, receipt_json FROM ${RECEIPT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?5 AND receipt_kind = ?6`).bind(...scopeValues(this.scope), String(product.operationId), serverRetirementReceiptKind(product)).first();
|
|
1183
|
-
if (!row) throw new Error("revoked lane has no persisted server retirement receipt");
|
|
1184
|
-
if (parseRequiredString(row.receipt_id, "server retirement receipt id") !== serverRetirementReceiptId(product)) throw new Error("server retirement receipt id differs from the revoked lane epoch");
|
|
1185
|
-
const receipt = parseLaneServerRetirementReceiptV1(parseJsonRecord(row.receipt_json, "server retirement receipt"));
|
|
1186
|
-
const digest = await verifyServerRetirementReceiptV1({
|
|
1187
|
-
store: this,
|
|
1188
|
-
product,
|
|
1189
|
-
command,
|
|
1190
|
-
receipt
|
|
1191
|
-
});
|
|
1192
|
-
if (parseRequiredString(row.receipt_digest_b64u, "server retirement receipt digest") !== digest || product.revocationReceiptDigestB64u !== digest) throw new Error("persisted server retirement receipt digest is invalid");
|
|
1193
|
-
return receipt;
|
|
1194
|
-
}
|
|
1195
|
-
async verifyStoredRefreshPredecessorRetirements(input) {
|
|
1196
|
-
const retirements = new Map(input.orderedPredecessorRetirements.map((raw) => {
|
|
1197
|
-
const refresh = parseLaneRefreshPredecessorRetirementV1(raw);
|
|
1198
|
-
return [String(refresh.refreshOperationId), refresh];
|
|
1199
|
-
}));
|
|
1200
|
-
let refreshCount = 0;
|
|
1201
|
-
for (const child of input.orderedChildReceipts) {
|
|
1202
|
-
if ((await this.getProtocol(child.operationId))?.value.job.target.operation !== "refresh_lane") continue;
|
|
1203
|
-
refreshCount += 1;
|
|
1204
|
-
const refresh = retirements.get(String(child.operationId));
|
|
1205
|
-
if (!refresh) throw new Error("stored refresh child has no exact predecessor retirement");
|
|
1206
|
-
const product = await this.getProductEpoch({
|
|
1207
|
-
walletId: input.walletId,
|
|
1208
|
-
walletKeyId: child.walletKeyId,
|
|
1209
|
-
laneId: refresh.sourceLaneId,
|
|
1210
|
-
laneShareEpoch: refresh.sourceLaneShareEpoch
|
|
1211
|
-
});
|
|
1212
|
-
const digest = await laneServerRetirementReceiptDigestV1(refresh.retirementReceipt);
|
|
1213
|
-
if (product?.state !== "retired" || product.retirementReason !== "rotation" || product.retirementReceiptDigestB64u !== digest || !mpcMaterialActivationRefsEqual(product.materialActivation, refresh.sourceMaterialActivation)) throw new Error("retired predecessor product differs from its exact receipt");
|
|
1214
|
-
const row = await this.database.prepare(`SELECT receipt_id, receipt_digest_b64u, receipt_json FROM ${RECEIPT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?5 AND receipt_kind = 'lane_refresh_predecessor_retirement'`).bind(...scopeValues(this.scope), String(refresh.refreshOperationId)).first();
|
|
1215
|
-
if (!row || parseRequiredString(row.receipt_id, "refresh predecessor receipt id") !== refreshPredecessorRetirementReceiptId(refresh) || parseRequiredString(row.receipt_digest_b64u, "refresh predecessor receipt digest") !== digest) throw new Error("refresh predecessor receipt persistence is missing or invalid");
|
|
1216
|
-
if (!equalLaneRecords(parseLaneServerRetirementReceiptV1(parseJsonRecord(row.receipt_json, "refresh predecessor receipt")), refresh.retirementReceipt)) throw new Error("refresh predecessor receipt replay differs from persisted receipt");
|
|
1217
|
-
}
|
|
1218
|
-
if (refreshCount !== retirements.size) throw new Error("stored predecessor retirements do not match refresh children exactly");
|
|
1219
|
-
}
|
|
1220
|
-
async readReceipt(operationId, kind) {
|
|
1221
|
-
const row = await this.database.prepare(`SELECT receipt_json FROM ${RECEIPT_TABLE} WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4 AND operation_id = ?5 AND receipt_kind = ?6`).bind(...scopeValues(this.scope), String(operationId), kind).first();
|
|
1222
|
-
if (!row) return null;
|
|
1223
|
-
const receiptRecord = parseJsonRecord(row.receipt_json, "lane receipt");
|
|
1224
|
-
switch (kind) {
|
|
1225
|
-
case "lane_protocol_commit": return parseLaneProtocolCommitReceiptV1(receiptRecord);
|
|
1226
|
-
case "lane_holder_delivery": return parseLaneHolderDeliveryReceiptV1(receiptRecord);
|
|
1227
|
-
case "lane_server_activation": return parseLaneServerActivationReceiptV1(receiptRecord);
|
|
1228
|
-
default: throw new Error(`unknown lane receipt kind ${kind}`);
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
};
|
|
1232
|
-
async function verifyServerRetirementReceiptV1(input) {
|
|
1233
|
-
const protocol = await input.store.getProtocol(input.product.operationId);
|
|
1234
|
-
if (protocol === null) throw new Error("server retirement receipt has no exact protocol operation");
|
|
1235
|
-
const job = protocol.value.job;
|
|
1236
|
-
const receipt = input.receipt;
|
|
1237
|
-
if (receipt.kind === "ed25519_server_retirement_receipt_v1") {
|
|
1238
|
-
if (job.keyFamily !== "ed25519" || input.product.keyFamily !== "ed25519" || protocol.value.lifecycle.state !== "active") throw new Error("Ed25519 server retirement receipt has no active protocol operation");
|
|
1239
|
-
const identity = receipt.identity;
|
|
1240
|
-
if (String(input.product.walletId) !== String(input.command.walletId) || identity.operationId !== input.product.operationId || identity.enrollmentId !== input.product.enrollmentId || identity.walletId !== input.product.walletId || identity.walletKeyId !== input.command.walletKeyId || identity.targetLaneId !== input.command.laneId || identity.targetLaneShareEpoch !== input.command.laneShareEpoch || identity.targetMaterialActivationId !== input.product.targetMaterialActivationId || identity.keyFamily !== "ed25519" || identity.holderParticipantBindingDigestB64u !== input.product.holderParticipant.participantBindingDigestB64u || identity.signingWorkerParticipantBindingDigestB64u !== input.product.signingWorkerParticipant.participantBindingDigestB64u || identity.holderRecipientKeyDigestB64u !== job.targetHolder.hpkePublicKeyDigestB64u || identity.serverRecipientKeyDigestB64u !== job.targetSigningWorker.hpkePublicKeyDigestB64u || identity.transcriptHashB64u !== protocol.value.lifecycle.transcriptHashB64u || identity.protocolCommitReceiptDigestB64u !== protocol.value.lifecycle.protocolCommitReceiptDigestB64u || receipt.revocationEpoch !== input.command.expectedRevocationEpoch || receipt.retirementReason !== retirementReceiptReasonV1(input.command.reason) || receipt.retirementCorrelationId !== input.command.retirementCorrelationId || receipt.retirementRequestDigestB64u !== input.command.retirementRequestDigestB64u || input.product.revocationEpoch !== input.command.expectedRevocationEpoch + 1) throw new Error("Ed25519 server retirement receipt differs from the frozen lane epoch");
|
|
1241
|
-
const digest = await computeEd25519ServerRetirementReceiptDigestV1(receipt);
|
|
1242
|
-
if (receipt.receiptDigestB64u !== digest) throw new Error("Ed25519 server retirement receipt self-digest is invalid");
|
|
1243
|
-
return digest;
|
|
1244
|
-
}
|
|
1245
|
-
if (job.keyFamily !== "ecdsa_secp256k1" || input.product.keyFamily !== "ecdsa_secp256k1") throw new Error("ECDSA server retirement receipt has no exact protocol operation");
|
|
1246
|
-
if (String(input.product.walletId) !== String(input.command.walletId) || String(receipt.manifest.manifestId) !== String(job.targetCapability.manifestId) || receipt.manifest.manifestRevision !== job.targetCapability.manifestRevision || !mpcMaterialActivationRefsEqual(receipt.materialActivation, input.product.materialActivation) || String(receipt.walletKeyId) !== String(input.command.walletKeyId) || String(receipt.laneId) !== String(input.command.laneId) || String(receipt.laneShareEpoch) !== String(input.command.laneShareEpoch) || receipt.revocationEpoch !== input.command.expectedRevocationEpoch || receipt.retirementReason !== retirementReceiptReasonV1(input.command.reason) || String(receipt.retirementCorrelationId) !== String(input.command.retirementCorrelationId) || receipt.retirementRequestDigestB64u !== input.command.retirementRequestDigestB64u || String(receipt.serverGeneration) !== String(job.sourceCapability.serverGeneration) || String(receipt.lifecycleId) !== String(input.product.materialActivation.lifecycleBinding) || input.product.revocationEpoch !== input.command.expectedRevocationEpoch + 1) throw new Error("ECDSA server retirement receipt differs from the frozen lane epoch");
|
|
1247
|
-
const digest = await computeEcdsaServerRetirementReceiptDigestV1(receipt);
|
|
1248
|
-
if (receipt.receiptDigestB64u !== digest) throw new Error("ECDSA server retirement receipt self-digest is invalid");
|
|
1249
|
-
return digest;
|
|
1250
|
-
}
|
|
1251
|
-
async function verifyRefreshPredecessorRetirementV1(input) {
|
|
1252
|
-
const refreshJob = input.refreshProtocol.value.job;
|
|
1253
|
-
if (refreshJob.target.operation !== "refresh_lane" || input.refreshProtocol.value.lifecycle.state !== "ready_for_parent_visibility" || input.previousProtocol === null || input.previousProtocol.value.lifecycle.state !== "active" || input.refresh.refreshOperationId !== refreshJob.operationId || input.refresh.sourceLaneId !== refreshJob.source.laneId || input.refresh.sourceLaneShareEpoch !== refreshJob.source.laneShareEpoch || !mpcMaterialActivationRefsEqual(input.refresh.sourceMaterialActivation, refreshJob.source.materialActivation) || !mpcMaterialActivationRefsEqual(input.refresh.sourceMaterialActivation, input.previous.materialActivation) || input.refresh.retirementEffectBindingDigestB64u !== refreshJob.authorization.ownerLaneRefreshDigestB64u || input.previous.revocationEpoch !== refreshJob.source.revocationEpoch + 1 || input.previous.revocationReason !== "rotation" || input.previous.retirementEffectBindingDigestB64u !== input.refresh.retirementEffectBindingDigestB64u) throw new Error("lane refresh predecessor retirement differs from the admitted source");
|
|
1254
|
-
const receipt = input.refresh.retirementReceipt;
|
|
1255
|
-
const requestDigestB64u = input.refreshProtocol.value.lifecycle.protocolCommitReceiptDigestB64u;
|
|
1256
|
-
if (receipt.retirementReason !== "rotation" || String(receipt.retirementCorrelationId) !== String(refreshJob.operationId) || receipt.retirementRequestDigestB64u !== requestDigestB64u || receipt.revocationEpoch !== refreshJob.source.revocationEpoch) throw new Error("lane refresh predecessor receipt is not bound to the refresh transcript");
|
|
1257
|
-
if (receipt.kind === "ed25519_server_retirement_receipt_v1") {
|
|
1258
|
-
const previousJob = input.previousProtocol.value.job;
|
|
1259
|
-
const identity = receipt.identity;
|
|
1260
|
-
if (refreshJob.keyFamily !== "ed25519" || previousJob.keyFamily !== "ed25519" || input.previous.keyFamily !== "ed25519" || identity.operationId !== input.previous.operationId || identity.enrollmentId !== input.previous.enrollmentId || identity.walletId !== input.previous.walletId || identity.walletKeyId !== input.previous.walletKeyId || identity.targetLaneId !== input.previous.laneId || identity.targetLaneShareEpoch !== input.previous.laneShareEpoch || identity.targetMaterialActivationId !== input.previous.targetMaterialActivationId || identity.holderParticipantBindingDigestB64u !== input.previous.holderParticipant.participantBindingDigestB64u || identity.signingWorkerParticipantBindingDigestB64u !== input.previous.signingWorkerParticipant.participantBindingDigestB64u || identity.holderRecipientKeyDigestB64u !== previousJob.targetHolder.hpkePublicKeyDigestB64u || identity.serverRecipientKeyDigestB64u !== previousJob.targetSigningWorker.hpkePublicKeyDigestB64u || identity.transcriptHashB64u !== input.previousProtocol.value.lifecycle.transcriptHashB64u || identity.protocolCommitReceiptDigestB64u !== input.previousProtocol.value.lifecycle.protocolCommitReceiptDigestB64u || receipt.retiredAtMs < input.previous.revocationRequestedAtMs || receipt.retiredAtMs > input.activatedAtMs) throw new Error("Ed25519 refresh predecessor receipt differs from the active source epoch");
|
|
1261
|
-
const digest = await computeEd25519ServerRetirementReceiptDigestV1(receipt);
|
|
1262
|
-
if (receipt.receiptDigestB64u !== digest) throw new Error("Ed25519 refresh predecessor receipt self-digest is invalid");
|
|
1263
|
-
return {
|
|
1264
|
-
receiptDigestB64u: digest,
|
|
1265
|
-
retiredAtMs: receipt.retiredAtMs
|
|
1266
|
-
};
|
|
1267
|
-
}
|
|
1268
|
-
const previousJob = input.previousProtocol.value.job;
|
|
1269
|
-
const retiredAtMs = Date.parse(receipt.retiredAt);
|
|
1270
|
-
if (refreshJob.keyFamily !== "ecdsa_secp256k1" || previousJob.keyFamily !== "ecdsa_secp256k1" || input.previous.keyFamily !== "ecdsa_secp256k1" || !mpcMaterialActivationRefsEqual(receipt.materialActivation, input.previous.materialActivation) || receipt.walletKeyId !== input.previous.walletKeyId || receipt.laneId !== input.previous.laneId || receipt.laneShareEpoch !== input.previous.laneShareEpoch || receipt.manifest.manifestId !== previousJob.targetCapability.manifestId || receipt.manifest.manifestRevision !== previousJob.targetCapability.manifestRevision || receipt.serverGeneration !== previousJob.sourceCapability.serverGeneration || String(receipt.lifecycleId) !== String(input.previous.materialActivation.lifecycleBinding) || !Number.isFinite(retiredAtMs) || retiredAtMs < input.previous.revocationRequestedAtMs || retiredAtMs > input.activatedAtMs) throw new Error("ECDSA refresh predecessor receipt differs from the active source epoch");
|
|
1271
|
-
const digest = await computeEcdsaServerRetirementReceiptDigestV1(receipt);
|
|
1272
|
-
if (receipt.receiptDigestB64u !== digest) throw new Error("ECDSA refresh predecessor receipt self-digest is invalid");
|
|
1273
|
-
return {
|
|
1274
|
-
receiptDigestB64u: digest,
|
|
1275
|
-
retiredAtMs
|
|
1276
|
-
};
|
|
1277
|
-
}
|
|
1278
|
-
function refreshPredecessorRetirementReceiptId(refresh) {
|
|
1279
|
-
return `${String(refresh.refreshOperationId)}:lane_refresh_predecessor_retirement:${String(refresh.sourceLaneId)}:${String(refresh.sourceLaneShareEpoch)}`;
|
|
1280
|
-
}
|
|
1281
|
-
async function laneServerRetirementReceiptDigestV1(receipt) {
|
|
1282
|
-
switch (receipt.kind) {
|
|
1283
|
-
case "ed25519_server_retirement_receipt_v1": return await computeEd25519ServerRetirementReceiptDigestV1(receipt);
|
|
1284
|
-
case "ecdsa_server_retirement_receipt_v1": return await computeEcdsaServerRetirementReceiptDigestV1(receipt);
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
function retirementReceiptReasonV1(reason) {
|
|
1288
|
-
switch (reason) {
|
|
1289
|
-
case "user_revoked":
|
|
1290
|
-
case "policy_revoked": return "lane_revoked";
|
|
1291
|
-
case "device_compromise": return "device_compromise";
|
|
1292
|
-
case "agent_compromise": return "agent_compromise";
|
|
1293
|
-
case "rotation": return "rotation";
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
function serverRetirementReceiptId(product) {
|
|
1297
|
-
return `${String(product.operationId)}:${serverRetirementReceiptKind(product)}:${String(product.laneId)}:${String(product.laneShareEpoch)}`;
|
|
1298
|
-
}
|
|
1299
|
-
function serverRetirementReceiptKind(product) {
|
|
1300
|
-
switch (product.keyFamily) {
|
|
1301
|
-
case "ed25519": return "ed25519_server_retirement";
|
|
1302
|
-
case "ecdsa_secp256k1": return "ecdsa_server_retirement";
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
async function admissionChildrenMatch(store, children) {
|
|
1306
|
-
for (const child of children) {
|
|
1307
|
-
const stored = await store.getProtocol(child.job.operationId);
|
|
1308
|
-
if (!stored || !equalLaneRecords(stored.value, child)) return false;
|
|
1309
|
-
}
|
|
1310
|
-
return true;
|
|
1311
|
-
}
|
|
1312
|
-
function validateChildrenAgainstManifest(manifest, children) {
|
|
1313
|
-
for (let index = 0; index < manifest.orderedChildren.length; index += 1) {
|
|
1314
|
-
const entry = manifest.orderedChildren[index];
|
|
1315
|
-
const child = children[index];
|
|
1316
|
-
if (!entry || !child) throw new Error(`lane enrollment child ${index} is missing`);
|
|
1317
|
-
if (String(child.job.operationId) !== String(entry.operationId) || String(child.job.enrollmentId) !== String(manifest.enrollmentId) || String(child.job.walletId) !== String(manifest.walletId) || String(child.job.walletKeyId) !== String(entry.walletKeyId) || child.job.keyFamily !== entry.keyFamily || !equalLaneRecords(child.job.authorization, manifest.authorization) || String(child.job.source.laneId) !== String(entry.sourceLaneId) || String(child.job.source.laneShareEpoch) !== String(entry.sourceLaneShareEpoch) || child.job.source.revocationEpoch !== entry.sourceRevocationEpoch || !mpcMaterialActivationRefsEqual(child.job.source.materialActivation, entry.sourceMaterialActivation) || String(child.job.target.laneId) !== String(entry.targetLaneId) || String(child.job.target.laneShareEpoch) !== String(entry.targetLaneShareEpoch) || String(child.job.targetMaterialActivationId) !== String(entry.targetMaterialActivationId) || child.job.targetHolder.participantBindingDigestB64u !== entry.holderParticipantBindingDigestB64u || child.job.targetSigningWorker.participantBindingDigestB64u !== entry.signingWorkerParticipantBindingDigestB64u) throw new Error(`lane enrollment child ${index} does not match manifest`);
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
function assertNeverEnrollmentLifecycle(value) {
|
|
1321
|
-
throw new Error(`Unhandled lane enrollment lifecycle ${JSON.stringify(value)}`);
|
|
1322
|
-
}
|
|
1323
|
-
function resolveReadyEnrollmentLifecycle(current, input, aggregateDigest) {
|
|
1324
|
-
if (current.state === "ready_for_visibility") {
|
|
1325
|
-
if (current.manifestDigestB64u !== input.manifestDigestB64u) return null;
|
|
1326
|
-
return current;
|
|
1327
|
-
}
|
|
1328
|
-
if (current.state === "preparing") {
|
|
1329
|
-
const operationIds = input.orderedChildReceipts.map((child) => child.operationId);
|
|
1330
|
-
const first = operationIds[0];
|
|
1331
|
-
if (!first) return null;
|
|
1332
|
-
const committed = transitionLaneEnrollmentLifecycleV1(current, {
|
|
1333
|
-
action: "mark_committed_completion_required",
|
|
1334
|
-
committedChildOperationIds: [first, ...operationIds.slice(1)],
|
|
1335
|
-
markedAtMs: input.activatedAtMs
|
|
1336
|
-
});
|
|
1337
|
-
if (committed.state !== "committed_completion_required") return null;
|
|
1338
|
-
const ready = transitionLaneEnrollmentLifecycleV1(committed, {
|
|
1339
|
-
action: "mark_ready_for_visibility",
|
|
1340
|
-
aggregateReceiptDigestB64u: aggregateDigest,
|
|
1341
|
-
readyAtMs: input.activatedAtMs
|
|
1342
|
-
});
|
|
1343
|
-
return ready.state === "ready_for_visibility" ? ready : null;
|
|
1344
|
-
}
|
|
1345
|
-
if (current.state === "committed_completion_required") {
|
|
1346
|
-
const ready = transitionLaneEnrollmentLifecycleV1(current, {
|
|
1347
|
-
action: "mark_ready_for_visibility",
|
|
1348
|
-
aggregateReceiptDigestB64u: aggregateDigest,
|
|
1349
|
-
readyAtMs: input.activatedAtMs
|
|
1350
|
-
});
|
|
1351
|
-
return ready.state === "ready_for_visibility" ? ready : null;
|
|
1352
|
-
}
|
|
1353
|
-
return null;
|
|
1354
|
-
}
|
|
1355
|
-
function validateActivationReceiptAgainstManifest(manifest, receipt) {
|
|
1356
|
-
if (manifest.orderedChildren.length !== receipt.orderedChildReceipts.length) throw new Error("aggregate activation child count differs from enrollment manifest");
|
|
1357
|
-
for (let index = 0; index < manifest.orderedChildren.length; index += 1) {
|
|
1358
|
-
const expected = manifest.orderedChildren[index];
|
|
1359
|
-
const actual = receipt.orderedChildReceipts[index];
|
|
1360
|
-
if (!expected || !actual) throw new Error("aggregate activation child order is invalid");
|
|
1361
|
-
if (String(expected.operationId) !== String(actual.operationId) || String(expected.walletKeyId) !== String(actual.walletKeyId) || String(expected.targetLaneId) !== String(actual.targetLaneId) || String(expected.targetLaneShareEpoch) !== String(actual.targetLaneShareEpoch) || String(expected.targetMaterialActivationId) !== String(actual.targetMaterialActivation.activationId)) throw new Error("aggregate activation child differs from enrollment manifest");
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
function assertProtocolCommitReceiptIdentity(protocol, receipt) {
|
|
1365
|
-
const job = protocol.job;
|
|
1366
|
-
if (protocol.lifecycle.state !== "active" && receipt.committedAtMs < protocol.lifecycle.startedAtMs) throw new Error("lane protocol commit receipt predates its admitted operation");
|
|
1367
|
-
if (String(receipt.enrollmentId) !== String(job.enrollmentId) || String(receipt.walletId) !== String(job.walletId) || String(receipt.walletKeyId) !== String(job.walletKeyId) || String(receipt.sourceLaneId) !== String(job.source.laneId) || String(receipt.sourceLaneShareEpoch) !== String(job.source.laneShareEpoch) || receipt.sourceRevocationEpoch !== job.source.revocationEpoch || !mpcMaterialActivationRefsEqual(receipt.sourceMaterialActivation, job.source.materialActivation) || String(receipt.targetLaneId) !== String(job.target.laneId) || String(receipt.targetLaneShareEpoch) !== String(job.target.laneShareEpoch) || String(receipt.targetMaterialActivationId) !== String(job.targetMaterialActivationId) || receipt.keyFamily !== job.keyFamily || receipt.holderRecipientKeyDigestB64u !== job.targetHolder.hpkePublicKeyDigestB64u || receipt.serverRecipientKeyDigestB64u !== job.targetSigningWorker.hpkePublicKeyDigestB64u) throw new Error("lane protocol commit receipt does not match its admitted operation");
|
|
1368
|
-
}
|
|
1369
|
-
function assertHolderDeliveryReceiptIdentity(protocol, receipt, commitReceipt) {
|
|
1370
|
-
const job = protocol.job;
|
|
1371
|
-
if (String(receipt.enrollmentId) !== String(job.enrollmentId) || String(receipt.targetLaneId) !== String(job.target.laneId) || String(receipt.targetLaneShareEpoch) !== String(job.target.laneShareEpoch) || String(receipt.targetMaterialActivationId) !== String(job.targetMaterialActivationId) || receipt.holderParticipantBindingDigestB64u !== job.targetHolder.participantBindingDigestB64u || receipt.holderRecipientKeyDigestB64u !== job.targetHolder.hpkePublicKeyDigestB64u) throw new Error("lane holder delivery receipt does not match its admitted operation");
|
|
1372
|
-
if (protocol.lifecycle.state !== "committed_awaiting_holder_delivery" && protocol.lifecycle.state !== "awaiting_server_activation" && protocol.lifecycle.state !== "ready_for_parent_visibility" && protocol.lifecycle.state !== "active") throw new Error("lane holder delivery receipt is not valid for this lifecycle");
|
|
1373
|
-
if (protocol.lifecycle.transcriptHashB64u !== receipt.transcriptHashB64u) throw new Error("lane holder delivery receipt transcript differs from the committed transcript");
|
|
1374
|
-
if (receipt.holderCiphertextDigestSetB64u !== commitReceipt.targetHolderCiphertextDigestSetB64u || receipt.acknowledgedAtMs < commitReceipt.committedAtMs) throw new Error("lane holder delivery receipt differs from its committed ciphertext");
|
|
1375
|
-
}
|
|
1376
|
-
function assertServerActivationReceiptIdentity(protocol, receipt, commitReceipt, holderReceipt) {
|
|
1377
|
-
const job = protocol.job;
|
|
1378
|
-
if (String(receipt.enrollmentId) !== String(job.enrollmentId) || String(receipt.targetLaneId) !== String(job.target.laneId) || String(receipt.targetLaneShareEpoch) !== String(job.target.laneShareEpoch) || String(receipt.targetMaterialActivation.activationId) !== String(job.targetMaterialActivationId) || receipt.targetMaterialActivation.capability !== job.source.materialActivation.capability || receipt.targetMaterialActivation.materialOwner !== job.source.materialActivation.materialOwner || receipt.targetMaterialActivation.keyBinding !== job.source.materialActivation.keyBinding || receipt.targetMaterialActivation.lifecycleBinding !== job.source.materialActivation.lifecycleBinding || String(receipt.targetMaterialActivation.signingWorker) !== String(job.targetSigningWorker.participantId) || receipt.serverCiphertextDigestSetB64u !== commitReceipt.targetServerCiphertextDigestSetB64u || receipt.activatedAtMs < holderReceipt.acknowledgedAtMs || receipt.signingWorkerParticipantBindingDigestB64u !== job.targetSigningWorker.participantBindingDigestB64u) throw new Error("lane server activation receipt does not match its admitted operation");
|
|
1379
|
-
if (protocol.lifecycle.state !== "awaiting_server_activation" && protocol.lifecycle.state !== "ready_for_parent_visibility" && protocol.lifecycle.state !== "active") throw new Error("lane server activation receipt is not valid for this lifecycle");
|
|
1380
|
-
if (protocol.lifecycle.transcriptHashB64u !== receipt.transcriptHashB64u) throw new Error("lane server activation receipt transcript differs from the committed transcript");
|
|
1381
|
-
}
|
|
1382
|
-
async function exactReceiptDigest(kind, receipt) {
|
|
1383
|
-
switch (kind) {
|
|
1384
|
-
case "lane_protocol_commit":
|
|
1385
|
-
if (receipt.kind !== "lane_protocol_commit_receipt_v1") throw new Error("receipt kind does not match lane protocol commit");
|
|
1386
|
-
return base64UrlEncode(await sha256Bytes(encodeLaneProtocolCommitReceiptV1(receipt)));
|
|
1387
|
-
case "lane_holder_delivery":
|
|
1388
|
-
if (receipt.kind !== "lane_holder_delivery_receipt_v1") throw new Error("receipt kind does not match holder delivery");
|
|
1389
|
-
return base64UrlEncode(await sha256Bytes(encodeLaneHolderDeliveryReceiptV1(receipt)));
|
|
1390
|
-
case "lane_server_activation":
|
|
1391
|
-
if (receipt.kind !== "lane_server_activation_receipt_v1") throw new Error("receipt kind does not match server activation");
|
|
1392
|
-
return base64UrlEncode(await sha256Bytes(encodeLaneServerActivationReceiptV1(receipt)));
|
|
1393
|
-
default: throw new Error(`unknown receipt kind ${kind}`);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
function parseProductEpochRecordV1(raw) {
|
|
1397
|
-
return parseLaneProductEpochRecordV1(parseJsonRecord(raw, "lane product epoch"), "lane product epoch");
|
|
1398
|
-
}
|
|
1399
|
-
async function buildPendingProductEpoch(input) {
|
|
1400
|
-
const target = input.protocol.job.target;
|
|
1401
|
-
const holderParticipant = {
|
|
1402
|
-
kind: "lane_holder_participant_v1",
|
|
1403
|
-
participantId: input.protocol.job.targetHolder.participantId,
|
|
1404
|
-
custodyBindingId: input.protocol.job.targetHolder.custodyBindingId,
|
|
1405
|
-
custodyBindingDigestB64u: input.protocol.job.targetHolder.custodyBindingDigestB64u,
|
|
1406
|
-
hpkePublicKeyB64u: input.protocol.job.targetHolder.hpkePublicKeyB64u,
|
|
1407
|
-
hpkePublicKeyDigestB64u: input.protocol.job.targetHolder.hpkePublicKeyDigestB64u,
|
|
1408
|
-
participantBindingDigestB64u: input.protocol.job.targetHolder.participantBindingDigestB64u
|
|
1409
|
-
};
|
|
1410
|
-
const signingWorkerParticipant = {
|
|
1411
|
-
kind: "signing_worker_participant_v1",
|
|
1412
|
-
participantId: input.protocol.job.targetSigningWorker.participantId,
|
|
1413
|
-
recipientKeyId: input.protocol.job.targetSigningWorker.recipientKeyId,
|
|
1414
|
-
hpkePublicKeyB64u: input.protocol.job.targetSigningWorker.hpkePublicKeyB64u,
|
|
1415
|
-
hpkePublicKeyDigestB64u: input.protocol.job.targetSigningWorker.hpkePublicKeyDigestB64u,
|
|
1416
|
-
participantBindingDigestB64u: input.protocol.job.targetSigningWorker.participantBindingDigestB64u
|
|
1417
|
-
};
|
|
1418
|
-
const participantSetBindingDigestB64u = await computeLaneParticipantSetBindingDigestV1({
|
|
1419
|
-
holderParticipant,
|
|
1420
|
-
signingWorkerParticipant
|
|
1421
|
-
});
|
|
1422
|
-
return buildLaneProductEpochPendingVisibilityV1({
|
|
1423
|
-
walletId: input.protocol.job.walletId,
|
|
1424
|
-
walletKeyId: input.protocol.job.walletKeyId,
|
|
1425
|
-
laneId: target.laneId,
|
|
1426
|
-
laneKind: target.laneKind,
|
|
1427
|
-
laneShareEpoch: target.laneShareEpoch,
|
|
1428
|
-
keyFamily: input.protocol.job.keyFamily,
|
|
1429
|
-
enrollmentId: input.protocol.job.enrollmentId,
|
|
1430
|
-
operationId: input.protocol.job.operationId,
|
|
1431
|
-
targetMaterialActivationId: input.protocol.job.targetMaterialActivationId,
|
|
1432
|
-
materialActivation: input.serverReceipt.targetMaterialActivation,
|
|
1433
|
-
publicIdentityDigestB64u: input.protocolReceipt.publicIdentityDigestB64u,
|
|
1434
|
-
holderParticipant,
|
|
1435
|
-
signingWorkerParticipant,
|
|
1436
|
-
participantSetBindingDigestB64u,
|
|
1437
|
-
revocationEpoch: input.protocol.job.source.revocationEpoch,
|
|
1438
|
-
createdAtMs: input.protocolReceipt.committedAtMs,
|
|
1439
|
-
aggregateManifestDigestB64u: input.manifestDigestB64u,
|
|
1440
|
-
protocolCommitReceiptDigestB64u: base64UrlEncode(await sha256Bytes(encodeLaneProtocolCommitReceiptV1(input.protocolReceipt))),
|
|
1441
|
-
holderDeliveryReceiptDigestB64u: base64UrlEncode(await sha256Bytes(encodeLaneHolderDeliveryReceiptV1(input.holderReceipt))),
|
|
1442
|
-
serverActivationReceiptDigestB64u: base64UrlEncode(await sha256Bytes(encodeLaneServerActivationReceiptV1(input.serverReceipt))),
|
|
1443
|
-
pendingSinceMs: input.serverReceipt.activatedAtMs
|
|
1444
|
-
});
|
|
1445
|
-
}
|
|
1446
|
-
async function activeProductEpochs(store, enrollmentId) {
|
|
1447
|
-
const values = (await store.listEnrollmentProductEpochs(enrollmentId)).filter((value) => value.state === "active");
|
|
1448
|
-
if (values.length === 0) throw new Error("no active product epochs");
|
|
1449
|
-
return values;
|
|
1450
|
-
}
|
|
1451
|
-
async function revokedProductEpochs(store, enrollmentId) {
|
|
1452
|
-
const values = (await store.listEnrollmentProductEpochs(enrollmentId)).filter((value) => value.state === "revoked");
|
|
1453
|
-
if (values.length === 0) throw new Error("no revoked product epochs");
|
|
1454
|
-
return values;
|
|
1455
|
-
}
|
|
1456
|
-
//#endregion
|
|
1457
|
-
export { CloudflareD1LaneLifecycleStore };
|
|
1458
|
-
|
|
1459
|
-
//# sourceMappingURL=d1LaneLifecycleStore.js.map
|