@seams/wallet-server 0.13.1 → 0.15.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.
Files changed (55) hide show
  1. package/artifact-manifest.json +21 -21
  2. package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
  3. package/cloudflare-router-ab/build/deriver-a/index_bg.wasm +0 -0
  4. package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
  5. package/cloudflare-router-ab/build/deriver-b/index_bg.wasm +0 -0
  6. package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
  7. package/cloudflare-router-ab/build/router/index.js +1 -1
  8. package/cloudflare-router-ab/build/router/index_bg.wasm +0 -0
  9. package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
  10. package/cloudflare-router-ab/build/signing-worker/index_bg.wasm +0 -0
  11. package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
  12. package/dist/esm/cloud-host.js +2 -2
  13. package/dist/esm/hosted-wallet-gateway.js +1 -1
  14. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +2 -2
  15. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +1 -1
  16. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +1 -1
  17. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +1 -1
  18. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +1 -1
  19. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +17 -45
  20. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +5 -5
  21. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyStore.js +1 -1
  22. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationSetupSupport.js +1 -17
  23. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +31 -34
  24. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +3 -2
  25. package/dist/esm/router/cloudflare/d1/registration/registrationCompletionWrite.js +20 -0
  26. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerFinalizeRecord.js +1 -1
  27. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAddSignerService.js +2 -2
  28. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +3 -3
  29. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +1 -1
  30. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +1 -1
  31. package/dist/esm/router/cloudflare.js +2562 -2505
  32. package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistration.js +3 -2
  33. package/dist/esm/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationRequestScopedRuntime.js +44 -8
  34. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationRequestScopedCloudflare.js +15 -1
  35. package/dist/esm/router/domains/passkeyCustody/registrationCustodyOutcome.js +8 -8
  36. package/dist/esm/router/domains/passkeyCustody/walletCustodyRegistrationCommit.js +1 -19
  37. package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +7 -7
  38. package/dist/esm/router/framework/registrationSetupDispatch.js +1 -1
  39. package/dist/esm/router/framework/registrationTiming.js +21 -0
  40. package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
  41. package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +2 -2
  42. package/dist/types/shared-ts/src/device-linking/contracts.d.ts +0 -9
  43. package/dist/types/shared-ts/src/utils/routerAbEcdsaDerivation.d.ts +0 -1
  44. package/dist/types/wallet-server/src/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.d.ts +5 -42
  45. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationSetupSupport.d.ts +0 -9
  46. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationService.d.ts +1 -2
  47. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/registrationCompletionWrite.d.ts +5 -0
  48. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.d.ts +5 -0
  49. package/dist/types/wallet-server/src/router/domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistration.d.ts +6 -4
  50. package/dist/types/wallet-server/src/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationRequestScopedCloudflare.d.ts +2 -0
  51. package/dist/types/wallet-server/src/router/domains/passkeyCustody/registrationCustodyOutcome.d.ts +16 -24
  52. package/dist/types/wallet-server/src/router/domains/passkeyCustody/walletCustodyRegistrationAdmission.d.ts +1 -3
  53. package/dist/types/wallet-server/src/router/domains/passkeyCustody/walletCustodyRegistrationCommit.d.ts +7 -17
  54. package/dist/types/wallet-server/src/router/framework/registrationTiming.d.ts +10 -0
  55. package/package.json +1 -1
@@ -7,8 +7,8 @@ import { secureRandomBase64Url } from "../../../../shared-ts/src/utils/secureRan
7
7
  import { ROUTER_AB_ED25519_NORMAL_SIGNING_STATE_KIND } from "../../../../shared-ts/src/utils/signingSessionSeal.js";
8
8
  import { computeAddSignerNearEd25519SigningKeyId, computeRegistrationNearEd25519SigningKeyId } from "../../../../shared-ts/src/utils/registrationIds.js";
9
9
  import { registrationNearEd25519BranchKey } from "../../../../shared-ts/src/utils/registrationSignerPlan.js";
10
- import { thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
11
10
  import "../../../../shared-ts/src/threshold/sessionPolicy.js";
11
+ import { thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
12
12
  import { createRouterApiModule } from "../../../framework/modules.js";
13
13
  import { InMemoryRouterAbEd25519YaoRegistrationStateV1, createRouterAbEd25519YaoRegistrationModule } from "../registration/routerAbEd25519YaoRegistration.js";
14
14
  import { InMemoryRouterAbEd25519YaoRegistrationIntentAuthorizationStateV1 } from "../registration/routerAbEd25519YaoRegistrationIntentAuthorization.js";
@@ -233,7 +233,8 @@ var RouterAbEd25519YaoProductRegistrationRuntime = class {
233
233
  status: 200,
234
234
  admissionRequest: bound.admissionRequest,
235
235
  value: admitted.value,
236
- companionWrite: "not_committed"
236
+ companionWrite: "not_committed",
237
+ executionAdmission: { kind: "stored" }
237
238
  };
238
239
  }
239
240
  /** This runtime issues a receipt at its admission only. */
@@ -1,3 +1,4 @@
1
+ import { recordRegistrationPromiseTiming } from "../../../framework/registrationTiming.js";
1
2
  import { InMemoryRouterAbEd25519YaoRegistrationService, describeRouterAbEd25519YaoRegistrationAdmissionV1 } from "../registration/routerAbEd25519YaoRegistration.js";
2
3
  import { InMemoryRouterAbEd25519YaoRegistrationIntentAuthorizationAdapter, routerAbEd25519YaoCredentialDigestSha256HexV1 } from "../registration/routerAbEd25519YaoRegistrationIntentAuthorization.js";
3
4
  import { resolveRouterAbEd25519YaoActiveCapability } from "../recovery/routerAbEd25519YaoRecovery.js";
@@ -44,12 +45,13 @@ var RouterAbEd25519YaoProductRegistrationRequestScopedRuntime = class {
44
45
  dispatchRoot
45
46
  };
46
47
  }
