@seams/wallet-server 0.10.2 → 0.12.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 +33 -1812
- package/artifact-manifest.json +28 -28
- 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/start-local-role-workers.mjs +3 -0
- package/cloudflare-router-ab/scripts/start-local-wallet-system.mjs +3 -0
- package/dist/esm/cloud-host.js +7 -7
- package/dist/esm/core/ThresholdService/kv.js +1 -218
- package/dist/esm/hosted-wallet-gateway.js +1 -1
- package/dist/esm/index.js +3 -4
- package/dist/esm/localHostedWalletGatewayHandler.js +17 -11
- package/dist/esm/localIntendedYaoFault.js +34 -3
- package/dist/esm/localIntendedYaoRecoveryFault.js +19 -16
- package/dist/esm/localIntendedYaoSigningFault.js +31 -16
- package/dist/esm/router/auth/routerApiKeyAuth.js +1 -13
- package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +3 -3
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.js +19 -0
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +5 -5
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.js +5 -2
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationSetupSupport.js +7 -1
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +29 -4
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationRead.js +6 -3
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +51 -29
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +23 -7
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerFinalizeRecord.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerService.js +2 -2
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +3 -3
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +1 -1
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +1 -1
- package/dist/esm/router/cloudflare-adaptor.js +2 -3
- package/dist/esm/router/cloudflare.js +2470 -2515
- package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistration.js +1 -1
- package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +39 -32
- package/dist/esm/router/framework/registrationSetupDispatch.js +11 -3
- package/dist/esm/router/framework/routeResponses.js +1 -5
- package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
- package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +2 -2
- package/dist/esm/router/transport/fetch/routes/thresholdEd25519.js +51 -24
- package/dist/esm/shared-ts/src/utils/validation.js +5 -1
- package/dist/esm/threshold/session/signingSessionSeal/guards/backends.js +2 -98
- package/dist/esm/threshold/session/signingSessionSeal/idempotencyBackends.js +2 -69
- package/dist/esm/threshold/session/signingSessionSeal/index.js +3 -4
- package/dist/esm/wasm/evm_crypto/pkg/evm_crypto_bg.wasm +0 -0
- package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
- package/dist/esm/wasm/shamir3pass_runtime/pkg/shamir3pass_runtime_bg.wasm +0 -0
- package/dist/types/wallet-server/src/cloud-host.d.ts +1 -0
- package/dist/types/wallet-server/src/core/ThresholdService/kv.d.ts +0 -29
- package/dist/types/wallet-server/src/localHostedWalletGatewayHandler.d.ts +1 -1
- package/dist/types/wallet-server/src/localIntendedYaoFault.d.ts +13 -3
- package/dist/types/wallet-server/src/localIntendedYaoRecoveryFault.d.ts +4 -2
- package/dist/types/wallet-server/src/localIntendedYaoSigningFault.d.ts +4 -2
- package/dist/types/wallet-server/src/router/auth/routerApiKeyAuth.d.ts +0 -8
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecordStore.d.ts +2 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.d.ts +1 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationSetupSupport.d.ts +2 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.d.ts +25 -5
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationRead.d.ts +15 -0
- package/dist/types/wallet-server/src/router/cloudflare-adaptor.d.ts +1 -3
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationInputs.d.ts +2 -0
- package/dist/types/wallet-server/src/router/framework/routeResponses.d.ts +0 -2
- package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/guards/backends.d.ts +1 -16
- package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/idempotencyBackends.d.ts +1 -16
- package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/index.d.ts +5 -6
- package/package.json +2 -9
- package/src/README.md +5 -3
- package/dist/esm/router/cloudflare/runtime/createSelfHostedCloudflareSigningWorker.js +0 -93
- package/dist/esm/router/express-adaptor.js +0 -84
- package/dist/esm/router/express.js +0 -26400
- package/dist/esm/router/node/nodeHostedWalletGateway.js +0 -64
- package/dist/esm/router/node/nodeHostedWalletGatewayCheck.js +0 -163
- package/dist/esm/router/node/nodeHostedWalletGatewayMain.js +0 -120
- package/dist/esm/router/node/nodeHttp.js +0 -79
- package/dist/esm/router/node/nodeSqlite.js +0 -43
- package/dist/esm/router/node/signerSqlMigrations.js +0 -48
- package/dist/esm/storage/syncSqlite.js +0 -79
- package/dist/esm/threshold/session/signingSessionSeal/transport/express.js +0 -75
- package/dist/types/wallet-server/src/router/cloudflare/runtime/createSelfHostedCloudflareSigningWorker.d.ts +0 -23
- package/dist/types/wallet-server/src/router/express-adaptor.d.ts +0 -22
- package/dist/types/wallet-server/src/router/node/nodeHostedWalletGateway.d.ts +0 -34
- package/dist/types/wallet-server/src/router/node/nodeHostedWalletGatewayCheck.d.ts +0 -21
- package/dist/types/wallet-server/src/router/node/nodeHostedWalletGatewayMain.d.ts +0 -2
- package/dist/types/wallet-server/src/router/node/nodeHttp.d.ts +0 -13
- package/dist/types/wallet-server/src/router/node/nodeSqlite.d.ts +0 -22
- package/dist/types/wallet-server/src/router/node/signerSqlMigrations.d.ts +0 -20
- package/dist/types/wallet-server/src/storage/syncSqlite.d.ts +0 -28
- package/dist/types/wallet-server/src/threshold/session/signingSessionSeal/transport/express.d.ts +0 -12
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assertString, requireRecord } from "./shared-ts/src/utils/validation.js";
|
|
2
|
+
import { isLocalIntendedYaoFaultTokenV1, parseLocalIntendedKeptRouterRequestV1 } from "./localIntendedYaoFault.js";
|
|
2
3
|
//#region src/localIntendedYaoSigningFault.ts
|
|
3
4
|
const LOCAL_INTENDED_YAO_SIGNING_FAULT_HEADER_V1 = "x-seams-intended-yao-signing-fault-v1";
|
|
4
5
|
const LOCAL_INTENDED_YAO_SIGNING_FAULT_TOKEN_HEADER_V1 = "x-seams-intended-yao-signing-fault-token-v1";
|
|
5
6
|
const LOCAL_INTENDED_YAO_FAULT_PROOF_HEADER_V1 = "x-seams-intended-yao-fault-proof-v1";
|
|
6
7
|
const ROUTER_AB_ED25519_SIGNING_FINALIZE_PATH_V1 = "/router-ab/ed25519/sign";
|
|
7
|
-
const
|
|
8
|
+
const KEPT_FINALIZE_SCOPE = "signing-finalize";
|
|
9
|
+
const KEPT_FINALIZE_TTL_MS = 600 * 1e3;
|
|
8
10
|
function parseLocalIntendedYaoSigningFaultModeV1(value) {
|
|
9
11
|
switch (value) {
|
|
10
12
|
case "capture_signing_finalize":
|
|
@@ -18,10 +20,11 @@ function parseLocalIntendedYaoSigningFaultTokenV1(value) {
|
|
|
18
20
|
}
|
|
19
21
|
/** The Gateway's Router binding, keeping the first NEAR finalize it carries. */
|
|
20
22
|
var LocalIntendedYaoSigningFaultControllerV1 = class {
|
|
21
|
-
constructor(baseFetch, mode, token) {
|
|
23
|
+
constructor(baseFetch, mode, token, storage) {
|
|
22
24
|
this.baseFetch = baseFetch;
|
|
23
25
|
this.mode = mode;
|
|
24
26
|
this.token = token;
|
|
27
|
+
this.storage = storage;
|
|
25
28
|
this.kept = false;
|
|
26
29
|
}
|
|
27
30
|
async fetch(input, init) {
|
|
@@ -33,7 +36,7 @@ var LocalIntendedYaoSigningFaultControllerV1 = class {
|
|
|
33
36
|
body: await request.clone().text()
|
|
34
37
|
};
|
|
35
38
|
if (this.mode === "withhold_signing_finalize") {
|
|
36
|
-
this.keep({
|
|
39
|
+
await this.keep({
|
|
37
40
|
request: kept,
|
|
38
41
|
original: null
|
|
39
42
|
});
|
|
@@ -44,7 +47,7 @@ var LocalIntendedYaoSigningFaultControllerV1 = class {
|
|
|
44
47
|
}, { status: 409 });
|
|
45
48
|
}
|
|
46
49
|
const response = await this.baseFetch.call(globalThis, request);
|
|
47
|
-
this.keep({
|
|
50
|
+
await this.keep({
|
|
48
51
|
request: kept,
|
|
49
52
|
original: {
|
|
50
53
|
status: response.status,
|
|
@@ -53,9 +56,14 @@ var LocalIntendedYaoSigningFaultControllerV1 = class {
|
|
|
53
56
|
});
|
|
54
57
|
return response;
|
|
55
58
|
}
|
|
56
|
-
keep(finalize) {
|
|
59
|
+
async keep(finalize) {
|
|
60
|
+
await this.storage.insertOrRead({
|
|
61
|
+
scope: KEPT_FINALIZE_SCOPE,
|
|
62
|
+
id: this.token,
|
|
63
|
+
value: finalize,
|
|
64
|
+
expiresAtMs: Date.now() + KEPT_FINALIZE_TTL_MS
|
|
65
|
+
});
|
|
57
66
|
this.kept = true;
|
|
58
|
-
if (!keptFinalizes.has(this.token)) keptFinalizes.set(this.token, finalize);
|
|
59
67
|
}
|
|
60
68
|
outcome() {
|
|
61
69
|
if (!this.kept) return `${this.token}:violated:signing_finalize_not_observed`;
|
|
@@ -63,21 +71,28 @@ var LocalIntendedYaoSigningFaultControllerV1 = class {
|
|
|
63
71
|
}
|
|
64
72
|
};
|
|
65
73
|
/** Sends the finalize kept under `token` to the Router again, exactly. */
|
|
66
|
-
async function releaseLocalIntendedYaoSigningFinalizeV1(router, token) {
|
|
67
|
-
const kept =
|
|
74
|
+
async function releaseLocalIntendedYaoSigningFinalizeV1(router, token, storage) {
|
|
75
|
+
const kept = await storage.take(KEPT_FINALIZE_SCOPE, token);
|
|
68
76
|
if (!kept) return Response.json({ code: "intended_signing_finalize_missing" }, { status: 404 });
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
headers: kept.request.headers.map(([name, value]) => [name, value]),
|
|
73
|
-
body: kept.request.body
|
|
74
|
-
}));
|
|
77
|
+
const request = parseLocalIntendedKeptRouterRequestV1(kept.request);
|
|
78
|
+
const original = parseKeptOriginalReply(kept.original);
|
|
79
|
+
const reply = await router.fetch(request);
|
|
75
80
|
return Response.json({
|
|
76
81
|
status: reply.status,
|
|
77
82
|
body: await reply.text(),
|
|
78
|
-
original
|
|
83
|
+
original
|
|
79
84
|
});
|
|
80
85
|
}
|
|
86
|
+
function parseKeptOriginalReply(value) {
|
|
87
|
+
if (value === null) return null;
|
|
88
|
+
const record = requireRecord(value, "Kept original reply");
|
|
89
|
+
const status = record.status;
|
|
90
|
+
if (typeof status !== "number" || !Number.isInteger(status) || status < 100 || status > 599) throw new Error("Kept original reply status is invalid");
|
|
91
|
+
return {
|
|
92
|
+
status,
|
|
93
|
+
body: assertString(record.body, "Kept original reply body")
|
|
94
|
+
};
|
|
95
|
+
}
|
|
81
96
|
function requestWithoutLocalIntendedYaoSigningFaultHeadersV1(request) {
|
|
82
97
|
const headers = new Headers(request.headers);
|
|
83
98
|
headers.delete(LOCAL_INTENDED_YAO_SIGNING_FAULT_HEADER_V1);
|
|
@@ -32,24 +32,12 @@ function extractRouterApiEnvironmentId(headers) {
|
|
|
32
32
|
if (fallback) return fallback;
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
|
-
function resolveSourceIpFromExpressRequest(input) {
|
|
36
|
-
const forwarded = readHeader(input.headers, "x-forwarded-for");
|
|
37
|
-
const realIp = readHeader(input.headers, "x-real-ip");
|
|
38
|
-
return normalizeSourceIp(forwarded || realIp || String(input.ip || ""));
|
|
39
|
-
}
|
|
40
35
|
function resolveSourceIpFromFetchHeaders(headers) {
|
|
41
36
|
const cfConnecting = readHeader(headers, "cf-connecting-ip");
|
|
42
37
|
const forwarded = readHeader(headers, "x-forwarded-for");
|
|
43
38
|
const realIp = readHeader(headers, "x-real-ip");
|
|
44
39
|
return normalizeSourceIp(cfConnecting || forwarded || realIp);
|
|
45
40
|
}
|
|
46
|
-
function resolveRequestOriginRateLimitKeyFromExpressRequest(input) {
|
|
47
|
-
const sourceIp = resolveSourceIpFromExpressRequest(input);
|
|
48
|
-
if (sourceIp) return `ip:${sourceIp}`;
|
|
49
|
-
const origin = readHeader(input.headers, "origin");
|
|
50
|
-
if (origin) return `origin:${origin}`;
|
|
51
|
-
return "origin:unknown-express";
|
|
52
|
-
}
|
|
53
41
|
function resolveRequestOriginRateLimitKeyFromFetchHeaders(headers) {
|
|
54
42
|
const sourceIp = resolveSourceIpFromFetchHeaders(headers);
|
|
55
43
|
if (sourceIp) return `ip:${sourceIp}`;
|
|
@@ -58,6 +46,6 @@ function resolveRequestOriginRateLimitKeyFromFetchHeaders(headers) {
|
|
|
58
46
|
return "origin:unknown-fetch";
|
|
59
47
|
}
|
|
60
48
|
//#endregion
|
|
61
|
-
export { extractBearerCredential, extractRouterApiEnvironmentId, normalizeSourceIp,
|
|
49
|
+
export { extractBearerCredential, extractRouterApiEnvironmentId, normalizeSourceIp, resolveRequestOriginRateLimitKeyFromFetchHeaders, resolveSourceIpFromFetchHeaders };
|
|
62
50
|
|
|
63
51
|
//# sourceMappingURL=routerApiKeyAuth.js.map
|
|
@@ -6,12 +6,13 @@ import { D1WalletStore } from "../../../../core/d1WalletStore.js";
|
|
|
6
6
|
import { D1WalletAuthMethodStore } from "../../../../core/d1WalletAuthMethodStore.js";
|
|
7
7
|
import { normalizeLogger } from "../../../../core/logger.js";
|
|
8
8
|
import { executeSignedDelegateWithRelayer } from "../../../../delegateAction/index.js";
|
|
9
|
+
import { sha256BytesPortable, toRecordValue } from "./d1RouterApiAuthBoundary.js";
|
|
10
|
+
import { parseD1EcdsaDerivationServerBootstrapResponse, parseD1WalletRegistrationCommittedInstallationProjection, parseD1WalletRegistrationFinalizeReplayResponse } from "../registration/d1RegistrationCeremonyRecords.js";
|
|
9
11
|
import { parseWalletUnlockIssuanceRejectionCode } from "../../../framework/authServicePort.js";
|
|
10
12
|
import { parseWebAuthnAuthenticationCredential } from "../../../auth/webAuthnCredentialCodecs.js";
|
|
11
13
|
import { resolveActiveOwnerWalletExecutionLane, resolveWalletAuthMethodIdForAuthority } from "../../../../core/signingLanes/WalletExecutionLaneProjection.js";
|
|
12
14
|
import { DEFAULT_WALLET_SESSION_TTL_MS } from "../../../../shared-ts/src/threshold/sessionPolicy.js";
|
|
13
15
|
import { createDeviceLinkingOwnerRequestAuthenticatorV1 } from "../../../transport/fetch/routes/deviceLinkingOwnerAuthorization.js";
|
|
14
|
-
import { sha256BytesPortable, toRecordValue } from "./d1RouterApiAuthBoundary.js";
|
|
15
16
|
import { verifyD1LinkedDeviceFreshRevokeProofV1 } from "../wallet/d1WalletAuthMethodBoundary.js";
|
|
16
17
|
import { D1LinkedDeviceAuthorityInstallServiceV1 } from "../deviceLinking/d1LinkedDeviceAuthorityInstallService.js";
|
|
17
18
|
import { D1WalletAuthorityStore } from "../wallet/d1WalletAuthorityStore.js";
|
|
@@ -25,7 +26,6 @@ import { toPublicKeyStringFromSecretKey } from "../../../../core/nearKeys.js";
|
|
|
25
26
|
import { MinimalNearClient } from "../../../../core/rpcClients/near/NearClient.js";
|
|
26
27
|
import { fundImplicitNearAccountWithRelayer } from "../../../../core/nearRelayerAccountProvisioning.js";
|
|
27
28
|
import { createSponsoredNamedNearAccountForOptions } from "../near/d1SponsoredNearAccount.js";
|
|
28
|
-
import { parseD1EcdsaDerivationServerBootstrapResponse, parseD1WalletRegistrationCommittedInstallationProjection, parseD1WalletRegistrationFinalizeReplayResponse } from "../registration/d1RegistrationCeremonyRecords.js";
|
|
29
29
|
import { parseD1WalletAddSignerFinalizeSideEffectRecord } from "../wallet/d1WalletAddSignerFinalizeRecord.js";
|
|
30
30
|
import { dispatchWalletRegistrationSetup } from "../../../framework/registrationSetupDispatch.js";
|
|
31
31
|
import { readActiveWalletSessionCredential, readEd25519WalletSessionSigningRead, readExhaustedWalletSessionCredential, readWalletSessionSigningCandidate } from "./walletSessionCredentialReaders.js";
|
|
@@ -53,8 +53,8 @@ import { D1WalletAuthMethodRevocationReplayStoreV1 } from "../wallet/d1WalletAut
|
|
|
53
53
|
import { CloudflareD1WalletAuthMethodService } from "../wallet/d1WalletAuthMethodService.js";
|
|
54
54
|
import { parseWalletRegistrationSessionCommitReceiptV2 } from "../registration/walletRegistrationSessionCommitReceipt.js";
|
|
55
55
|
import { CloudflareD1WalletRegistrationService } from "../registration/d1WalletRegistrationService.js";
|
|
56
|
-
import { D1WalletRegistrationRead } from "../registration/d1WalletRegistrationRead.js";
|
|
57
56
|
import { CloudflareD1WalletRegistrationCommitStore } from "../registration/d1WalletRegistrationCommitStore.js";
|
|
57
|
+
import { D1WalletRegistrationRead } from "../registration/d1WalletRegistrationRead.js";
|
|
58
58
|
import { CloudflareD1Ed25519YaoLifecycleDecisionStoreV1 } from "../ed25519Yao/d1Ed25519YaoLifecycleDecisionStore.js";
|
|
59
59
|
import { createD1PasskeyCustodyRouteService } from "../passkeyCustody/d1PasskeyCustodyRouteService.js";
|
|
60
60
|
import { CloudflareD1WalletRecoveryGoogleEmailOtpAttemptStore } from "../passkeyCustody/d1WalletRecoveryGoogleEmailOtpAttemptStore.js";
|
package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js
CHANGED
|
@@ -11,9 +11,9 @@ import { buildEmailOtpWalletAuthAuthority, buildPasskeyWalletAuthAuthority, wall
|
|
|
11
11
|
import { walletAuthorityDigestsMatchV1 } from "../../../../shared-ts/src/authorization/walletAuthority.js";
|
|
12
12
|
import { buildWalletSessionLinkedDeviceOwnerAuthorizationV1, parseQrLinkedDeviceSessionPayloadV5 } from "../../../../shared-ts/src/device-linking/parsers.js";
|
|
13
13
|
import { computeLinkedDevicePublicKeyDigestV1 } from "../../../../shared-ts/src/device-linking/requestProof.js";
|
|
14
|
+
import { thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
|
|
14
15
|
import { resolveActiveOwnerWalletExecutionLane, resolveWalletAuthMethodIdForAuthority } from "../../../../core/signingLanes/WalletExecutionLaneProjection.js";
|
|
15
16
|
import "../../../../core/deviceLinking/requestProof.js";
|
|
16
|
-
import { thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
|
|
17
17
|
import { sourceKeyManifestDigestForFamilyV1 } from "../../../../core/deviceLinking/linkedDeviceSessionRecord.js";
|
|
18
18
|
import { LinkedDeviceSourceFamilyUnavailableErrorV1 } from "./d1LinkedDeviceVerifiedLinkSourceReader.js";
|
|
19
19
|
import { linkedDeviceSignerManifestsEqualV1 } from "./d1LinkedDeviceVerifiedLinkBuilder.js";
|
|
@@ -3,8 +3,8 @@ import { base64UrlDecode } from "../../../../shared-ts/src/utils/base64.js";
|
|
|
3
3
|
import "../../../../shared-ts/src/utils/encoders.js";
|
|
4
4
|
import { hasExactKeys } from "../../../../shared-ts/src/utils/exactKeys.js";
|
|
5
5
|
import { failure } from "../../../../shared-ts/src/utils/failure.js";
|
|
6
|
-
import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_ACTIONS, WALLET_EMAIL_OTP_UNLOCK_OPERATION, isWalletEmailOtpLoginOperation } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
|
|
7
6
|
import { isB64uString, nonNegativeSafeInteger, parseJsonObject, positiveSafeInteger } from "../auth/d1RouterApiAuthBoundary.js";
|
|
7
|
+
import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_ACTIONS, WALLET_EMAIL_OTP_UNLOCK_OPERATION, isWalletEmailOtpLoginOperation } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
|
|
8
8
|
import { parseCurrentEmailOtpChallengeRow, parseCurrentEmailOtpGrantRow, parseCurrentEmailOtpUnlockChallengeRow, parseEmailOtpChallengePurpose } from "../../../../core/EmailOtpRecords.js";
|
|
9
9
|
//#region src/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.ts
|
|
10
10
|
function maskEmail(email) {
|
|
@@ -2,8 +2,8 @@ import { normalizeOptionalTrimmedString } from "../../../../shared-ts/src/utils/
|
|
|
2
2
|
import { secureRandomBase64Url } from "../../../../shared-ts/src/utils/secureRandomId.js";
|
|
3
3
|
import { failedVerification, failure } from "../../../../shared-ts/src/utils/failure.js";
|
|
4
4
|
import { validateSecp256k1PublicKey33, verifySecp256k1RecoverableSignatureAgainstPublicKey33 } from "../../../../core/ThresholdService/evmCryptoWasm.js";
|
|
5
|
-
import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_ACTIONS } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
|
|
6
5
|
import { parseD1BoundaryWalletIdResult } from "../auth/d1RouterApiAuthBoundary.js";
|
|
6
|
+
import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_ACTIONS } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
|
|
7
7
|
import { bytesEqual, clampedEmailOtpUnlockTtlMs, decodeFixedBase64Url, emailOtpUnlockChallengeRecord } from "./d1EmailOtpRecords.js";
|
|
8
8
|
//#region src/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.ts
|
|
9
9
|
function errorMessage(error) {
|
|
@@ -3,8 +3,8 @@ import { normalizeOptionalTrimmedString } from "../../../../shared-ts/src/utils/
|
|
|
3
3
|
import { secureRandomBase64Url } from "../../../../shared-ts/src/utils/secureRandomId.js";
|
|
4
4
|
import { failure } from "../../../../shared-ts/src/utils/failure.js";
|
|
5
5
|
import { createServerAllocatedWalletId } from "../../../../shared-ts/src/utils/registrationIds.js";
|
|
6
|
-
import { hashEmailOtpOperationBinding } from "../../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
|
|
7
6
|
import { parseD1BoundaryWalletId, parseD1BoundaryWalletIdResult } from "../auth/d1RouterApiAuthBoundary.js";
|
|
7
|
+
import { hashEmailOtpOperationBinding } from "../../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
|
|
8
8
|
import { abandonedGoogleEmailOtpRegistrationAttemptRecord, expiredGoogleEmailOtpRegistrationAttemptRecord, googleEmailOtpRegistrationOfferForResponse, requireRuntimePolicyScope } from "./d1GoogleEmailOtpRegistrationRecords.js";
|
|
9
9
|
import { googleEmailOtpStaleIdentityMapping, hasDifferentWalletIdentitySubject } from "../identity/d1IdentityRecords.js";
|
|
10
10
|
//#region src/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.ts
|
|
@@ -40,6 +40,25 @@ var D1RegistrationCeremonyRecordStore = class {
|
|
|
40
40
|
prepareGet(scope, id) {
|
|
41
41
|
return this.prepareRead(this.normalizeKey(scope, id));
|
|
42
42
|
}
|
|
43
|
+
/** Load the ceremony's immutable founding identities and their current records together. */
|
|
44
|
+
prepareFoundingRecordsRead(id) {
|
|
45
|
+
const key = this.normalizeKey("ceremony", id);
|
|
46
|
+
return this.database.prepare(`
|
|
47
|
+
SELECT json_extract(ceremony.record_json, '$.foundingWalletAuthorityId') AS authority_id,
|
|
48
|
+
json_extract(ceremony.record_json, '$.foundingWalletAuthMethodId') AS auth_method_id,
|
|
49
|
+
(SELECT record_json FROM wallet_authorities
|
|
50
|
+
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
51
|
+
AND authority_id = json_extract(ceremony.record_json, '$.foundingWalletAuthorityId'))
|
|
52
|
+
AS authority_json,
|
|
53
|
+
(SELECT record_json FROM wallet_auth_methods
|
|
54
|
+
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
55
|
+
AND wallet_auth_method_id = json_extract(ceremony.record_json, '$.foundingWalletAuthMethodId'))
|
|
56
|
+
AS auth_method_json
|
|
57
|
+
FROM registration_ceremony_records AS ceremony
|
|
58
|
+
WHERE namespace = ?1 AND org_id = ?2 AND project_id = ?3 AND env_id = ?4
|
|
59
|
+
AND record_scope = ?5 AND record_id = ?6
|
|
60
|
+
`).bind(...this.bindKey(key));
|
|
61
|
+
}
|
|
43
62
|
async parseGet(scope, id, row) {
|
|
44
63
|
if (!row) return null;
|
|
45
64
|
const parsed = parseStoredRow(row);
|
|
@@ -20,16 +20,16 @@ import { thresholdEcdsaChainTargetFromValue } from "../../../../core/thresholdEc
|
|
|
20
20
|
import { buildWalletEcdsaSignerRecord, parseWalletEd25519SignerRecord } from "../../../../core/d1WalletStore.js";
|
|
21
21
|
import { nearEd25519SigningKeyIdFromString, walletIdFromString } from "../../../../shared-ts/src/utils/registrationIds.js";
|
|
22
22
|
import { registrationPreparationIdFromString } from "../../../../core/types.js";
|
|
23
|
-
import "../../../../shared-ts/src/signing-lanes/index.js";
|
|
24
|
-
import { parsePasskeyCustodyEnvelopeRecord } from "../../../../shared-ts/src/passkey-custody/custodyEnvelope.js";
|
|
25
|
-
import "../../../../shared-ts/src/passkey-custody/index.js";
|
|
26
23
|
import { parseImplicitNearAccountId, parseNamedNearAccountId } from "../../../../shared-ts/src/utils/near.js";
|
|
27
24
|
import { findRegistrationSignerPlanNearEd25519Branch, normalizeAddSignerSelection, normalizeRegistrationSignerPlan, registrationSignerBranchKeyFromString, registrationSignerSetSelectionFromPlan } from "../../../../shared-ts/src/utils/registrationSignerPlan.js";
|
|
25
|
+
import { parseStoredRegistrationSignerPlan, parseStoredWalletRegistrationPreparedContext, storedRegistrationSignerPlansMatch } from "../../../../core/RegistrationCeremonyStore.js";
|
|
26
|
+
import "../../../../shared-ts/src/signing-lanes/index.js";
|
|
28
27
|
import { addAuthMethodIntentGrantFromString, addSignerIntentGrantFromString, normalizeAddAuthMethodIntentCaller } from "../../../../shared-ts/src/utils/registrationIntent.js";
|
|
28
|
+
import { parsePasskeyCustodyEnvelopeRecord } from "../../../../shared-ts/src/passkey-custody/custodyEnvelope.js";
|
|
29
|
+
import "../../../../shared-ts/src/passkey-custody/index.js";
|
|
29
30
|
import { parseEcdsaDerivationPublicIdentity, parseThresholdEd25519AuthorityScope, thresholdEd25519AuthorityScopeFromWalletAuthAuthority, thresholdEd25519AuthorityScopesMatch } from "../../../../core/ThresholdService/validation.js";
|
|
30
|
-
import { toRecordValue } from "../auth/d1RouterApiAuthBoundary.js";
|
|
31
|
-
import { parseStoredRegistrationSignerPlan, parseStoredWalletRegistrationPreparedContext, storedRegistrationSignerPlansMatch } from "../../../../core/RegistrationCeremonyStore.js";
|
|
32
31
|
import { parseStoredRouterAbEcdsaPendingActivationV1 } from "../../../domains/ecdsa/routerAbEcdsaStrictRegistration.js";
|
|
32
|
+
import { toRecordValue } from "../auth/d1RouterApiAuthBoundary.js";
|
|
33
33
|
//#region src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.ts
|
|
34
34
|
function inferRuntimePolicyScopeFromSigningRoot(input) {
|
|
35
35
|
const signingRootId = normalizeOptionalTrimmedString(input.signingRootId);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { normalizeOptionalTrimmedString } from "../../../../shared-ts/src/utils/normalize.js";
|
|
2
2
|
import { isPlainObject } from "../../../../shared-ts/src/utils/validation.js";
|
|
3
|
-
import {
|
|
3
|
+
import { D1RegistrationCeremonyRecordStore } from "./d1RegistrationCeremonyRecordStore.js";
|
|
4
4
|
import { parseD1StoredAddAuthMethodIntent, parseD1StoredAddSignerIntent, parseD1StoredWalletAddAuthMethodCeremony, parseD1StoredWalletAddAuthMethodFinalizeReplay, parseD1StoredWalletAddSignerCeremony, parseD1StoredWalletAddSignerFinalizeReplay, parseD1StoredWalletRegistrationCeremony } from "./d1RegistrationCeremonyRecords.js";
|
|
5
|
+
import { prepareD1RegistrationHomeReservation } from "./d1WalletExecutionAuthority.js";
|
|
5
6
|
import { retryTransientD1 } from "../../../../storage/d1Retry.js";
|
|
6
|
-
import { D1RegistrationCeremonyRecordStore } from "./d1RegistrationCeremonyRecordStore.js";
|
|
7
7
|
//#region src/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.ts
|
|
8
8
|
var CloudflareD1RegistrationCeremonyIntentStore = class {
|
|
9
9
|
constructor(input) {
|
|
@@ -47,6 +47,9 @@ var CloudflareD1RegistrationCeremonyIntentStore = class {
|
|
|
47
47
|
prepareCeremonyRead(registrationCeremonyId) {
|
|
48
48
|
return this.storage.prepareGet("ceremony", registrationCeremonyId);
|
|
49
49
|
}
|
|
50
|
+
prepareFoundingRecordsRead(registrationCeremonyId) {
|
|
51
|
+
return this.storage.prepareFoundingRecordsRead(registrationCeremonyId);
|
|
52
|
+
}
|
|
50
53
|
async parseCeremonyRead(registrationCeremonyId, result) {
|
|
51
54
|
return (await this.parseCeremonySnapshotRead(registrationCeremonyId, result))?.ceremony ?? null;
|
|
52
55
|
}
|
|
@@ -71,6 +71,12 @@ function registrationSignerBranchesFromPlan(plan) {
|
|
|
71
71
|
function recordRegistrationServerTiming(sink, name, startedAtMs) {
|
|
72
72
|
sink.push([name, Math.max(0, Date.now() - startedAtMs)]);
|
|
73
73
|
}
|
|
74
|
+
/** The `Server-Timing` header of a registration route's recorded waits. */
|
|
75
|
+
function registrationServerTimingHeaders(serverTiming) {
|
|
76
|
+
if (serverTiming.length === 0) return void 0;
|
|
77
|
+
const header = serverTiming.map(([name, durationMs]) => `${name};dur=${Math.max(0, durationMs).toFixed(1)}`).join(", ");
|
|
78
|
+
return { "Server-Timing": header };
|
|
79
|
+
}
|
|
74
80
|
async function recordRegistrationPromiseTiming(args) {
|
|
75
81
|
try {
|
|
76
82
|
return await args.promise;
|
|
@@ -79,6 +85,6 @@ async function recordRegistrationPromiseTiming(args) {
|
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
//#endregion
|
|
82
|
-
export { createD1RegistrationRouteTimingRecorder, errorMessage, finishD1RegistrationRouteTiming, recordRegistrationPromiseTiming, recordRegistrationServerTiming, registrationIntentSignerBranches, registrationPreparedContextEcdsaChainTargets, registrationSignerBranchesFromPlan, resolveRegistrationPreparedContextFromPlan, startD1RegistrationRouteTiming };
|
|
88
|
+
export { createD1RegistrationRouteTimingRecorder, errorMessage, finishD1RegistrationRouteTiming, recordRegistrationPromiseTiming, recordRegistrationServerTiming, registrationIntentSignerBranches, registrationPreparedContextEcdsaChainTargets, registrationServerTimingHeaders, registrationSignerBranchesFromPlan, resolveRegistrationPreparedContextFromPlan, startD1RegistrationRouteTiming };
|
|
83
89
|
|
|
84
90
|
//# sourceMappingURL=d1RegistrationSetupSupport.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mpcMaterialActivationRefsEqual, parseWalletId } from "../../../../shared-ts/src/utils/domainIds.js";
|
|
1
|
+
import { mpcMaterialActivationRefsEqual, parseWalletAuthMethodId, parseWalletAuthorityId, parseWalletId } from "../../../../shared-ts/src/utils/domainIds.js";
|
|
2
2
|
import { normalizeOptionalTrimmedString } from "../../../../shared-ts/src/utils/normalize.js";
|
|
3
3
|
import { parseWalletAuthMethodRecordV2, sameWalletAuthMethodRecordV2 } from "../../../../shared-ts/src/utils/walletAuthMethodRecord.js";
|
|
4
4
|
import { parseWalletAuthorityV1 } from "../../../../shared-ts/src/authorization/walletAuthority.js";
|
|
@@ -123,6 +123,30 @@ function canExtendFoundingAuthorityWithEd25519(existing, next) {
|
|
|
123
123
|
const nextEcdsa = next.signerActivations.ecdsa;
|
|
124
124
|
return existing.signerActivations.keyFamilies.length === 1 && existing.signerActivations.keyFamilies[0] === "ecdsa_secp256k1" && next.signerActivations.keyFamilies.length === 2 && next.signerActivations.keyFamilies[0] === "ed25519" && next.signerActivations.keyFamilies[1] === "ecdsa_secp256k1" && existingEcdsa !== void 0 && nextEcdsa !== void 0 && sameWalletEcdsaSignerActivationV1(existingEcdsa, nextEcdsa) && foundingAuthorityIdentityMatches(existing, next) && next.updatedAtMs >= existing.updatedAtMs;
|
|
125
125
|
}
|
|
126
|
+
function parseRegistrationFoundingRead(result) {
|
|
127
|
+
if (!result.success) throw new Error("Registration founding records read failed");
|
|
128
|
+
const row = result.results?.[0];
|
|
129
|
+
if (!row) return null;
|
|
130
|
+
const authorityId = parseWalletAuthorityId(row.authority_id);
|
|
131
|
+
const authMethodId = parseWalletAuthMethodId(row.auth_method_id);
|
|
132
|
+
if (!authorityId.ok || !authMethodId.ok) throw new Error("Registration founding identity is invalid");
|
|
133
|
+
return {
|
|
134
|
+
kind: "snapshot",
|
|
135
|
+
records: {
|
|
136
|
+
walletAuthorityId: authorityId.value,
|
|
137
|
+
walletAuthMethodId: authMethodId.value,
|
|
138
|
+
authorityRow: row.authority_json === null ? null : { record_json: row.authority_json },
|
|
139
|
+
authMethodRow: row.auth_method_json === null ? null : { record_json: row.auth_method_json }
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function readFoundingRecords(database, scope, founding) {
|
|
144
|
+
if (founding === null) return Promise.resolve(null);
|
|
145
|
+
switch (founding.kind) {
|
|
146
|
+
case "read": return readStoredFoundingRecords(database, scope, founding.ids);
|
|
147
|
+
case "snapshot": return Promise.resolve(founding.records);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
126
150
|
async function readStoredFoundingRecords(database, scope, ids) {
|
|
127
151
|
const authorityRead = database.prepare(`SELECT record_json
|
|
128
152
|
FROM wallet_authorities
|
|
@@ -196,7 +220,8 @@ function prepareFoundingStatements(input) {
|
|
|
196
220
|
if (!authMethodRow) statements.push(prepareD1WalletAuthMethodV2PutStatement({
|
|
197
221
|
database: input.database,
|
|
198
222
|
scope: input.scope,
|
|
199
|
-
record: foundingAuthMethod
|
|
223
|
+
record: foundingAuthMethod,
|
|
224
|
+
insertOnly: true
|
|
200
225
|
}));
|
|
201
226
|
return statements;
|
|
202
227
|
}
|
|
@@ -224,7 +249,7 @@ var CloudflareD1WalletRegistrationCommitStore = class {
|
|
|
224
249
|
walletId: authority.walletId,
|
|
225
250
|
rpId: authority.rpId,
|
|
226
251
|
credentialIdB64u: authority.credentialIdB64u
|
|
227
|
-
}) : void 0,
|
|
252
|
+
}) : void 0, readFoundingRecords(this.database, this.scope, founding)]);
|
|
228
253
|
return this.commit.bind(this, authority, stored);
|
|
229
254
|
}
|
|
230
255
|
async claimPasskeyAhead(input) {
|
|
@@ -336,6 +361,6 @@ function isEd25519Signer(signer) {
|
|
|
336
361
|
return signer.version === "wallet_signer_ed25519_v1";
|
|
337
362
|
}
|
|
338
363
|
//#endregion
|
|
339
|
-
export { CloudflareD1WalletRegistrationCommitStore };
|
|
364
|
+
export { CloudflareD1WalletRegistrationCommitStore, parseRegistrationFoundingRead };
|
|
340
365
|
|
|
341
366
|
//# sourceMappingURL=d1WalletRegistrationCommitStore.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseRouterAbEd25519YaoRegistrationAdmissionReadV1 } from "../../../domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPartitionedStateStore.js";
|
|
2
|
+
import { parseRegistrationFoundingRead } from "./d1WalletRegistrationCommitStore.js";
|
|
2
3
|
//#region src/router/cloudflare/d1/registration/d1WalletRegistrationRead.ts
|
|
3
4
|
/** Read admission and immutable finalization state from one D1 snapshot. */
|
|
4
5
|
var D1WalletRegistrationRead = class {
|
|
@@ -42,16 +43,18 @@ var D1WalletRegistrationRead = class {
|
|
|
42
43
|
ceremonies.prepareCeremonyRead(home.ceremonyId),
|
|
43
44
|
this.decisions.prepareRead(home.ceremonyId),
|
|
44
45
|
this.passkeyClaims.prepareHeldPasskeyClaimRead(home.ceremonyId),
|
|
45
|
-
this.yaoRecords.prepareRead(home.ceremonyId)
|
|
46
|
+
this.yaoRecords.prepareRead(home.ceremonyId),
|
|
47
|
+
ceremonies.prepareFoundingRecordsRead(home.ceremonyId)
|
|
46
48
|
]);
|
|
47
|
-
const [homeRead, operationRead, ceremonyRead, decisionRead, passkeyClaimRead, yaoRead] = results;
|
|
48
|
-
if (results.length !==
|
|
49
|
+
const [homeRead, operationRead, ceremonyRead, decisionRead, passkeyClaimRead, yaoRead, foundingRead] = results;
|
|
50
|
+
if (results.length !== 7 || !homeRead || !operationRead || !ceremonyRead || !decisionRead || !passkeyClaimRead || !yaoRead || !foundingRead) throw new Error("Registration finalization D1 batch returned incomplete results");
|
|
49
51
|
const admission = await this.authority.admitHomeRead(home, homeRead);
|
|
50
52
|
if (!admission.ok) return admission;
|
|
51
53
|
if (!ceremonyRead.success) throw new Error("Registration ceremony D1 read failed");
|
|
52
54
|
return {
|
|
53
55
|
ok: true,
|
|
54
56
|
operation: this.operations.parseReadResult(operationRead),
|
|
57
|
+
readFounding: parseRegistrationFoundingRead.bind(void 0, foundingRead),
|
|
55
58
|
decision: this.decisions.parseRead(home.ceremonyId, decisionRead),
|
|
56
59
|
heldPasskeyClaim: this.passkeyClaims.parseHeldPasskeyClaimRead(passkeyClaimRead),
|
|
57
60
|
readCeremony: ceremonies.parseCeremonyRead.bind(ceremonies, home.ceremonyId, ceremonyRead),
|
|
@@ -20,34 +20,34 @@ import { buildActiveWalletAuthorityV1, buildWalletSignerActivationSetV1, compute
|
|
|
20
20
|
import { ROUTER_AB_ED25519_NORMAL_SIGNING_STATE_KIND } from "../../../../shared-ts/src/utils/signingSessionSeal.js";
|
|
21
21
|
import { normalizeThresholdEd25519ParticipantIds } from "../../../../shared-ts/src/threshold/participants.js";
|
|
22
22
|
import { nearEd25519SigningKeyIdFromString, registrationEd25519AuthorityScopeFromAuthority, walletIdFromString } from "../../../../shared-ts/src/utils/registrationIds.js";
|
|
23
|
-
import {
|
|
24
|
-
import "../../../../shared-ts/src/passkey-custody/index.js";
|
|
23
|
+
import { admitRegistrationReservationHome, cancelRegistrationHome } from "../../../domains/walletRegistration/walletRegistrationReservation.js";
|
|
25
24
|
import { parseImplicitNearAccountId, parseNamedNearAccountId } from "../../../../shared-ts/src/utils/near.js";
|
|
26
25
|
import { registrationNearEd25519BranchKey } from "../../../../shared-ts/src/utils/registrationSignerPlan.js";
|
|
26
|
+
import { buildStoredWalletRegistrationEvmFamilyEcdsaFinalizedBranch, buildStoredWalletRegistrationNearEd25519YaoAuthorizedBranch, findStoredWalletRegistrationEvmFamilyEcdsaBranch, findStoredWalletRegistrationNearEd25519YaoBranch, replaceStoredWalletRegistrationSignerBranch, storedRegistrationAuthoritiesMatch, verifiedRegistrationCeremonyAuthority } from "../../../../core/RegistrationCeremonyStore.js";
|
|
27
27
|
import { registrationIntentGrantFromString } from "../../../../shared-ts/src/utils/registrationIntent.js";
|
|
28
|
+
import { walletCustodyCeremonyCommitPayloadFromWire } from "../../../../shared-ts/src/passkey-custody/ceremonyCommitPayload.js";
|
|
29
|
+
import "../../../../shared-ts/src/passkey-custody/index.js";
|
|
30
|
+
import { parseEcdsaDerivationPublicIdentity, thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
|
|
28
31
|
import { createRouterAbTraceContextV1 } from "../../../../shared-ts/src/utils/routerAbTraceContext.js";
|
|
32
|
+
import { routerAbEcdsaStrictRegistrationRequestBindingJson } from "../../../domains/ecdsa/routerAbEcdsaStrictRegistration.js";
|
|
33
|
+
import { buildD1EcdsaWalletKeysFromBootstrap, buildD1WalletEcdsaSignerRecords, buildD1WalletRecord, parseWalletIdForIntent, thresholdEcdsaChainTargetsEqual } from "./d1RegistrationCeremonyRecords.js";
|
|
34
|
+
import { createD1RegistrationRouteTimingRecorder, errorMessage, finishD1RegistrationRouteTiming, recordRegistrationPromiseTiming, recordRegistrationServerTiming, registrationSignerBranchesFromPlan, startD1RegistrationRouteTiming } from "./d1RegistrationSetupSupport.js";
|
|
29
35
|
import { buildTenantRootIdentityFromAuthenticatedDeploymentV1 } from "../../../../shared-ts/src/tenant-root/tenantRootIdentity.js";
|
|
30
36
|
import { DEFAULT_WALLET_SESSION_TTL_MS } from "../../../../shared-ts/src/threshold/sessionPolicy.js";
|
|
31
|
-
import { parseEcdsaDerivationPublicIdentity, thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
|
|
32
37
|
import { walletAuthAuthorityFromRegistrationAuthority, walletRegistrationFinalizeAuthMethodFromAuthority } from "../wallet/d1WalletAuthMethodBoundary.js";
|
|
33
38
|
import { buildRouterAbEd25519YaoRegistrationCapabilityRecordV1 } from "../../../domains/ed25519Yao/recovery/routerAbEd25519YaoRecovery.js";
|
|
34
39
|
import { buildRouterAbEd25519YaoProductAdmissionRequestV1, projectRouterAbEd25519YaoExactWalletSession } from "../../../domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistration.js";
|
|
35
40
|
import { routerAbEd25519YaoRegistrationExecutionTimingEntriesV1 } from "../../../domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationRequestScopedCloudflare.js";
|
|
36
41
|
import { runRouterAbEd25519YaoRegistrationSideEffectV2, throwIfRouterAbEd25519YaoRetryableSideEffectFailureV1 } from "../../../domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationSideEffectBoundary.js";
|
|
37
42
|
import { buildYaoEd25519WalletSignerRecord, ed25519NearPublicKeyFromBytes, implicitNearAccountIdFromEd25519PublicKeyBytes } from "../ed25519Yao/d1Ed25519YaoWalletSigner.js";
|
|
38
|
-
import { buildStoredWalletRegistrationEvmFamilyEcdsaFinalizedBranch, buildStoredWalletRegistrationNearEd25519YaoAuthorizedBranch, findStoredWalletRegistrationEvmFamilyEcdsaBranch, findStoredWalletRegistrationNearEd25519YaoBranch, replaceStoredWalletRegistrationSignerBranch, storedRegistrationAuthoritiesMatch, verifiedRegistrationCeremonyAuthority } from "../../../../core/RegistrationCeremonyStore.js";
|
|
39
|
-
import { routerAbEcdsaStrictRegistrationRequestBindingJson } from "../../../domains/ecdsa/routerAbEcdsaStrictRegistration.js";
|
|
40
|
-
import { buildD1EcdsaWalletKeysFromBootstrap, buildD1WalletEcdsaSignerRecords, buildD1WalletRecord, parseWalletIdForIntent, thresholdEcdsaChainTargetsEqual } from "./d1RegistrationCeremonyRecords.js";
|
|
41
43
|
import { deriveThresholdEcdsaKeyHandle } from "../../../../shared-ts/src/utils/thresholdEcdsaKeyHandle.js";
|
|
42
44
|
import { isTransientD1Error, retryTransientD1 } from "../../../../storage/d1Retry.js";
|
|
43
|
-
import { admitRegistrationReservationHome, cancelRegistrationHome } from "../../../domains/walletRegistration/walletRegistrationReservation.js";
|
|
44
45
|
import { listThresholdEcdsaKeyIdentityTargetsForUser } from "../../../../core/authService/thresholdEcdsaKeyInventory.js";
|
|
45
46
|
import { routerAbEd25519YaoLifecycleDecisionLookupV1, routerAbEd25519YaoLifecycleDecisionV1 } from "../../../domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoLifecycleDecision.js";
|
|
46
47
|
import { reserveRegistrationCustody } from "../../../domains/passkeyCustody/registrationCustodyOutcome.js";
|
|
47
48
|
import { resolveTenantRootIdentityV1 } from "../../../domains/tenantRoot/tenantRootIdentityResolution.js";
|
|
48
49
|
import { walletRegistrationOperationPreparedFromCeremony } from "./d1WalletRegistrationPreparation.js";
|
|
49
50
|
import { computeWalletRegistrationSetupDigestB64u, parseWalletRegistrationSetupClaims, verifySignedWalletRegistrationSetup, verifyWalletRegistrationSetupClaims } from "../../../domains/walletRegistration/walletRegistrationSetupPayload.js";
|
|
50
|
-
import { createD1RegistrationRouteTimingRecorder, errorMessage, finishD1RegistrationRouteTiming, recordRegistrationPromiseTiming, recordRegistrationServerTiming, registrationSignerBranchesFromPlan, startD1RegistrationRouteTiming } from "./d1RegistrationSetupSupport.js";
|
|
51
51
|
import { projectWalletRegistrationSessionCommitReceiptV2, registrationCommitActivation, registrationReplayAuthMethodFields, replayedRegistrationCommit, unissuedRegistrationCommit } from "./walletRegistrationSessionCommitReceipt.js";
|
|
52
52
|
import { assertDirectWalletSessionOwnerProof, buildRegistrationOwnerProof, issueDirectRegistrationEstablishedEcdsaSession, issueDirectRegistrationEstablishedEd25519Session, projectCurrentNearRegistrationSession, replayDirectRegistrationEstablishedEcdsaSession, replayDirectRegistrationEstablishedEd25519Session, walletSessionPrincipalId } from "./walletRegistrationEstablishedSessionIssuer.js";
|
|
53
53
|
import { commitWalletRegistration } from "./d1WalletRegistrationInitialSession.js";
|
|
@@ -2154,7 +2154,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2154
2154
|
}, effectivePrepared, source, args.serverTiming, initialSessionPlan, args.lifecycleDecision, args.heldPasskeyClaim, {
|
|
2155
2155
|
kind: "snapshot",
|
|
2156
2156
|
authority: args.readYaoAdmission()
|
|
2157
|
-
});
|
|
2157
|
+
}, args.readFounding());
|
|
2158
2158
|
if (!execution.ok) return unissuedRegistrationCommit(throwIfRouterAbEd25519YaoRetryableSideEffectFailureV1(execution));
|
|
2159
2159
|
const finalized = execution.finalized;
|
|
2160
2160
|
if (finalized.kind !== "near_ed25519") {
|
|
@@ -2357,22 +2357,29 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2357
2357
|
};
|
|
2358
2358
|
const admissionStartedAtMs = Date.now();
|
|
2359
2359
|
const operationKey = `near-provisioning:${input.registrationCeremonyId}:${input.idempotencyKey}`;
|
|
2360
|
-
const initial = await
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2360
|
+
const [initial, requestFingerprintBytes] = await Promise.all([recordRegistrationPromiseTiming({
|
|
2361
|
+
sink: serverTiming,
|
|
2362
|
+
name: "near_finalize_initial_read",
|
|
2363
|
+
startedAtMs: admissionStartedAtMs,
|
|
2364
|
+
promise: this.registrationRead.readFinalization({
|
|
2365
|
+
ceremonyId: verified.claims.registrationCeremonyId,
|
|
2366
|
+
walletId: walletIdFromString(verified.claims.walletId)
|
|
2367
|
+
}, operationKey)
|
|
2368
|
+
}), recordRegistrationPromiseTiming({
|
|
2369
|
+
sink: serverTiming,
|
|
2370
|
+
name: "near_finalize_fingerprint",
|
|
2371
|
+
startedAtMs: Date.now(),
|
|
2372
|
+
promise: sha256BytesUtf8(alphabetizeStringify({
|
|
2373
|
+
version: "wallet_registration_near_provisioning_digest_v1",
|
|
2374
|
+
registrationCeremonyId: input.registrationCeremonyId,
|
|
2375
|
+
setupDigestB64u: verified.claims.setupDigestB64u,
|
|
2376
|
+
idempotencyKey: input.idempotencyKey,
|
|
2377
|
+
ed25519: input.ed25519,
|
|
2378
|
+
emailOtpEnrollment: input.emailOtpEnrollment
|
|
2379
|
+
}))
|
|
2380
|
+
})]);
|
|
2365
2381
|
if (!initial.ok) return initial;
|
|
2366
|
-
const
|
|
2367
|
-
const requestFingerprint = base64UrlEncode(await sha256BytesUtf8(alphabetizeStringify({
|
|
2368
|
-
version: "wallet_registration_near_provisioning_digest_v1",
|
|
2369
|
-
registrationCeremonyId: input.registrationCeremonyId,
|
|
2370
|
-
setupDigestB64u: verified.claims.setupDigestB64u,
|
|
2371
|
-
idempotencyKey: input.idempotencyKey,
|
|
2372
|
-
ed25519: input.ed25519,
|
|
2373
|
-
emailOtpEnrollment: input.emailOtpEnrollment
|
|
2374
|
-
})));
|
|
2375
|
-
recordRegistrationServerTiming(serverTiming, "near_finalize_fingerprint", fingerprintStartedAtMs);
|
|
2382
|
+
const requestFingerprint = base64UrlEncode(requestFingerprintBytes);
|
|
2376
2383
|
const sideEffectStartedAtMs = Date.now();
|
|
2377
2384
|
let preparedCeremony = null;
|
|
2378
2385
|
const run = await runRouterAbEd25519YaoRegistrationSideEffectV2(this.registrationRead.operations, {
|
|
@@ -2403,7 +2410,8 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2403
2410
|
preparedCeremony: () => preparedCeremony,
|
|
2404
2411
|
lifecycleDecision: initial.decision,
|
|
2405
2412
|
heldPasskeyClaim: initial.heldPasskeyClaim,
|
|
2406
|
-
readYaoAdmission: initial.readYaoAdmission
|
|
2413
|
+
readYaoAdmission: initial.readYaoAdmission,
|
|
2414
|
+
readFounding: initial.readFounding
|
|
2407
2415
|
}),
|
|
2408
2416
|
projectReceipt: (execution) => projectWalletRegistrationSessionCommitReceiptV2({
|
|
2409
2417
|
operation: "near_provisioning",
|
|
@@ -2553,6 +2561,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2553
2561
|
const ceremony = input.ceremony;
|
|
2554
2562
|
const stored = storedRespondEd25519DeferredWork(ceremony.signerState);
|
|
2555
2563
|
let authority;
|
|
2564
|
+
const authorityStartedAtMs = Date.now();
|
|
2556
2565
|
if (stored) {
|
|
2557
2566
|
const replayAuthority = await this.verifyRespondReplayAuthority({
|
|
2558
2567
|
ceremony,
|
|
@@ -2586,6 +2595,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2586
2595
|
};
|
|
2587
2596
|
authority = verified.authority;
|
|
2588
2597
|
}
|
|
2598
|
+
recordRegistrationServerTiming(input.serverTiming, "respond_authority_verify", authorityStartedAtMs);
|
|
2589
2599
|
if (authority.walletId !== ceremony.intent.walletId) return {
|
|
2590
2600
|
ok: false,
|
|
2591
2601
|
code: "scope_mismatch",
|
|
@@ -2597,12 +2607,14 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2597
2607
|
code: "not_configured",
|
|
2598
2608
|
message: "Ed25519 Yao registration is unavailable"
|
|
2599
2609
|
};
|
|
2610
|
+
const requestStartedAtMs = Date.now();
|
|
2600
2611
|
const admissionRequest = stored ? stored.admissionRequest : await buildRespondEd25519AdmissionRequest({
|
|
2601
2612
|
ceremony,
|
|
2602
2613
|
branch: input.branch,
|
|
2603
2614
|
authority,
|
|
2604
2615
|
signingWorkerId: runtime.signingWorkerId
|
|
2605
2616
|
});
|
|
2617
|
+
recordRegistrationServerTiming(input.serverTiming, "yao_admission_request", requestStartedAtMs);
|
|
2606
2618
|
const verifiedAuthority = authority;
|
|
2607
2619
|
const branchKey = input.branch.branchKey;
|
|
2608
2620
|
const ceremonyStore = this.getRegistrationCeremonyIntentStore();
|
|
@@ -2620,6 +2632,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2620
2632
|
})]
|
|
2621
2633
|
}
|
|
2622
2634
|
});
|
|
2635
|
+
const bindStartedAtMs = Date.now();
|
|
2623
2636
|
const admitted = await runtime.bindAndAdmitVerifiedRegistration({
|
|
2624
2637
|
kind: "verified_registration_intent",
|
|
2625
2638
|
ownershipGeneration: input.ownershipGeneration,
|
|
@@ -2631,6 +2644,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2631
2644
|
expected: input.snapshot,
|
|
2632
2645
|
next: authorizedCeremony(bound)
|
|
2633
2646
|
}), input.startedDispatchRoot, requireRegistrationEd25519YaoMint(ceremony).sessionId);
|
|
2647
|
+
recordRegistrationServerTiming(input.serverTiming, "yao_admission_bind", bindStartedAtMs);
|
|
2634
2648
|
if (!admitted.ok) return {
|
|
2635
2649
|
ok: false,
|
|
2636
2650
|
code: admitted.code,
|
|
@@ -2638,6 +2652,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2638
2652
|
};
|
|
2639
2653
|
if (!stored && admitted.companionWrite === "not_committed") {
|
|
2640
2654
|
const next = authorizedCeremony(admitted.admissionRequest);
|
|
2655
|
+
const commitStartedAtMs = Date.now();
|
|
2641
2656
|
try {
|
|
2642
2657
|
await ceremonyStore.commitEcdsaClaim({
|
|
2643
2658
|
expected: input.snapshot,
|
|
@@ -2647,6 +2662,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2647
2662
|
const committed = await ceremonyStore.getCeremony(ceremony.registrationCeremonyId);
|
|
2648
2663
|
if (!committed || alphabetizeStringify(committed) !== alphabetizeStringify(next)) throw error;
|
|
2649
2664
|
}
|
|
2665
|
+
recordRegistrationServerTiming(input.serverTiming, "respond_ceremony_commit", commitStartedAtMs);
|
|
2650
2666
|
}
|
|
2651
2667
|
if (!stored && input.waitUntil && verifiedAuthority.kind === "passkey") input.waitUntil(this.walletRegistrationCommitStore.claimPasskeyAhead({
|
|
2652
2668
|
registrationCeremonyId: ceremony.registrationCeremonyId,
|
|
@@ -2901,7 +2917,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
2901
2917
|
}, prepared, {
|
|
2902
2918
|
kind: "stored_ceremony",
|
|
2903
2919
|
ceremony: activatedCeremony
|
|
2904
|
-
}, [], { kind: "separate" }, null, null, { kind: "stored" });
|
|
2920
|
+
}, [], { kind: "separate" }, null, null, { kind: "stored" }, null);
|
|
2905
2921
|
if (!execution.ok) return unissuedRegistrationCommit(throwIfRouterAbEd25519YaoRetryableSideEffectFailureV1(execution));
|
|
2906
2922
|
const commit = execution.finalized;
|
|
2907
2923
|
if (commit.kind !== "evm_family_ecdsa") {
|
|
@@ -3237,7 +3253,7 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
3237
3253
|
};
|
|
3238
3254
|
}
|
|
3239
3255
|
}
|
|
3240
|
-
async executeWalletRegistrationFinalize(request, prepared, source, serverTiming, initialSessionPlan, lifecycleDecision, heldPasskeyClaim, yaoAdmission) {
|
|
3256
|
+
async executeWalletRegistrationFinalize(request, prepared, source, serverTiming, initialSessionPlan, lifecycleDecision, heldPasskeyClaim, yaoAdmission, founding) {
|
|
3241
3257
|
const finalizeTiming = createD1RegistrationRouteTimingRecorder("wallets_register_finalize");
|
|
3242
3258
|
const totalTiming = startD1RegistrationRouteTiming("registerFinalizeTotalMs");
|
|
3243
3259
|
let startedCustody = null;
|
|
@@ -3476,7 +3492,10 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
3476
3492
|
sink: serverTiming,
|
|
3477
3493
|
name: "near_finalize_authority_reserve",
|
|
3478
3494
|
startedAtMs: Date.now(),
|
|
3479
|
-
promise: this.walletRegistrationCommitStore.reserveAuthority(ceremonyAuthority, heldPasskeyClaim,
|
|
3495
|
+
promise: this.walletRegistrationCommitStore.reserveAuthority(ceremonyAuthority, heldPasskeyClaim, founding ?? {
|
|
3496
|
+
kind: "read",
|
|
3497
|
+
ids: prepared
|
|
3498
|
+
})
|
|
3480
3499
|
})]);
|
|
3481
3500
|
if (activationConsumption.status === "rejected") throw activationConsumption.reason;
|
|
3482
3501
|
if (authorityReservation.status === "rejected") throw authorityReservation.reason;
|
|
@@ -3605,7 +3624,10 @@ var CloudflareD1WalletRegistrationService = class {
|
|
|
3605
3624
|
} else {
|
|
3606
3625
|
custodyReservation = reserveCustody();
|
|
3607
3626
|
startedCustody = custodyReservation;
|
|
3608
|
-
commitWallet = await this.walletRegistrationCommitStore.reserveAuthority(ceremonyAuthority, null,
|
|
3627
|
+
commitWallet = await this.walletRegistrationCommitStore.reserveAuthority(ceremonyAuthority, null, {
|
|
3628
|
+
kind: "read",
|
|
3629
|
+
ids: prepared
|
|
3630
|
+
});
|
|
3609
3631
|
}
|
|
3610
3632
|
if (yaoDecisionFound?.kind === "decided_otherwise") return {
|
|
3611
3633
|
ok: false,
|