47
- async bindAndAdmitVerifiedRegistration(input, companionWrite, startedDispatchRoot, mintedSessionId) {
48
+ async bindAndAdmitVerifiedRegistration(input, companionWrite, startedDispatchRoot, mintedSessionId, serverTiming = []) {
48
49
  return await bindAndAdmitVerifiedRegistration({
49
50
  input,
50
51
  companionWrite,
51
52
  startedDispatchRoot,
52
53
  mintedSessionId,
54
+ serverTiming,
53
55
  store: this.input.store,
54
56
  backend: this.input.registrationBackend
55
57
  });
@@ -64,6 +66,7 @@ var RouterAbEd25519YaoProductRegistrationRequestScopedRuntime = class {
64
66
  async executeAdmittedRegistration(input) {
65
67
  return await executeRouterAbEd25519YaoAdmittedRegistrationV1({
66
68
  store: this.input.store,
69
+ admission: input.admission,
67
70
  backend: this.input.registrationBackend,
68
71
  request: input.request,
69
72
  credentialDigestSha256Hex: await routerAbEd25519YaoCredentialDigestSha256HexV1(input.credential),
@@ -170,8 +173,18 @@ async function bindAndAdmitVerifiedRegistration(input) {
170
173
  let backendResult = null;
171
174
  let dispatchRoot = null;
172
175
  for (let attempt = 0; attempt < MAX_DETERMINISTIC_COMMIT_ATTEMPTS; attempt += 1) {
173
- const loaded = await input.store.loadRegistration(lifecycleId);
174
- const bound = await new InMemoryRouterAbEd25519YaoRegistrationIntentAuthorizationAdapter(loaded.state.authorization).bindAndAuthorizeAdmission(input.input);
176
+ const loaded = await recordRegistrationPromiseTiming({
177
+ sink: input.serverTiming,
178
+ name: "yao_admission_state_read",
179
+ startedAtMs: Date.now(),
180
+ promise: input.store.loadRegistration(lifecycleId)
181
+ });
182
+ const bound = await recordRegistrationPromiseTiming({
183
+ sink: input.serverTiming,
184
+ name: "yao_admission_authorization",
185
+ startedAtMs: Date.now(),
186
+ promise: new InMemoryRouterAbEd25519YaoRegistrationIntentAuthorizationAdapter(loaded.state.authorization).bindAndAuthorizeAdmission(input.input)
187
+ });
175
188
  if (!bound.ok) return bound;
176
189
  const service = new InMemoryRouterAbEd25519YaoRegistrationService(input.backend, loaded.state.registration);
177
190
  const preparation = service.prepareAdmit(bound.admissionRequest);
@@ -180,7 +193,11 @@ async function bindAndAdmitVerifiedRegistration(input) {
180
193
  status: 200,
181
194
  admissionRequest: bound.admissionRequest,
182
195
  value: preparation.value,
183
- companionWrite: "not_committed"
196
+ companionWrite: "not_committed",
197
+ executionAdmission: {
198
+ kind: "snapshot",
199
+ authority: routerAbEd25519YaoAdmittedRegistrationAuthorityV1(loaded.state, lifecycleId)
200
+ }
184
201
  };
185
202
  if (preparation.kind === "failed") return preparation.failure;
186
203
  if (dispatchRoot === null) {
@@ -193,7 +210,12 @@ async function bindAndAdmitVerifiedRegistration(input) {
193
210
  message: "registration tenant root was read for another signing root ID"
194
211
  };
195
212
  try {
196
- dispatchRoot = await (started ? started.dispatchRoot : input.backend.resolveRegistrationDispatchRoot(signingRootId));
213
+ dispatchRoot = await recordRegistrationPromiseTiming({
214
+ sink: input.serverTiming,
215
+ name: "yao_admission_root_wait",
216
+ startedAtMs: Date.now(),
217
+ promise: started ? started.dispatchRoot : input.backend.resolveRegistrationDispatchRoot(signingRootId)
218
+ });
197
219
  } catch (error) {
198
220
  return {
199
221
  ok: false,
@@ -204,7 +226,12 @@ async function bindAndAdmitVerifiedRegistration(input) {
204
226
  }
205
227
  }
206
228
  if (backendResult === null) try {
207
- backendResult = await input.backend.admit(bound.admissionRequest, void 0, input.mintedSessionId);
229
+ backendResult = await recordRegistrationPromiseTiming({
230
+ sink: input.serverTiming,
231
+ name: "yao_admission_backend",
232
+ startedAtMs: Date.now(),
233
+ promise: input.backend.admit(bound.admissionRequest, void 0, input.mintedSessionId)
234
+ });
208
235
  } catch (error) {
209
236
  return {
210
237
  ok: false,
@@ -223,12 +250,21 @@ async function bindAndAdmitVerifiedRegistration(input) {
223
250
  });
224
251
  if (!admitted.ok) return admitted;
225
252
  pinRouterAbEd25519YaoRegistrationDispatchRootV1(loaded.state.registration, lifecycleId, dispatchRoot);
226
- if ((await input.store.commitRegistration(loaded, input.companionWrite?.(bound.admissionRequest) ?? null)).kind === "stored") return {
253
+ if ((await recordRegistrationPromiseTiming({
254
+ sink: input.serverTiming,
255
+ name: "yao_admission_commit",
256
+ startedAtMs: Date.now(),
257
+ promise: input.store.commitRegistration(loaded, input.companionWrite?.(bound.admissionRequest) ?? null)
258
+ })).kind === "stored") return {
227
259
  ok: true,
228
260
  status: 200,
229
261
  admissionRequest: bound.admissionRequest,
230
262
  value: admitted.value,
231
- companionWrite: input.companionWrite ? "committed" : "not_committed"
263
+ companionWrite: input.companionWrite ? "committed" : "not_committed",
264
+ executionAdmission: {
265
+ kind: "snapshot",
266
+ authority: routerAbEd25519YaoAdmittedRegistrationAuthorityV1(loaded.state, lifecycleId)
267
+ }
232
268
  };
233
269
  }
234
270
  return {
@@ -184,6 +184,7 @@ async function runExecutionRequest(input, request, trace) {
184
184
  });
185
185
  return await executeRouterAbEd25519YaoAdmittedRegistrationV1({
186
186
  store: input.store,
187
+ admission: { kind: "stored" },
187
188
  backend: input.backend,
188
189
  request,
189
190
  credentialDigestSha256Hex: credential.digestSha256Hex,
@@ -208,7 +209,17 @@ async function executeRouterAbEd25519YaoAdmittedRegistrationV1(input) {
208
209
  resultReconstructionMs: 0
209
210
  };
210
211
  const admissionStartedAt = performance.now();
211
- const authority = routerAbEd25519YaoAdmittedRegistrationAuthorityV1((await input.store.loadRegistration(lifecycleId)).state, lifecycleId);
212
+ const admission = input.admission;
213
+ let authority;
214
+ switch (admission.kind) {
215
+ case "stored":
216
+ authority = routerAbEd25519YaoAdmittedRegistrationAuthorityV1((await input.store.loadRegistration(lifecycleId)).state, lifecycleId);
217
+ break;
218
+ case "snapshot":
219
+ authority = admission.authority;
220
+ break;
221
+ default: return assertNeverAdmissionSource(admission);
222
+ }
212
223
  const timingBeforeRouter = {
213
224
  ...timing,
214
225
  d1AdmissionReadMs: elapsedMs(admissionStartedAt)
@@ -452,6 +463,9 @@ function terminalStateConflictFailure(result) {
452
463
  message: `Yao terminal state is uncertain after a ${result.key} conflict`
453
464
  };
454
465
  }
466
+ function assertNeverAdmissionSource(value) {
467
+ throw new Error(`Unknown registration admission source: ${String(value)}`);
468
+ }
455
469
  //#endregion
456
470
  export { executeRouterAbEd25519YaoAdmittedRegistrationV1, handleRouterAbEd25519YaoRegistrationRequestScopedCloudflareV1, routerAbEd25519YaoRegistrationExecutionTimingEntriesV1 };
457
471
 
@@ -22,19 +22,20 @@ async function reserveRegistrationCustody(input) {
22
22
  store: input.store
23
23
  });
24
24
  if (admitted.kind !== "reserved") return settled(toOutcome(admitted));
25
- return async () => {
26
- try {
27
- return toOutcome(await admitted.commit());
28
- } catch (error) {
29
- return storeFailure(error);
30
- }
25
+ return {
26
+ kind: "prepared",
27
+ outcome: { status: "committed" },
28
+ write: { statements: admitted.statements }
31
29
  };
32
30
  } catch (error) {
33
31
  return settled(storeFailure(error));
34
32
  }
35
33
  }
36
34
  function settled(outcome) {
37
- return () => Promise.resolve(outcome);
35
+ return {
36
+ kind: "settled",
37
+ outcome
38
+ };
38
39
  }
39
40
  function storeFailure(error) {
40
41
  return {
@@ -44,7 +45,6 @@ function storeFailure(error) {
44
45
  }
45
46
  function toOutcome(admitted) {
46
47
  switch (admitted.kind) {
47
- case "committed": return { status: "committed" };
48
48
  case "no_custody_records": return {
49
49
  status: "joined",
50
50
  keyManifestDigestB64u: admitted.keyManifestDigestB64u
@@ -148,25 +148,7 @@ async function reserveWalletCustodyRegistration(input) {
148
148
  kind: "rejected",
149
149
  reason: reserved.reason
150
150
  };
151
- return {
152
- kind: "reserved",
153
- commit: async () => commitOutcome(await reserved.commit())
154
- };
155
- }
156
- function commitOutcome(stored) {
157
- switch (stored.kind) {
158
- case "committed": return {
159
- kind: "committed",
160
- envelopeStoreVersion: stored.envelopeStoreVersion,
161
- recoverySetStoreVersion: stored.recoverySetStoreVersion
162
- };
163
- case "already_exists": return { kind: "already_exists" };
164
- case "custody_already_established": return { kind: "custody_already_established" };
165
- case "inconsistent": return {
166
- kind: "rejected",
167
- reason: stored.reason
168
- };
169
- }
151
+ return reserved;
170
152
  }
171
153
  //#endregion
172
154
  export { reserveWalletCustodyRegistration };
@@ -14,13 +14,7 @@ import { parseHostedWalletSessionOperationCredentialToken, parsePrimaryWalletSes
14
14
  import { normalizeCorsOrigin } from "../../../core/SessionService.js";
15
15
  import { thresholdEcdsaChainTargetFromValue } from "../../../core/thresholdEcdsaChainTarget.js";
16
16
  import { walletIdFromString } from "../../../shared-ts/src/utils/registrationIds.js";
17
- import { deriveImplicitNearAccountIdFromEd25519PublicKey, parseImplicitNearAccountId } from "../../../shared-ts/src/utils/near.js";
18
- import { normalizeRegistrationSignerPlan, registrationSignerSetSelectionFromPlan } from "../../../shared-ts/src/utils/registrationSignerPlan.js";
19
- import { addAuthMethodIntentGrantFromString, addSignerIntentGrantFromString, computeAddAuthMethodIntentDigestB64u, computeAddSignerIntentDigestB64u, normalizeAddAuthMethodIntentCaller } from "../../../shared-ts/src/utils/registrationIntent.js";
20
- import { parsePasskeyCustodyEnvelopeRecord } from "../../../shared-ts/src/passkey-custody/custodyEnvelope.js";
21
- import "../../../shared-ts/src/passkey-custody/index.js";
22
- import { parseRouterAbTraceContextV1 } from "../../../shared-ts/src/utils/routerAbTraceContext.js";
23
- import { recordRegistrationServerTiming, registrationServerTimingHeaders } from "../../cloudflare/d1/registration/d1RegistrationSetupSupport.js";
17
+ import { recordRegistrationServerTiming, registrationServerTimingHeaders } from "../../framework/registrationTiming.js";
24
18
  import { parseRegistrationSetupOperationId } from "../../../shared-ts/src/utils/registrationSetupOperation.js";
25
19
  import { extractBearerCredential, extractRouterApiEnvironmentId } from "../../auth/routerApiKeyAuth.js";
26
20
  import { publishableKeyRoutePrincipal, resolvePublishableKeyApiCredentialAuth, resolveWalletRegistrationContext } from "../../auth/routerApiCredentialAuth.js";
@@ -28,7 +22,13 @@ import { resolveActiveRuntimePolicyScopeForEnvironment, resolveWalletSessionAdmi
28
22
  import { enforceRoutePolicy } from "../../framework/enforceRoutePolicy.js";
29
23
  import { parseRegistrationPreparedSessionSeal } from "./registrationSessionSeal.js";
30
24
  import { routeError, routeJson } from "../../framework/routeResponses.js";
25
+ import { parsePasskeyCustodyEnvelopeRecord } from "../../../shared-ts/src/passkey-custody/custodyEnvelope.js";
26
+ import "../../../shared-ts/src/passkey-custody/index.js";
31
27
  import { computeWalletEcdsaKeyFactsInventoryChallengeDigestB64u } from "../../../shared-ts/src/utils/ecdsaKeyFactsInventory.js";
28
+ import { deriveImplicitNearAccountIdFromEd25519PublicKey, parseImplicitNearAccountId } from "../../../shared-ts/src/utils/near.js";
29
+ import { normalizeRegistrationSignerPlan, registrationSignerSetSelectionFromPlan } from "../../../shared-ts/src/utils/registrationSignerPlan.js";
30
+ import { addAuthMethodIntentGrantFromString, addSignerIntentGrantFromString, computeAddAuthMethodIntentDigestB64u, computeAddSignerIntentDigestB64u, normalizeAddAuthMethodIntentCaller } from "../../../shared-ts/src/utils/registrationIntent.js";
31
+ import { parseRouterAbTraceContextV1 } from "../../../shared-ts/src/utils/routerAbTraceContext.js";
32
32
  //#region src/router/domains/walletRegistration/walletRegistrationRoutes.ts
33
33
  function parseRegistrationTraceContext(headers) {
34
34
  const parsed = parseRouterAbTraceContextV1(headers["x-seams-trace-id"] ?? headers["X-Seams-Trace-Id"]);
@@ -1,4 +1,4 @@
1
- import { recordRegistrationServerTiming, registrationServerTimingHeaders } from "../cloudflare/d1/registration/d1RegistrationSetupSupport.js";
1
+ import { recordRegistrationServerTiming, registrationServerTimingHeaders } from "./registrationTiming.js";
2
2
  //#region src/router/framework/registrationSetupDispatch.ts
3
3
  /** A transient storage fault outlived its retries. The same request can succeed later. */
4
4
  const SETUP_STORAGE_UNAVAILABLE = {
@@ -0,0 +1,21 @@
1
+ //#region src/router/framework/registrationTiming.ts
2
+ function recordRegistrationServerTiming(sink, name, startedAtMs) {
3
+ sink.push([name, Math.max(0, Date.now() - startedAtMs)]);
4
+ }
5
+ /** The `Server-Timing` header of a registration route's recorded waits. */
6
+ function registrationServerTimingHeaders(serverTiming) {
7
+ if (serverTiming.length === 0) return void 0;
8
+ const header = serverTiming.map(([name, durationMs]) => `${name};dur=${Math.max(0, durationMs).toFixed(1)}`).join(", ");
9
+ return { "Server-Timing": header };
10
+ }
11
+ async function recordRegistrationPromiseTiming(args) {
12
+ try {
13
+ return await args.promise;
14
+ } finally {
15
+ recordRegistrationServerTiming(args.sink, args.name, args.startedAtMs);
16
+ }
17
+ }
18
+ //#endregion
19
+ export { recordRegistrationPromiseTiming, recordRegistrationServerTiming, registrationServerTimingHeaders };
20
+
21
+ //# sourceMappingURL=registrationTiming.js.map
@@ -4,9 +4,9 @@ import { sha256DigestB64u } from "../../../../shared-ts/src/utils/canonicalPrimi
4
4
  import { buildEmailOtpWalletAuthAuthority, buildPasskeyWalletAuthAuthority, walletAuthAuthorityRef } from "../../../../shared-ts/src/utils/walletAuthAuthority.js";
5
5
  import { parseLinkedDeviceOwnerAuthorizationRequestV1 } from "../../../../shared-ts/src/device-linking/parsers.js";
6
6
  import { buildWalletSessionCapabilitySubjectsV1, walletSessionCapabilitySubjectsV1Equal } from "../../../../authorization/domain.js";
7
- import { thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
8
7
  import { extractBearerCredential } from "../../../auth/routerApiKeyAuth.js";
9
8
  import { json, jsonFailure, readJson } from "../../../framework/http.js";
9
+ import { thresholdEd25519AuthorityScopeFromWalletAuthAuthority } from "../../../../core/ThresholdService/validation.js";
10
10
  //#region src/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.ts
11
11
  const LINKED_DEVICE_OWNER_AUTHORIZATION_PATH_V1 = "/wallet/device-linking/v1/owner-authorization";
12
12
  /**
@@ -10,10 +10,10 @@ import { buildPasskeyWalletAuthAuthority, walletAuthAuthorityRef } from "../../.
10
10
  import { parseSessionOrigin, parseVerifiedOwnerProofId } from "../../../../authorization/domain.js";
11
11
  import { buildVerifiedWalletOperationEmailOtpFactorResult, buildVerifiedWalletOperationPasskeyFactorResult } from "../../../../authorization/factorEvidence.js";
12
12
  import { findRouteDefinitionById, matchesRouteDefinitionRequest } from "../../../framework/routeDefinitions.js";
13
- import { parsePasskeyCustodyEnvelopeRecord } from "../../../../shared-ts/src/passkey-custody/custodyEnvelope.js";
14
- import "../../../../shared-ts/src/passkey-custody/index.js";
15
13
  import { extractBearerCredential, resolveSourceIpFromFetchHeaders } from "../../../auth/routerApiKeyAuth.js";
16
14
  import { toFetchRouteResponse } from "../../../framework/routeResponses.js";
15
+ import { parsePasskeyCustodyEnvelopeRecord } from "../../../../shared-ts/src/passkey-custody/custodyEnvelope.js";
16
+ import "../../../../shared-ts/src/passkey-custody/index.js";
17
17
  import { readJson } from "../../../framework/http.js";
18
18
  import { isHostWithinRpId, originHostnameOrEmpty } from "../../../../core/authService/webauthnOidcHelpers.js";
19
19
  import { parseRecoveryCodeReservationId } from "../../../../shared-ts/src/wallet-recovery/recoveryCodeReservation.js";
@@ -698,12 +698,6 @@ export type LocalAuthorityInstallationReceiptV1 = {
698
698
  readonly targetFactorVerificationDigestB64u: DigestB64u;
699
699
  readonly installedAtMs: number;
700
700
  };
701
- type RelinkRequiredReasonV1 = {
702
- readonly kind: 'incomplete_migrated_enrollment';
703
- } | {
704
- readonly kind: 'missing_canonical_local_material';
705
- readonly activation: MpcMaterialActivationRef;
706
- };
707
701
  export type LinkIntegrityFailureV1 = {
708
702
  readonly kind: 'authority_id_mismatch';
709
703
  readonly expectedAuthorityId: WalletAuthorityId;
@@ -749,9 +743,6 @@ export type LinkedAuthorityActivationResultV1 = {
749
743
  } | {
750
744
  readonly kind: 'failed_before_commit';
751
745
  readonly reason: LinkPrecommitFailureV1;
752
- } | {
753
- readonly kind: 'relink_required';
754
- readonly reason: RelinkRequiredReasonV1;
755
746
  } | {
756
747
  readonly kind: 'integrity_error';
757
748
  readonly reason: LinkIntegrityFailureV1;
@@ -611,7 +611,6 @@ export declare function sameRouterAbEcdsaRegistrationActivationReceiptV1(left: R
611
611
  export declare function sameRouterAbEcdsaDerivationNormalSigningStateV1(left: RouterAbEcdsaDerivationNormalSigningStateV1, right: RouterAbEcdsaDerivationNormalSigningStateV1): boolean;
612
612
  export declare function sameRouterAbEcdsaDerivationPublicCapabilityV1(left: RouterAbEcdsaDerivationPublicCapabilityV1, right: RouterAbEcdsaDerivationPublicCapabilityV1): boolean;
613
613
  export declare function routerAbEcdsaRerandomizationClientCommitmentV1(contribution32: Uint8Array): Promise<Uint8Array>;
614
- export declare function routerAbEcdsaDerivationContextBindingB64uV1(context: RouterAbEcdsaDerivationStableKeyContextV1): Promise<string>;
615
614
  export declare function routerAbEcdsaDerivationNormalSigningScopeCanonicalBytesV1(scope: RouterAbEcdsaDerivationNormalSigningScopeV1): Uint8Array;
616
615
  export declare function sameRouterAbEcdsaDerivationNormalSigningScopeV1(left: RouterAbEcdsaDerivationNormalSigningScopeV1, right: RouterAbEcdsaDerivationNormalSigningScopeV1): boolean;
617
616
  export declare function routerAbEcdsaDerivationEvmDigestSigningRequestDigestV1(request: RouterAbEcdsaDerivationEvmDigestSigningRequestV1Wire): Promise<RouterAbPublicDigest32V1Wire>;
@@ -41,43 +41,14 @@ export type WalletRecoveryCodeLocatorRecord = {
41
41
  * A registration commit whose recovery-code routes are claimed. `commit`
42
42
  * writes the records, and it needs the wallet that the registration commits.
43
43
  */
44
- export type WalletCustodyRegistrationReservation = Extract<WalletCustodyRegistrationCommitResult, {
45
- kind: 'inconsistent';
46
- }> | {
44
+ export type WalletCustodyRegistrationReservation = {
47
45
  readonly kind: 'reserved';
48
- readonly commit: () => Promise<WalletCustodyRegistrationCommitResult>;
49
- };
50
- export type WalletCustodyRegistrationCommitResult = {
51
- readonly kind: 'committed';
52
- readonly envelopeStoreVersion: string;
53
- readonly recoverySetStoreVersion: string;
54
- }
55
- /**
56
- * This ceremony's own envelope is already stored: the commit was applied
57
- * before, and the caller holding this result is done. Never an overwrite —
58
- * replacing stored custody would strand every key the existing seed controls.
59
- */
60
- | {
46
+ readonly statements: readonly D1PreparedStatementLike[];
47
+ } | {
61
48
  readonly kind: 'already_exists';
62
- readonly key: string;
63
- }
64
- /**
65
- * The wallet already has custody, established by a *different* ceremony —
66
- * its recovery-set key is occupied while this ceremony's envelope key is
67
- * free. This is the losing side of the establish race: two key sets each
68
- * believed they were the wallet's first. The caller must discard this run's
69
- * seed and re-enter as a join of the existing envelope, committing only its
70
- * key set's manifest.
71
- *
72
- * Distinct from `already_exists` because the correct reactions are opposite:
73
- * a repeat is finished, a lost race has a key set still to provision.
74
- */
75
- | {
49
+ } | {
76
50
  readonly kind: 'custody_already_established';
77
- readonly walletId: WalletId;
78
- }
79
- /** The two records describe different wallets. */
80
- | {
51
+ } | {
81
52
  readonly kind: 'inconsistent';
82
53
  readonly reason: string;
83
54
  };
@@ -153,14 +124,6 @@ export declare class CloudflareD1WalletCustodyCommitStore {
153
124
  * may run it beside its other remote effects and write afterwards.
154
125
  */
155
126
  reserveRegistration(commit: WalletCustodyRegistrationCommit): Promise<WalletCustodyRegistrationReservation>;
156
- /**
157
- * Writes the envelope and the recovery set in one transaction.
158
- *
159
- * Both are inserts, never updates: `expectedVersion: null` fails if either
160
- * key already holds a row, so a repeated registration cannot silently replace
161
- * an established wallet's custody.
162
- */
163
- private commitReservedRegistration;
164
127
  /**
165
128
  * Reads a wallet's recovery envelope set. Returns null when absent, and also
166
129
  * when the stored row is not a recovery set — a row that fails its own parser
@@ -47,14 +47,5 @@ type RegistrationIntentSignerBranches = {
47
47
  readonly nearEd25519: RegistrationNearEd25519SignerPlan | null;
48
48
  readonly evmFamilyEcdsa: RegistrationEvmFamilyEcdsaSignerPlan | null;
49
49
  };
50
- export declare function recordRegistrationServerTiming(sink: Array<readonly [string, number]>, name: string, startedAtMs: number): void;
51
- /** The `Server-Timing` header of a registration route's recorded waits. */
52
- export declare function registrationServerTimingHeaders(serverTiming: readonly (readonly [string, number])[]): Record<string, string> | undefined;
53
- export declare function recordRegistrationPromiseTiming<T>(args: {
54
- readonly sink: Array<readonly [string, number]>;
55
- readonly name: string;
56
- readonly startedAtMs: number;
57
- readonly promise: T | Promise<T>;
58
- }): Promise<T>;
59
50
  export {};
60
51
  //# sourceMappingURL=d1RegistrationSetupSupport.d.ts.map
@@ -294,8 +294,7 @@ export declare class CloudflareD1WalletRegistrationService {
294
294
  */
295
295
  private verifyRespondReplayAuthority;
296
296
  private respondEd25519OnlyRegistration;
297
- /**
298
- * Derives the authority-bound Yao admission now that the proof is verified.
297
+ /** Derives the authority-bound Yao admission after proof verification.
299
298
  * Both auth methods take this path — the scope comes from the verified
300
299
  * authority, so Email OTP's `providerUserId` is established rather than
301
300
  * assumed.
@@ -0,0 +1,5 @@
1
+ import type { RegistrationCommitExecution } from './walletRegistrationSessionCommitReceipt';
2
+ import type { RouterAbEd25519YaoPreparedWriteV1 } from '../../../domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPartitionedStateStore';
3
+ /** Custody, home activation and the replay receipt share one durable transaction. */
4
+ export declare function registrationCommitCompletionWrite<T>(execution: RegistrationCommitExecution<T>): RouterAbEd25519YaoPreparedWriteV1 | null;
5
+ //# sourceMappingURL=registrationCompletionWrite.d.ts.map
@@ -1,3 +1,4 @@
1
+ import type { RouterAbEd25519YaoPreparedWriteV1 } from '../../../domains/ed25519Yao/capabilityLifecycle/routerAbEd25519YaoProductRegistrationPartitionedStateStore';
1
2
  import type { WalletRegistrationFinalizeResponse, WalletRegistrationFinalizeSuccess } from '../../../../core/registrationContracts';
2
3
  import type { WalletRegistrationFinalizeAuthMethod } from '../../../../../../shared-ts/src/utils/registrationContracts';
3
4
  import type { RegistrationActivationWrite } from '../../../domains/walletRegistration/walletRegistrationReservation';
@@ -12,15 +13,18 @@ export type WalletRegistrationNearProvisioningFinalizeResponse = WalletRegistrat
12
13
  export type RegistrationCommitExecution<T> = {
13
14
  readonly kind: 'unissued';
14
15
  readonly response: T;
16
+ readonly custodyWrite?: never;
15
17
  } | {
16
18
  readonly kind: 'replayed';
17
19
  readonly response: T;
20
+ readonly custodyWrite?: never;
18
21
  } | {
19
22
  readonly kind: 'session_issued';
20
23
  readonly response: T;
21
24
  readonly issuedAtMs: number;
22
25
  readonly expectedOrigin: string;
23
26
  readonly activation: RegistrationActivationWrite | null;
27
+ readonly custodyWrite: RouterAbEd25519YaoPreparedWriteV1 | null;
24
28
  readonly installationProjection?: never;
25
29
  } | {
26
30
  readonly kind: 'session_issued_with_installation_projection';
@@ -28,6 +32,7 @@ export type RegistrationCommitExecution<T> = {
28
32
  readonly issuedAtMs: number;
29
33
  readonly expectedOrigin: string;
30
34
  readonly activation: RegistrationActivationWrite | null;
35
+ readonly custodyWrite: RouterAbEd25519YaoPreparedWriteV1 | null;
31
36
  readonly installationProjection: WalletRegistrationCommittedInstallationProjectionV1;
32
37
  };
33
38
  /** The home activation that a commit left for the record that completes its operation. */
@@ -59,8 +59,8 @@ export type RouterAbEd25519YaoWalletSessionMintInputV1 = (RouterAbEd25519YaoWall
59
59
  readonly expiresAtMs: number;
60
60
  readonly remainingUses: number;
61
61
  });
62
- /** Admission is immutable. A finalization batch may supply it before consumption. */
63
- export type RouterAbEd25519YaoConsumptionAdmissionV1 = {
62
+ /** Immutable admission may come from the request's committed or batched snapshot. */
63
+ export type RouterAbEd25519YaoRegistrationAdmissionSourceV1 = {
64
64
  readonly kind: 'stored';
65
65
  readonly authority?: never;
66
66
  } | {
@@ -78,7 +78,7 @@ export type RouterAbEd25519YaoProductRegistrationRuntimeV1 = RouterAbEd25519YaoP
78
78
  */
79
79
  startRegistrationDispatchRoot(signingRootId: RouterAbEd25519YaoRegistrationSigningRootIdV1): RouterAbEd25519YaoStartedDispatchRootV1 | null;
80
80
  /** `mintedSessionId` is the session that the registration's setup minted. */
81
- bindAndAdmitVerifiedRegistration(input: RouterAbEd25519YaoVerifiedActivationIntentV1, companionWrite: RouterAbEd25519YaoAdmissionCompanionWriteV1 | null, startedDispatchRoot: RouterAbEd25519YaoStartedDispatchRootV1 | null, mintedSessionId: RouterAbEd25519YaoBytes32V1): Promise<RouterAbEd25519YaoVerifiedRegistrationAdmissionResultV1>;
81
+ bindAndAdmitVerifiedRegistration(input: RouterAbEd25519YaoVerifiedActivationIntentV1, companionWrite: RouterAbEd25519YaoAdmissionCompanionWriteV1 | null, startedDispatchRoot: RouterAbEd25519YaoStartedDispatchRootV1 | null, mintedSessionId: RouterAbEd25519YaoBytes32V1, serverTiming?: Array<readonly [string, number]>): Promise<RouterAbEd25519YaoVerifiedRegistrationAdmissionResultV1>;
82
82
  /**
83
83
  * The receipt of the admission that a registration gets for `request`
84
84
  * over the session that its setup minted. Nothing is stored and nothing
@@ -91,12 +91,13 @@ export type RouterAbEd25519YaoProductRegistrationRuntimeV1 = RouterAbEd25519YaoP
91
91
  * execute route does for its bearer.
92
92
  */
93
93
  executeAdmittedRegistration(input: {
94
+ readonly admission: RouterAbEd25519YaoRegistrationAdmissionSourceV1;
94
95
  readonly request: RouterAbEd25519YaoActivationExecuteRequestV1<'registration'>;
95
96
  readonly credential: string;
96
97
  readonly trace: RouterAbTraceContextV1;
97
98
  }): Promise<RouterAbEd25519YaoTimedRegistrationExecutionResultV1>;
98
99
  bindVerifiedIntent(input: RouterAbEd25519YaoVerifiedActivationIntentV1): Promise<RouterAbEd25519YaoRegistrationIntentBindingResult>;
99
- consumeActivated(request: RouterAbEd25519YaoActivationConsumptionRequestV1, admission: RouterAbEd25519YaoConsumptionAdmissionV1): Promise<RouterAbEd25519YaoActivationConsumptionResultV1>;
100
+ consumeActivated(request: RouterAbEd25519YaoActivationConsumptionRequestV1, admission: RouterAbEd25519YaoRegistrationAdmissionSourceV1): Promise<RouterAbEd25519YaoActivationConsumptionResultV1>;
100
101
  };
101
102
  /** A tenant-root read in flight, with the signing root ID that it was started for. */
102
103
  export type RouterAbEd25519YaoStartedDispatchRootV1 = {
@@ -124,6 +125,7 @@ export type RouterAbEd25519YaoVerifiedRegistrationAdmissionResultV1 = Extract<Ro
124
125
  * runtime has no batch to share: the caller then writes for itself.
125
126
  */
126
127
  readonly companionWrite: 'committed' | 'not_committed';
128
+ readonly executionAdmission: RouterAbEd25519YaoRegistrationAdmissionSourceV1;
127
129
  };
128
130
  export type RouterAbEd25519YaoProductRegistrationCompositionV1 = {
129
131
  readonly kind: 'router_ab_ed25519_yao_product_registration_composition_v1';
@@ -1,3 +1,4 @@
1
+ import type { RouterAbEd25519YaoRegistrationAdmissionSourceV1 } from '../capabilityLifecycle/routerAbEd25519YaoProductRegistration';
1
2
  import type { VerifiedNearRegistrationContinuationV1 } from './routerAbEd25519YaoRegistrationIntentAuthorization';
2
3
  import { type RouterAbEd25519YaoActivationExecuteRequestV1, type RouterAbEd25519YaoActivationResultV1 } from '../../../../../../shared-ts/src/utils/routerAbEd25519Yao';
3
4
  import { type RouterAbTraceContextV1 } from '../../../../../../shared-ts/src/utils/routerAbTraceContext';
@@ -39,6 +40,7 @@ export declare function handleRouterAbEd25519YaoRegistrationRequestScopedCloudfl
39
40
  * the execute request takes it from the signed setup that it just verified.
40
41
  */
41
42
  export declare function executeRouterAbEd25519YaoAdmittedRegistrationV1(input: Pick<RouterAbEd25519YaoRegistrationRequestScopedCloudflareInputV1, 'store' | 'backend'> & {
43
+ readonly admission: RouterAbEd25519YaoRegistrationAdmissionSourceV1;
42
44
  readonly request: RouterAbEd25519YaoRegistrationExecuteRequestV1;
43
45
  readonly credentialDigestSha256Hex: string;
44
46
  readonly credentialDigestMs: number;
@@ -1,33 +1,25 @@
1
+ import type { D1PreparedStatementLike } from '../../../storage/tenantRoute';
1
2
  import type { WalletCustodyRegistrationOutcome } from '../../../../../shared-ts/src/passkey-custody';
2
3
  import type { WalletAuthAuthority } from '../../../../../shared-ts/src/utils/walletAuthAuthority';
3
4
  import type { WalletId } from '../../../../../shared-ts/src/utils/domainIds';
4
5
  import type { WalletCustodyCeremonyCommitPayload } from './walletCustodyRegistrationCommit';
5
6
  import { type VerifiedEmailOtpEnrollmentFacts } from './verifiedCustodyFactor';
6
7
  import type { CloudflareD1WalletCustodyCommitStore } from '../../cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore';
7
- /**
8
- * The whole custody side-effect of one registration leg, in two steps: resolve
9
- * the factor from the authority the leg verified and admit the payload against
10
- * the wallet the leg registers, which claims the recovery-code routes; then
11
- * store the records once that wallet is committed.
12
- *
13
- * **Activation never fails because of custody.** The wallet's registration is
14
- * already committed by the time the records are stored, and the seed exists only in the
15
- * client's worker — so the client is the one party that can retry, re-enter as
16
- * a join, or abandon the run. Failing activation here would leave the server
17
- * registered, the response an error, and the client with no instruction; the
18
- * client cannot be told what happened by an exception it never sees the body
19
- * of. So every outcome is reported, and the caller decides.
20
- *
21
- * That is a deliberate default, not a claim that a wallet without custody is
22
- * fine — it is not, and a client that sees anything but `committed` or
23
- * `not_requested` must act on it rather than treat registration as done.
24
- *
25
- * The outcome shape itself is the wire contract, and lives in shared beside the
26
- * payload it answers.
27
- */
8
+ /** Custody becomes committed only with the registration's durable completion receipt. */
28
9
  type RegistrationCustodyOutcome = WalletCustodyRegistrationOutcome;
29
- /** Stores the admitted custody records. It reports every failure and never throws. */
30
- export type RegistrationCustodyCommit = () => Promise<RegistrationCustodyOutcome>;
10
+ export type RegistrationCustodyReservation = {
11
+ readonly kind: 'prepared';
12
+ readonly outcome: Extract<RegistrationCustodyOutcome, {
13
+ status: 'committed';
14
+ }>;
15
+ readonly write: {
16
+ readonly statements: readonly D1PreparedStatementLike[];
17
+ };
18
+ } | {
19
+ readonly kind: 'settled';
20
+ readonly outcome: RegistrationCustodyOutcome;
21
+ readonly write?: never;
22
+ };
31
23
  /** Admits the custody payload and claims its routes. It never throws either. */
32
24
  export declare function reserveRegistrationCustody(input: {
33
25
  /** Absent when the client did not run a custody ceremony for this leg. */
@@ -38,6 +30,6 @@ export declare function reserveRegistrationCustody(input: {
38
30
  readonly verifiedEmailOtpEnrollment?: VerifiedEmailOtpEnrollmentFacts;
39
31
  readonly nowMs: number;
40
32
  readonly store: CloudflareD1WalletCustodyCommitStore;
41
- }): Promise<RegistrationCustodyCommit>;
33
+ }): Promise<RegistrationCustodyReservation>;
42
34
  export {};
43
35
  //# sourceMappingURL=registrationCustodyOutcome.d.ts.map
@@ -56,9 +56,7 @@ type WalletCustodyRegistrationAdmissionInput = {
56
56
  * An admitted commit with its recovery-code routes claimed, or the outcome
57
57
  * that ends the admission with nothing claimed or written.
58
58
  */
59
- export type WalletCustodyRegistrationAdmission = WalletCustodyRegistrationReserved | Extract<WalletCustodyRegistrationAdmissionOutcome, {
60
- kind: 'rejected' | 'no_custody_records';
61
- }>;
59
+ export type WalletCustodyRegistrationAdmission = WalletCustodyRegistrationReserved | WalletCustodyRegistrationAdmissionOutcome;
62
60
  export declare function admitWalletCustodyRegistrationCommit(input: WalletCustodyRegistrationAdmissionInput): Promise<WalletCustodyRegistrationAdmission>;
63
61
  export {};
64
62
  //# sourceMappingURL=walletCustodyRegistrationAdmission.d.ts.map