@interop/wallet-core 0.62.0 → 0.65.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 (312) hide show
  1. package/README.md +41 -16
  2. package/dist/clientAnnex/credentialAnchoredGenesis.d.ts +46 -26
  3. package/dist/clientAnnex/credentialAnchoredGenesis.d.ts.map +1 -1
  4. package/dist/clientAnnex/credentialAnchoredGenesis.js +91 -39
  5. package/dist/clientAnnex/credentialAnchoredGenesis.js.map +1 -1
  6. package/dist/clientAnnex/establish.d.ts +55 -34
  7. package/dist/clientAnnex/establish.d.ts.map +1 -1
  8. package/dist/clientAnnex/establish.js +102 -56
  9. package/dist/clientAnnex/establish.js.map +1 -1
  10. package/dist/clientAnnex/forget.d.ts +16 -2
  11. package/dist/clientAnnex/forget.d.ts.map +1 -1
  12. package/dist/clientAnnex/forget.js +11 -9
  13. package/dist/clientAnnex/forget.js.map +1 -1
  14. package/dist/clientAnnex/forgetLast.d.ts +62 -18
  15. package/dist/clientAnnex/forgetLast.d.ts.map +1 -1
  16. package/dist/clientAnnex/forgetLast.js +92 -26
  17. package/dist/clientAnnex/forgetLast.js.map +1 -1
  18. package/dist/clientAnnex/gc.d.ts +3 -2
  19. package/dist/clientAnnex/gc.d.ts.map +1 -1
  20. package/dist/clientAnnex/gc.js +7 -7
  21. package/dist/clientAnnex/gc.js.map +1 -1
  22. package/dist/clientAnnex/heal.d.ts +38 -5
  23. package/dist/clientAnnex/heal.d.ts.map +1 -1
  24. package/dist/clientAnnex/heal.js +346 -236
  25. package/dist/clientAnnex/heal.js.map +1 -1
  26. package/dist/clientAnnex/index.d.ts +21 -5
  27. package/dist/clientAnnex/index.d.ts.map +1 -1
  28. package/dist/clientAnnex/index.js +24 -5
  29. package/dist/clientAnnex/index.js.map +1 -1
  30. package/dist/clientAnnex/ladder.d.ts +58 -0
  31. package/dist/clientAnnex/ladder.d.ts.map +1 -1
  32. package/dist/clientAnnex/ladder.js +222 -33
  33. package/dist/clientAnnex/ladder.js.map +1 -1
  34. package/dist/clientAnnex/ladderAnchored.d.ts +148 -22
  35. package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -1
  36. package/dist/clientAnnex/ladderAnchored.js +391 -346
  37. package/dist/clientAnnex/ladderAnchored.js.map +1 -1
  38. package/dist/clientAnnex/log.d.ts +162 -43
  39. package/dist/clientAnnex/log.d.ts.map +1 -1
  40. package/dist/clientAnnex/log.js +423 -192
  41. package/dist/clientAnnex/log.js.map +1 -1
  42. package/dist/clientAnnex/mend.d.ts +12 -6
  43. package/dist/clientAnnex/mend.d.ts.map +1 -1
  44. package/dist/clientAnnex/mend.js +26 -12
  45. package/dist/clientAnnex/mend.js.map +1 -1
  46. package/dist/clientAnnex/recoveryLadderAnchored.d.ts +6 -4
  47. package/dist/clientAnnex/recoveryLadderAnchored.d.ts.map +1 -1
  48. package/dist/clientAnnex/recoveryLadderAnchored.js +56 -35
  49. package/dist/clientAnnex/recoveryLadderAnchored.js.map +1 -1
  50. package/dist/clientAnnex/spaceCapability.d.ts +123 -0
  51. package/dist/clientAnnex/spaceCapability.d.ts.map +1 -0
  52. package/dist/clientAnnex/spaceCapability.js +152 -0
  53. package/dist/clientAnnex/spaceCapability.js.map +1 -0
  54. package/dist/clientAnnex/stages.d.ts +63 -0
  55. package/dist/clientAnnex/stages.d.ts.map +1 -0
  56. package/dist/clientAnnex/stages.js +64 -0
  57. package/dist/clientAnnex/stages.js.map +1 -0
  58. package/dist/clientAnnex/zcap.d.ts +1 -1
  59. package/dist/clientAnnex/zcap.d.ts.map +1 -1
  60. package/dist/clientAnnex/zcap.js +42 -35
  61. package/dist/clientAnnex/zcap.js.map +1 -1
  62. package/dist/clients/policy.d.ts +15 -1
  63. package/dist/clients/policy.d.ts.map +1 -1
  64. package/dist/clients/policy.js +12 -6
  65. package/dist/clients/policy.js.map +1 -1
  66. package/dist/clients/revocation.d.ts +18 -10
  67. package/dist/clients/revocation.d.ts.map +1 -1
  68. package/dist/clients/revocation.js +13 -5
  69. package/dist/clients/revocation.js.map +1 -1
  70. package/dist/clients/rosterPolicy.d.ts +10 -2
  71. package/dist/clients/rosterPolicy.d.ts.map +1 -1
  72. package/dist/clients/rosterPolicy.js +41 -24
  73. package/dist/clients/rosterPolicy.js.map +1 -1
  74. package/dist/descriptors/acquire.d.ts.map +1 -1
  75. package/dist/descriptors/acquire.js +6 -23
  76. package/dist/descriptors/acquire.js.map +1 -1
  77. package/dist/descriptors/cipher.d.ts.map +1 -1
  78. package/dist/descriptors/cipher.js +5 -0
  79. package/dist/descriptors/cipher.js.map +1 -1
  80. package/dist/descriptors/errors.d.ts +43 -0
  81. package/dist/descriptors/errors.d.ts.map +1 -0
  82. package/dist/descriptors/errors.js +45 -0
  83. package/dist/descriptors/errors.js.map +1 -0
  84. package/dist/descriptors/index.d.ts +5 -0
  85. package/dist/descriptors/index.d.ts.map +1 -1
  86. package/dist/descriptors/index.js +5 -0
  87. package/dist/descriptors/index.js.map +1 -1
  88. package/dist/enrollment/enrollment.d.ts +37 -10
  89. package/dist/enrollment/enrollment.d.ts.map +1 -1
  90. package/dist/enrollment/enrollment.js +52 -15
  91. package/dist/enrollment/enrollment.js.map +1 -1
  92. package/dist/genesis/accountGenesis.d.ts +42 -11
  93. package/dist/genesis/accountGenesis.d.ts.map +1 -1
  94. package/dist/genesis/accountGenesis.js +80 -22
  95. package/dist/genesis/accountGenesis.js.map +1 -1
  96. package/dist/genesis/index.d.ts +3 -1
  97. package/dist/genesis/index.d.ts.map +1 -1
  98. package/dist/genesis/index.js +3 -1
  99. package/dist/genesis/index.js.map +1 -1
  100. package/dist/identity/agents.d.ts +17 -1
  101. package/dist/identity/agents.d.ts.map +1 -1
  102. package/dist/identity/agents.js +23 -7
  103. package/dist/identity/agents.js.map +1 -1
  104. package/dist/identity/index.d.ts +3 -1
  105. package/dist/identity/index.d.ts.map +1 -1
  106. package/dist/identity/index.js +3 -1
  107. package/dist/identity/index.js.map +1 -1
  108. package/dist/index.d.ts +6 -3
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js +6 -3
  111. package/dist/index.js.map +1 -1
  112. package/dist/keyring/index.d.ts +2 -1
  113. package/dist/keyring/index.d.ts.map +1 -1
  114. package/dist/keyring/index.js +2 -1
  115. package/dist/keyring/index.js.map +1 -1
  116. package/dist/keyring/record.d.ts.map +1 -1
  117. package/dist/keyring/record.js +3 -6
  118. package/dist/keyring/record.js.map +1 -1
  119. package/dist/keyring/unlockSpace.d.ts +14 -5
  120. package/dist/keyring/unlockSpace.d.ts.map +1 -1
  121. package/dist/keyring/unlockSpace.js +31 -36
  122. package/dist/keyring/unlockSpace.js.map +1 -1
  123. package/dist/keys/index.d.ts +10 -6
  124. package/dist/keys/index.d.ts.map +1 -1
  125. package/dist/keys/index.js +9 -5
  126. package/dist/keys/index.js.map +1 -1
  127. package/dist/keys/rosterLogStore.d.ts +12 -11
  128. package/dist/keys/rosterLogStore.d.ts.map +1 -1
  129. package/dist/keys/rosterLogStore.js +15 -13
  130. package/dist/keys/rosterLogStore.js.map +1 -1
  131. package/dist/keys/rosterStore.d.ts +3 -6
  132. package/dist/keys/rosterStore.d.ts.map +1 -1
  133. package/dist/keys/rosterStore.js +10 -9
  134. package/dist/keys/rosterStore.js.map +1 -1
  135. package/dist/keys/spaceEpochs.d.ts.map +1 -1
  136. package/dist/keys/spaceEpochs.js +2 -3
  137. package/dist/keys/spaceEpochs.js.map +1 -1
  138. package/dist/keys/userKeyRoster.d.ts +57 -7
  139. package/dist/keys/userKeyRoster.d.ts.map +1 -1
  140. package/dist/keys/userKeyRoster.js +222 -17
  141. package/dist/keys/userKeyRoster.js.map +1 -1
  142. package/dist/keys/userKeyRosterCascade.d.ts +7 -6
  143. package/dist/keys/userKeyRosterCascade.d.ts.map +1 -1
  144. package/dist/keys/userKeyRosterCascade.js +7 -6
  145. package/dist/keys/userKeyRosterCascade.js.map +1 -1
  146. package/dist/keys/wasLabelsStore.d.ts +9 -2
  147. package/dist/keys/wasLabelsStore.d.ts.map +1 -1
  148. package/dist/keys/wasLabelsStore.js +14 -6
  149. package/dist/keys/wasLabelsStore.js.map +1 -1
  150. package/dist/log.d.ts +7 -2
  151. package/dist/log.d.ts.map +1 -1
  152. package/dist/log.js +6 -1
  153. package/dist/log.js.map +1 -1
  154. package/dist/recovery/index.d.ts +12 -8
  155. package/dist/recovery/index.d.ts.map +1 -1
  156. package/dist/recovery/index.js +11 -7
  157. package/dist/recovery/index.js.map +1 -1
  158. package/dist/recovery/recoveryCode.d.ts +27 -7
  159. package/dist/recovery/recoveryCode.d.ts.map +1 -1
  160. package/dist/recovery/recoveryCode.js +18 -6
  161. package/dist/recovery/recoveryCode.js.map +1 -1
  162. package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
  163. package/dist/recovery/recoveryDelegation.js +21 -34
  164. package/dist/recovery/recoveryDelegation.js.map +1 -1
  165. package/dist/recovery/recoveryWebvh.d.ts +75 -63
  166. package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
  167. package/dist/recovery/recoveryWebvh.js +127 -116
  168. package/dist/recovery/recoveryWebvh.js.map +1 -1
  169. package/dist/request/classify.d.ts +32 -8
  170. package/dist/request/classify.d.ts.map +1 -1
  171. package/dist/request/classify.js +39 -14
  172. package/dist/request/classify.js.map +1 -1
  173. package/dist/request/ephemeralExchange.d.ts +1 -6
  174. package/dist/request/ephemeralExchange.d.ts.map +1 -1
  175. package/dist/request/ephemeralExchange.js.map +1 -1
  176. package/dist/request/onboarding.d.ts.map +1 -1
  177. package/dist/request/onboarding.js +2 -2
  178. package/dist/request/onboarding.js.map +1 -1
  179. package/dist/request/parse.d.ts.map +1 -1
  180. package/dist/request/parse.js +2 -3
  181. package/dist/request/parse.js.map +1 -1
  182. package/dist/resourceLog/controller.d.ts +34 -12
  183. package/dist/resourceLog/controller.d.ts.map +1 -1
  184. package/dist/resourceLog/controller.js +79 -86
  185. package/dist/resourceLog/controller.js.map +1 -1
  186. package/dist/resourceLog/document.d.ts +182 -0
  187. package/dist/resourceLog/document.d.ts.map +1 -0
  188. package/dist/resourceLog/document.js +159 -0
  189. package/dist/resourceLog/document.js.map +1 -0
  190. package/dist/resourceLog/errors.d.ts +47 -8
  191. package/dist/resourceLog/errors.d.ts.map +1 -1
  192. package/dist/resourceLog/errors.js +54 -8
  193. package/dist/resourceLog/errors.js.map +1 -1
  194. package/dist/resourceLog/index.d.ts +7 -3
  195. package/dist/resourceLog/index.d.ts.map +1 -1
  196. package/dist/resourceLog/index.js +7 -3
  197. package/dist/resourceLog/index.js.map +1 -1
  198. package/dist/resourceLog/ladderRungs.d.ts +35 -0
  199. package/dist/resourceLog/ladderRungs.d.ts.map +1 -0
  200. package/dist/resourceLog/ladderRungs.js +352 -0
  201. package/dist/resourceLog/ladderRungs.js.map +1 -0
  202. package/dist/resourceLog/license.d.ts +42 -17
  203. package/dist/resourceLog/license.d.ts.map +1 -1
  204. package/dist/resourceLog/license.js +38 -24
  205. package/dist/resourceLog/license.js.map +1 -1
  206. package/dist/space/activity.d.ts +15 -15
  207. package/dist/space/activity.d.ts.map +1 -1
  208. package/dist/space/activity.js +15 -15
  209. package/dist/space/activity.js.map +1 -1
  210. package/dist/space/collections.d.ts +11 -0
  211. package/dist/space/collections.d.ts.map +1 -1
  212. package/dist/space/collections.js +13 -0
  213. package/dist/space/collections.js.map +1 -1
  214. package/dist/space/deleteSpace.d.ts +28 -0
  215. package/dist/space/deleteSpace.d.ts.map +1 -0
  216. package/dist/space/deleteSpace.js +44 -0
  217. package/dist/space/deleteSpace.js.map +1 -0
  218. package/dist/space/errors.d.ts.map +1 -1
  219. package/dist/space/errors.js +0 -1
  220. package/dist/space/errors.js.map +1 -1
  221. package/dist/space/index.d.ts +6 -0
  222. package/dist/space/index.d.ts.map +1 -1
  223. package/dist/space/index.js +6 -0
  224. package/dist/space/index.js.map +1 -1
  225. package/dist/space/plaintextCollection.d.ts +43 -0
  226. package/dist/space/plaintextCollection.d.ts.map +1 -0
  227. package/dist/space/plaintextCollection.js +17 -0
  228. package/dist/space/plaintextCollection.js.map +1 -0
  229. package/dist/stages.d.ts +23 -0
  230. package/dist/stages.d.ts.map +1 -0
  231. package/dist/stages.js +23 -0
  232. package/dist/stages.js.map +1 -0
  233. package/dist/sync/index.d.ts +7 -0
  234. package/dist/sync/index.d.ts.map +1 -1
  235. package/dist/sync/index.js +7 -0
  236. package/dist/sync/index.js.map +1 -1
  237. package/dist/sync/push.js +4 -4
  238. package/dist/sync/push.js.map +1 -1
  239. package/dist/sync/remint.js +2 -2
  240. package/dist/sync/remint.js.map +1 -1
  241. package/dist/sync/types.d.ts +41 -1
  242. package/dist/sync/types.d.ts.map +1 -1
  243. package/dist/sync/types.js +47 -1
  244. package/dist/sync/types.js.map +1 -1
  245. package/dist/unlock/index.d.ts +5 -1
  246. package/dist/unlock/index.d.ts.map +1 -1
  247. package/dist/unlock/index.js +5 -1
  248. package/dist/unlock/index.js.map +1 -1
  249. package/dist/unlock/retire.d.ts +35 -7
  250. package/dist/unlock/retire.d.ts.map +1 -1
  251. package/dist/unlock/retire.js +52 -14
  252. package/dist/unlock/retire.js.map +1 -1
  253. package/dist/unlock/standingClient.d.ts.map +1 -1
  254. package/dist/unlock/standingClient.js +5 -1
  255. package/dist/unlock/standingClient.js.map +1 -1
  256. package/dist/unlock/standingWebvh.d.ts +217 -35
  257. package/dist/unlock/standingWebvh.d.ts.map +1 -1
  258. package/dist/unlock/standingWebvh.js +469 -210
  259. package/dist/unlock/standingWebvh.js.map +1 -1
  260. package/dist/webvh/accountEntry.d.ts +146 -0
  261. package/dist/webvh/accountEntry.d.ts.map +1 -0
  262. package/dist/webvh/accountEntry.js +239 -0
  263. package/dist/webvh/accountEntry.js.map +1 -0
  264. package/dist/webvh/didWeb.d.ts +12 -7
  265. package/dist/webvh/didWeb.d.ts.map +1 -1
  266. package/dist/webvh/didWeb.js +2 -2
  267. package/dist/webvh/didWeb.js.map +1 -1
  268. package/dist/webvh/didWebProjection.d.ts +164 -0
  269. package/dist/webvh/didWebProjection.d.ts.map +1 -0
  270. package/dist/webvh/didWebProjection.js +230 -0
  271. package/dist/webvh/didWebProjection.js.map +1 -0
  272. package/dist/webvh/didWebvh.d.ts +275 -136
  273. package/dist/webvh/didWebvh.d.ts.map +1 -1
  274. package/dist/webvh/didWebvh.js +307 -340
  275. package/dist/webvh/didWebvh.js.map +1 -1
  276. package/dist/webvh/enrollClient.d.ts +65 -0
  277. package/dist/webvh/enrollClient.d.ts.map +1 -0
  278. package/dist/webvh/enrollClient.js +172 -0
  279. package/dist/webvh/enrollClient.js.map +1 -0
  280. package/dist/webvh/index.d.ts +37 -12
  281. package/dist/webvh/index.d.ts.map +1 -1
  282. package/dist/webvh/index.js +33 -10
  283. package/dist/webvh/index.js.map +1 -1
  284. package/dist/webvh/listClients.d.ts +1 -35
  285. package/dist/webvh/listClients.d.ts.map +1 -1
  286. package/dist/webvh/listClients.js +2 -30
  287. package/dist/webvh/listClients.js.map +1 -1
  288. package/dist/webvh/revokeClient.d.ts +41 -11
  289. package/dist/webvh/revokeClient.d.ts.map +1 -1
  290. package/dist/webvh/revokeClient.js +99 -48
  291. package/dist/webvh/revokeClient.js.map +1 -1
  292. package/dist/webvh/standingZcap.d.ts +61 -14
  293. package/dist/webvh/standingZcap.d.ts.map +1 -1
  294. package/dist/webvh/standingZcap.js +91 -0
  295. package/dist/webvh/standingZcap.js.map +1 -1
  296. package/dist/webvh/verifyLog.d.ts +59 -5
  297. package/dist/webvh/verifyLog.d.ts.map +1 -1
  298. package/dist/webvh/verifyLog.js +76 -11
  299. package/dist/webvh/verifyLog.js.map +1 -1
  300. package/dist/webvh/wasIdStore.d.ts +8 -8
  301. package/dist/webvh/wasIdStore.d.ts.map +1 -1
  302. package/dist/webvh/wasIdStore.js +39 -14
  303. package/dist/webvh/wasIdStore.js.map +1 -1
  304. package/dist/webvh/zcap.d.ts +14 -1
  305. package/dist/webvh/zcap.d.ts.map +1 -1
  306. package/dist/webvh/zcap.js +3 -27
  307. package/dist/webvh/zcap.js.map +1 -1
  308. package/package.json +2 -2
  309. package/dist/webvh/keyAgreement.d.ts +0 -97
  310. package/dist/webvh/keyAgreement.d.ts.map +0 -1
  311. package/dist/webvh/keyAgreement.js +0 -71
  312. package/dist/webvh/keyAgreement.js.map +0 -1
@@ -1,14 +1,30 @@
1
1
  import { WasClient } from '@interop/was-client';
2
- import { effectiveParameters, readPublishedLog, WebvhLogConflictError, withLogConflictRetry } from '../webvh/didWebvh.js';
3
- import { delegationKeyInDocument, ladderVmIds } from '../webvh/listClients.js';
4
- import { delegationProofKeyId, zcapExpiring } from '../webvh/standingZcap.js';
2
+ import { spacePath } from '@interop/was-client/paths';
3
+ import { currentLogParameters, readPublishedLog, readPublishedLogOrThrow, WebvhLogConflictError, withLogConflictRetry } from '../webvh/didWebvh.js';
4
+ import { ladderVmIds } from '../resourceLog/document.js';
5
+ import { standingZcapStale } from '../webvh/standingZcap.js';
5
6
  import { delegateLogWrite } from '../recovery/recoveryDelegation.js';
6
7
  import { accountLogPinId } from '../webvh/verifyLog.js';
7
8
  import { mintSpaceId } from '../genesis/accountGenesis.js';
8
9
  import { attributeLadderRung, ladderRung, ladderVmKeyMultibase } from './ladder.js';
9
10
  import { revealLadderRungWebvh } from './ladderAnchored.js';
10
11
  import { ladderVmAgent, ladderVmZcapClient } from './zcap.js';
11
- import { clientAnnexDidParts, clientAnnexLogPinId, clientAnnexLogStore, delegatedClientsDelegationSpaceId, delegatedClientsPointer, ensureGenerationDelegationCurrent, mintCredentialClientAnnexGeneration, mintDelegatedClientsDelegation, mintGenerationDelegation, setDelegatedClientsPointerOnce } from './log.js';
12
+ import { mintSpaceRootVerbCapability } from './spaceCapability.js';
13
+ import { clientAnnexDidParts, clientAnnexLogPinId, clientAnnexLogStore, delegatedClientsDelegationSpaceId, delegatedClientsPointer, ensureClientAnnexSpace, ensureGenerationDelegationCurrent, mintCredentialClientAnnexGeneration, mintDelegatedClientsDelegation, mintGenerationDelegation, setDelegatedClientsPointerOnce } from './log.js';
14
+ /**
15
+ * The HTTP status a raw signed request's rejection carries, when it carries
16
+ * one. `WasClient.request` applies no error mapping, so the status is all a
17
+ * caller has to dispatch on, and different transports hang it in different
18
+ * places (`status`, or `response.status`).
19
+ *
20
+ * @param err {unknown}
21
+ * @returns {number | undefined}
22
+ */
23
+ function rawRequestStatus(err) {
24
+ const raw = err;
25
+ const status = raw?.status ?? raw?.response?.status;
26
+ return typeof status === 'number' ? status : undefined;
27
+ }
12
28
  /**
13
29
  * The typed refusal of {@link ensureCredentialClientAnnexGeneration}: the
14
30
  * account is not in a shape this visit can mend, and nothing was written.
@@ -212,49 +228,319 @@ async function ensureCredentialClientAnnexGenerationChecked({ wasServerUrl, spac
212
228
  }
213
229
  return {};
214
230
  }
215
- if (annexSpaceId === undefined) {
216
- // THE FRESH-SPACE ARM: neither the pointer nor a sibling names a Space.
217
- // The pre-flight attribution runs before any generation or Space is
218
- // minted (a bridge delegation mint writes nothing durable); the stage
219
- // order mirrors the credential-anchored genesis exactly. A rung that is
220
- // only committed passes here and is revealed at the pointer entry.
221
- await assertPointerEntryAttributable({ ladderSeed, log: account.log });
231
+ /**
232
+ * The fresh-Space stage, controller-first past the create. The create
233
+ * itself must name the ladder VM's bare did:key: a storage server
234
+ * authorizes a Space create against the controller the request body names,
235
+ * and a root invocation must be signed by that very DID, so a create
236
+ * naming the account did:webvh is refused. The controller is flipped to
237
+ * the account DID in the very next request, before anything publishes into
238
+ * the Space.
239
+ *
240
+ * So the stranding window is one request wide. Inside it the stranded
241
+ * Space is did:key-controlled, which no server orphan sweep can reap,
242
+ * since a did:key resolves from its own bytes forever. Past the flip it is
243
+ * account-controlled and reapable. Narrowing the window to that one
244
+ * request is what this ordering buys; it does not close it.
245
+ *
246
+ * The flip preceding the generation mint is load-bearing rather than
247
+ * cosmetic. The mint and the delegation embed ride the ladder-signed
248
+ * sibling delegation, and the server admits that chain only once the
249
+ * Space's controller is the account DID whose document lists the ladder
250
+ * VM. Minting first and flipping afterwards would need the bootstrap key's
251
+ * own root invocations, which is the ordering this stage replaced.
252
+ *
253
+ * @returns {Promise<string>} the fresh auxiliary Space's id
254
+ */
255
+ async function mintFreshAnnexSpace() {
222
256
  const freshSpaceId = mintSpaceId();
223
257
  const keyAgent = await ladderVmAgent({ ladderSeed });
224
258
  const bootstrapWas = bootstrapWasFor({ keyAgent });
225
- const minted = await mintCredentialClientAnnexGeneration({
259
+ const created = await ensureClientAnnexSpace({
226
260
  was: bootstrapWas,
227
- wasServerUrl,
228
261
  spaceId: freshSpaceId,
229
- controller: keyAgent.id,
230
- ladderSeed
262
+ controller: keyAgent.id
263
+ });
264
+ // The create's own answer is the current Description, so the flip carries
265
+ // it as `current` rather than re-reading what this call just wrote.
266
+ await bootstrapWas
267
+ .space(freshSpaceId)
268
+ .configure({ current: created, controller: account.did, force: true });
269
+ return freshSpaceId;
270
+ }
271
+ /**
272
+ * One Space Description read, judged by its HTTP STATUS alone. A 404 is
273
+ * `'not-found'`; a 2xx is `'present'`, whatever its body says, since a
274
+ * Space served with an unreadable body is a present Space and reading it
275
+ * as absence is exactly what would re-point a live account. Every other
276
+ * answer -- a transport failure, a 5xx, a 4xx that is not 404 -- throws,
277
+ * so nothing but a real 404 can ever reach the absence decision.
278
+ *
279
+ * The read goes through the raw signed request rather than the
280
+ * `describe()` handle, whose null-on-404 translation also swallows 401 and
281
+ * 403 and an unparseable body.
282
+ *
283
+ * @param options {object}
284
+ * @param options.was {WasClient} the client whose signer invokes
285
+ * @param options.annexSpaceId {string}
286
+ * @param [options.capability] {IZcap} the attached capability; absent
287
+ * means a root invocation
288
+ * @returns {Promise<'present' | 'not-found'>}
289
+ */
290
+ async function readSpaceDescription({ was, annexSpaceId, capability }) {
291
+ let status;
292
+ try {
293
+ const response = await was.request({
294
+ path: spacePath(annexSpaceId),
295
+ method: 'GET',
296
+ ...(capability !== undefined ? { capability } : {})
297
+ });
298
+ status = response.status;
299
+ }
300
+ catch (err) {
301
+ if (rawRequestStatus(err) === 404) {
302
+ return 'not-found';
303
+ }
304
+ throw err;
305
+ }
306
+ if (status >= 200 && status < 300) {
307
+ return 'present';
308
+ }
309
+ if (status === 404) {
310
+ return 'not-found';
311
+ }
312
+ throw new Error(`client annex: the Space Description read for "${annexSpaceId}" ` +
313
+ `answered ${status}; the visit cannot tell whether the Space is gone.`);
314
+ }
315
+ /**
316
+ * Whether the auxiliary Space itself is gone from the server, asked only
317
+ * when the pointed generation's log did not read back. A storage server
318
+ * masks an unauthorized read as the same 404 an absent Space answers, so
319
+ * ONE 404 is not absence: it is "absent, or this reader has no authority
320
+ * here". Absence is therefore corroborated by two independent readers, and
321
+ * the Space is gone only when both answer a real 404.
322
+ *
323
+ * The first reader is a ladder-signed GET-only child of the Space's own
324
+ * root, which the account DID's document backs. The sibling delegation
325
+ * cannot carry the question: it targets the items subtree beneath the
326
+ * Space and says nothing about the Space Description.
327
+ *
328
+ * The second is a root invocation as the ladder VM's BARE did:key, the
329
+ * controller a torn establishment leaves behind when its flip never
330
+ * landed. That reader answers 2xx on exactly the Space the first reader
331
+ * has no authority over, so the pair covers both controllers a live annex
332
+ * Space of this credential's can have.
333
+ *
334
+ * The residual bound, stated because no read can close it: a server that
335
+ * does not admit the ladder delegation clause's single-verb predicate
336
+ * refuses the first probe with the same masked 404, and on an
337
+ * account-controlled Space the second probe is refused too. Both readers
338
+ * then say `'not-found'` about a live Space. That is a server older than
339
+ * the one this arm was built against, and the arm's cost there is a
340
+ * re-point of a live generation.
341
+ *
342
+ * @param options {object}
343
+ * @param options.annexSpaceId {string}
344
+ * @param options.was {WasClient} the standing client's storage client
345
+ * @returns {Promise<boolean>}
346
+ */
347
+ async function annexSpaceAbsent({ annexSpaceId, was }) {
348
+ const probe = await mintSpaceRootVerbCapability({
349
+ zcapClient: ladderClient,
350
+ storageServerUrl: wasServerUrl,
351
+ spaceId: annexSpaceId,
352
+ verb: 'GET',
353
+ controller: standingClient.did,
354
+ ...(now !== undefined ? { now } : {})
355
+ });
356
+ const delegated = await readSpaceDescription({
357
+ was,
358
+ annexSpaceId,
359
+ capability: probe
360
+ });
361
+ if (delegated === 'present') {
362
+ return false;
363
+ }
364
+ const bootstrapWas = bootstrapWasFor({
365
+ keyAgent: await ladderVmAgent({ ladderSeed })
366
+ });
367
+ const asBootstrap = await readSpaceDescription({
368
+ was: bootstrapWas,
369
+ annexSpaceId
370
+ });
371
+ return asBootstrap === 'not-found';
372
+ }
373
+ let spaceMinted = false;
374
+ let pointedSpaceMissing = false;
375
+ /**
376
+ * The arms that run inside one auxiliary Space: the sibling delegation,
377
+ * the pointed generation's renewal, and the fresh-generation mint with its
378
+ * pointer move. Called once on the resolved Space, and once more on a
379
+ * fresh Space when the pointed one turns out to be gone -- the replacement
380
+ * is decided before any write, so nothing is stranded by the re-run.
381
+ *
382
+ * @param options {object}
383
+ * @param options.annexSpaceId {string} the Space this run works in
384
+ * @param options.allowSpaceReplacement {boolean} whether an absent
385
+ * pointed generation may be checked against the Space itself, and a
386
+ * fresh Space minted when the Space is gone. False on the run that
387
+ * already works in a Space this visit created
388
+ * @param [options.pointer] {string} the pointed annex DID, when the
389
+ * document names one and this run works in its Space
390
+ * @returns {Promise<ClientAnnexGenerationEnsureOutcome>}
391
+ */
392
+ async function runInAnnexSpace({ annexSpaceId, allowSpaceReplacement, pointer }) {
393
+ // A usable sibling first: absent, targeting a different Space than this
394
+ // run works in, or stale on either of the standing-zcap axes -- expiry
395
+ // (past, or inside the renewal window) and signer death (its proof key
396
+ // no longer under `capabilityDelegation` in the verified account
397
+ // document, the current-key-set rule) -- a fresh sibling is minted
398
+ // (local ladder-VM signing, which verifies because the gate above proved
399
+ // the VM a document verification method) so every annex request below
400
+ // can ride it.
401
+ let sibling = delegatedClients;
402
+ let siblingReminted = false;
403
+ const siblingStale = sibling !== undefined &&
404
+ standingZcapStale({
405
+ zcap: sibling,
406
+ doc: account.doc,
407
+ ...(now !== undefined ? { now } : {})
408
+ });
409
+ if (sibling === undefined ||
410
+ siblingSpaceId !== annexSpaceId ||
411
+ siblingStale) {
412
+ sibling = await mintDelegatedClientsDelegation({
413
+ zcapClient: ladderClient,
414
+ wasServerUrl,
415
+ clientAnnexSpaceId: annexSpaceId,
416
+ controller: standingClient.did,
417
+ ...(now !== undefined ? { now } : {})
418
+ });
419
+ siblingReminted = true;
420
+ }
421
+ const usableSibling = sibling;
422
+ const standingWas = new WasClient({
423
+ serverUrl: wasServerUrl,
424
+ zcapClient: standingClient.zcapClient
425
+ });
426
+ const storeFor = (generationId) => clientAnnexLogStore({
427
+ was: standingWas,
428
+ spaceId: annexSpaceId,
429
+ generationId,
430
+ capability: usableSibling
431
+ });
432
+ const annexPin = (generationId) => pinStore !== undefined
433
+ ? {
434
+ pinStore,
435
+ logId: clientAnnexLogPinId({ spaceId: annexSpaceId, generationId })
436
+ }
437
+ : {};
438
+ // RENEW PRECEDES MINT: a live, verifiable pointed generation is renewed
439
+ // in place; only a rung this generation never committed falls through to
440
+ // the fresh mint (the GC swap's no-committed-survivor escape).
441
+ if (pointer !== undefined) {
442
+ const parts = clientAnnexDidParts({ did: pointer });
443
+ const pointedLog = await readPublishedLog({
444
+ idStore: storeFor(parts.generationId),
445
+ expectedDid: pointer,
446
+ ...annexPin(parts.generationId)
447
+ });
448
+ if (pointedLog !== undefined) {
449
+ try {
450
+ const ensured = await ensureGenerationDelegationCurrent({
451
+ store: storeFor(parts.generationId),
452
+ ladderSeed,
453
+ generationId: parts.generationId,
454
+ mintGenerationDelegation: mintDelegation,
455
+ expectedDid: pointer,
456
+ accountDoc: account.doc,
457
+ // The head just read: on a healthy account this stage spends no
458
+ // second round trip on the same log, and hands its head back for
459
+ // the enrollment to build on.
460
+ published: pointedLog,
461
+ ...annexPin(parts.generationId),
462
+ ...(now !== undefined ? { now } : {})
463
+ });
464
+ const resealed = await resealRecord({
465
+ delegatedClients: usableSibling,
466
+ siblingReminted
467
+ });
468
+ return {
469
+ clientAnnexDid: pointer,
470
+ generationDelegation: ensured.delegation,
471
+ delegation: usableBridge,
472
+ delegatedClients: usableSibling,
473
+ generationMinted: false,
474
+ spaceMinted,
475
+ pointedSpaceMissing,
476
+ delegationRenewed: ensured.renewed,
477
+ siblingReminted,
478
+ bridgeReminted,
479
+ ...(ensured.published !== undefined
480
+ ? { generationLog: ensured.published }
481
+ : {}),
482
+ ...resealed
483
+ };
484
+ }
485
+ catch (err) {
486
+ if (err.name !==
487
+ 'ClientAnnexRungUncommittedError') {
488
+ throw err;
489
+ }
490
+ // This credential's rung was never committed into the pointed
491
+ // generation (bound mid-generation): fall through to the fresh
492
+ // mint, which commits it with the fresh genesis.
493
+ }
494
+ }
495
+ else if (allowSpaceReplacement &&
496
+ (await annexSpaceAbsent({ annexSpaceId, was: standingWas }))) {
497
+ // THE POINTED SPACE IS GONE. A missing generation log inside a live
498
+ // Space is the fresh-generation arm's case; a missing SPACE is not,
499
+ // since every write below would land in a Space that does not exist
500
+ // and the visit would fail on something other than the typed
501
+ // refusal. The Space is re-minted and the run starts over in it,
502
+ // before anything has been written.
503
+ await assertPointerEntryAttributable({ ladderSeed, log: account.log });
504
+ const freshSpaceId = await mintFreshAnnexSpace();
505
+ spaceMinted = true;
506
+ pointedSpaceMissing = true;
507
+ return runInAnnexSpace({
508
+ annexSpaceId: freshSpaceId,
509
+ allowSpaceReplacement: false
510
+ });
511
+ }
512
+ }
513
+ // THE FRESH-GENERATION ARM: pre-flight attribution first (never mint a
514
+ // generation the pointer entry cannot then name), then the GC swap's
515
+ // stage order minus its revoke -- mint, install the delegation,
516
+ // re-point. The fresh genesis commits only the acting credential's annex
517
+ // rung; other standing credentials' per-generation rungs are re-committed
518
+ // only by their own later ceremonies (a property of every generation
519
+ // swap).
520
+ await assertPointerEntryAttributable({ ladderSeed, log: account.log });
521
+ const minted = await mintCredentialClientAnnexGeneration({
522
+ was: standingWas,
523
+ wasServerUrl,
524
+ spaceId: annexSpaceId,
525
+ controller: account.did,
526
+ ladderSeed,
527
+ capability: usableSibling
231
528
  });
232
- // The delegation embeds while the Space still answers to the bootstrap
233
- // did:key; the controller flip follows, then the pointer entry.
234
529
  const ensured = await ensureGenerationDelegationCurrent({
235
- store: clientAnnexLogStore({
236
- was: bootstrapWas,
237
- spaceId: freshSpaceId,
238
- generationId: minted.generationId
239
- }),
530
+ store: storeFor(minted.generationId),
240
531
  ladderSeed,
241
532
  generationId: minted.generationId,
242
533
  mintGenerationDelegation: mintDelegation,
243
534
  expectedDid: minted.did,
244
- ...(pinStore !== undefined
245
- ? {
246
- pinStore,
247
- logId: clientAnnexLogPinId({
248
- spaceId: freshSpaceId,
249
- generationId: minted.generationId
250
- })
251
- }
252
- : {}),
535
+ ...annexPin(minted.generationId),
253
536
  ...(now !== undefined ? { now } : {})
254
537
  });
255
- await bootstrapWas
256
- .space(freshSpaceId)
257
- .configure({ controller: account.did, force: true });
538
+ // No revocation of the superseded generation's delegation is attempted:
539
+ // a transient visit has no reach that could invoke it (the standing
540
+ // client is neither the Space controller nor in that delegation's
541
+ // chain). The pointer move itself retires it on a conforming server --
542
+ // the inspector clause compares the delegation's controller against the
543
+ // document's pointer -- and it otherwise rots on its TTL.
258
544
  await movePointerAsLadder({
259
545
  idStore,
260
546
  ladderSeed,
@@ -264,207 +550,41 @@ async function ensureCredentialClientAnnexGenerationChecked({ wasServerUrl, spac
264
550
  ? { pinStore, logId: accountLogPinId({ spaceId }) }
265
551
  : {})
266
552
  });
267
- const sibling = await mintDelegatedClientsDelegation({
268
- zcapClient: ladderClient,
269
- wasServerUrl,
270
- clientAnnexSpaceId: freshSpaceId,
271
- controller: standingClient.did,
272
- ...(now !== undefined ? { now } : {})
273
- });
274
553
  const resealed = await resealRecord({
275
- delegatedClients: sibling,
276
- siblingReminted: true
554
+ delegatedClients: usableSibling,
555
+ siblingReminted
277
556
  });
278
557
  return {
279
558
  clientAnnexDid: minted.did,
280
559
  generationDelegation: ensured.delegation,
281
560
  delegation: usableBridge,
282
- delegatedClients: sibling,
561
+ delegatedClients: usableSibling,
283
562
  generationMinted: true,
284
- spaceMinted: true,
563
+ spaceMinted,
564
+ pointedSpaceMissing,
285
565
  delegationRenewed: false,
286
- siblingReminted: true,
566
+ siblingReminted,
287
567
  bridgeReminted,
288
568
  ...resealed
289
569
  };
290
570
  }
291
- // THE EXISTING-SPACE ARMS. A usable sibling first: absent, targeting a
292
- // different Space than the resolved one, or stale on either of the
293
- // standing-zcap axes -- expiry (past, or inside the renewal window) and
294
- // signer death (its proof key no longer under `capabilityDelegation` in
295
- // the verified account document, the current-key-set rule) -- a fresh
296
- // sibling is minted (local ladder-VM signing, which verifies because the
297
- // gate above proved the VM a document verification method) so every annex
298
- // request below can ride it.
299
- let sibling = delegatedClients;
300
- let siblingReminted = false;
301
- const siblingStale = sibling !== undefined &&
302
- standingZcapStale({
303
- zcap: sibling,
304
- doc: account.doc,
305
- ...(now !== undefined ? { now } : {})
306
- });
307
- if (sibling === undefined ||
308
- siblingSpaceId !== annexSpaceId ||
309
- siblingStale) {
310
- sibling = await mintDelegatedClientsDelegation({
311
- zcapClient: ladderClient,
312
- wasServerUrl,
313
- clientAnnexSpaceId: annexSpaceId,
314
- controller: standingClient.did,
315
- ...(now !== undefined ? { now } : {})
316
- });
317
- siblingReminted = true;
318
- }
319
- const usableSibling = sibling;
320
- const standingWas = new WasClient({
321
- serverUrl: wasServerUrl,
322
- zcapClient: standingClient.zcapClient
323
- });
324
- const storeFor = (generationId) => clientAnnexLogStore({
325
- was: standingWas,
326
- spaceId: annexSpaceId,
327
- generationId,
328
- capability: usableSibling
329
- });
330
- const annexPin = (generationId) => pinStore !== undefined
331
- ? {
332
- pinStore,
333
- logId: clientAnnexLogPinId({ spaceId: annexSpaceId, generationId })
334
- }
335
- : {};
336
- // RENEW PRECEDES MINT: a live, verifiable pointed generation is renewed in
337
- // place; only a rung this generation never committed falls through to the
338
- // fresh mint (the GC swap's no-committed-survivor escape).
339
- if (pointer !== undefined) {
340
- const parts = clientAnnexDidParts({ did: pointer });
341
- const pointedLog = await readPublishedLog({
342
- idStore: storeFor(parts.generationId),
343
- expectedDid: pointer,
344
- ...annexPin(parts.generationId)
571
+ if (annexSpaceId === undefined) {
572
+ // NEITHER THE POINTER NOR A SIBLING NAMES A SPACE. The pre-flight
573
+ // attribution runs before any Space or generation is minted (a bridge
574
+ // delegation mint writes nothing durable).
575
+ await assertPointerEntryAttributable({ ladderSeed, log: account.log });
576
+ const freshSpaceId = await mintFreshAnnexSpace();
577
+ spaceMinted = true;
578
+ return runInAnnexSpace({
579
+ annexSpaceId: freshSpaceId,
580
+ allowSpaceReplacement: false
345
581
  });
346
- if (pointedLog !== undefined) {
347
- try {
348
- const ensured = await ensureGenerationDelegationCurrent({
349
- store: storeFor(parts.generationId),
350
- ladderSeed,
351
- generationId: parts.generationId,
352
- mintGenerationDelegation: mintDelegation,
353
- expectedDid: pointer,
354
- accountDoc: account.doc,
355
- ...annexPin(parts.generationId),
356
- ...(now !== undefined ? { now } : {})
357
- });
358
- const resealed = await resealRecord({
359
- delegatedClients: usableSibling,
360
- siblingReminted
361
- });
362
- return {
363
- clientAnnexDid: pointer,
364
- generationDelegation: ensured.delegation,
365
- delegation: usableBridge,
366
- delegatedClients: usableSibling,
367
- generationMinted: false,
368
- spaceMinted: false,
369
- delegationRenewed: ensured.renewed,
370
- siblingReminted,
371
- bridgeReminted,
372
- ...resealed
373
- };
374
- }
375
- catch (err) {
376
- if (err.name !== 'ClientAnnexRungUncommittedError') {
377
- throw err;
378
- }
379
- // This credential's rung was never committed into the pointed
380
- // generation (bound mid-generation): fall through to the fresh mint,
381
- // which commits it with the fresh genesis.
382
- }
383
- }
384
582
  }
385
- // THE FRESH-GENERATION ARM, existing Space: pre-flight attribution first
386
- // (never mint a generation the pointer entry cannot then name), then the
387
- // GC swap's stage order minus its revoke -- mint, install the delegation,
388
- // re-point. The fresh genesis commits only the acting credential's annex
389
- // rung; other standing credentials' per-generation rungs are re-committed
390
- // only by their own later ceremonies (a property of every generation
391
- // swap).
392
- await assertPointerEntryAttributable({ ladderSeed, log: account.log });
393
- const minted = await mintCredentialClientAnnexGeneration({
394
- was: standingWas,
395
- wasServerUrl,
396
- spaceId: annexSpaceId,
397
- controller: account.did,
398
- ladderSeed,
399
- capability: usableSibling
400
- });
401
- const ensured = await ensureGenerationDelegationCurrent({
402
- store: storeFor(minted.generationId),
403
- ladderSeed,
404
- generationId: minted.generationId,
405
- mintGenerationDelegation: mintDelegation,
406
- expectedDid: minted.did,
407
- ...annexPin(minted.generationId),
408
- ...(now !== undefined ? { now } : {})
409
- });
410
- // No revocation of the superseded generation's delegation is attempted:
411
- // a transient visit has no reach that could invoke it (the standing client
412
- // is neither the Space controller nor in that delegation's chain). The
413
- // pointer move itself retires it on a conforming server -- the inspector
414
- // clause compares the delegation's controller against the document's
415
- // pointer -- and it otherwise rots on its TTL.
416
- await movePointerAsLadder({
417
- idStore,
418
- ladderSeed,
419
- clientAnnexDid: minted.did,
420
- accountDid: account.did,
421
- ...(pinStore !== undefined
422
- ? { pinStore, logId: accountLogPinId({ spaceId }) }
423
- : {})
583
+ return runInAnnexSpace({
584
+ annexSpaceId,
585
+ allowSpaceReplacement: true,
586
+ ...(pointer !== undefined ? { pointer } : {})
424
587
  });
425
- const resealed = await resealRecord({
426
- delegatedClients: usableSibling,
427
- siblingReminted
428
- });
429
- return {
430
- clientAnnexDid: minted.did,
431
- generationDelegation: ensured.delegation,
432
- delegation: usableBridge,
433
- delegatedClients: usableSibling,
434
- generationMinted: true,
435
- spaceMinted: false,
436
- delegationRenewed: false,
437
- siblingReminted,
438
- bridgeReminted,
439
- ...resealed
440
- };
441
- }
442
- /**
443
- * The one staleness predicate for the standing recorded delegations this
444
- * ensure may renew: the record's bridge delegation and its `delegatedClients`
445
- * sibling. Two axes, the established pair -- expiry (past, or inside the
446
- * renewal window) and signer death (the proof's verification method no longer
447
- * under `capabilityDelegation` in the verified account document, the
448
- * current-key-set rule). One helper rather than a copy per delegation, so the
449
- * two can never drift onto different rules.
450
- *
451
- * @param options {object}
452
- * @param options.zcap {IZcap} the recorded delegation
453
- * @param options.doc {object} the VERIFIED account document
454
- * @param [options.now] {number} epoch milliseconds, for tests
455
- * @returns {boolean}
456
- */
457
- function standingZcapStale({ zcap, doc, now }) {
458
- const { expires } = zcap;
459
- const delegationKeyId = delegationProofKeyId(zcap);
460
- return (zcapExpiring({
461
- ...(expires !== undefined ? { expires } : {}),
462
- ...(now !== undefined ? { now } : {})
463
- }) ||
464
- !delegationKeyInDocument({
465
- doc: doc,
466
- ...(delegationKeyId !== undefined ? { delegationKeyId } : {})
467
- }));
468
588
  }
469
589
  /**
470
590
  * The annex Space, in the settled resolution order: the account document's
@@ -513,11 +633,7 @@ export function resolveClientAnnexSpaceId({ doc, delegatedClients }) {
513
633
  * @returns {Promise<ClientWebvhUpdateKeys>}
514
634
  */
515
635
  export async function pointerEntryUpdateKeys({ ladderSeed, log }) {
516
- const params = effectiveParameters(log);
517
- const current = params[params.length - 1] ?? {
518
- updateKeys: [],
519
- nextKeyHashes: []
520
- };
636
+ const current = currentLogParameters({ log });
521
637
  const unattributable = () => new ClientAnnexGenerationUnavailableError({
522
638
  reason: 'update-key-not-attributable',
523
639
  message: "No current account-log update key is a rung of this credential's " +
@@ -557,11 +673,7 @@ export async function pointerEntryUpdateKeys({ ladderSeed, log }) {
557
673
  * @returns {Promise<void>}
558
674
  */
559
675
  async function assertPointerEntryAttributable({ ladderSeed, log }) {
560
- const params = effectiveParameters(log);
561
- const current = params[params.length - 1] ?? {
562
- updateKeys: [],
563
- nextKeyHashes: []
564
- };
676
+ const current = currentLogParameters({ log });
565
677
  try {
566
678
  await attributeLadderRung({ ladderSeed, published: current });
567
679
  }
@@ -641,14 +753,12 @@ async function movePointerAsLadder({ idStore, ladderSeed, clientAnnexDid, accoun
641
753
  });
642
754
  // The head the reveal entry just published (or the unchanged head, when
643
755
  // the rung was revealed already), under the same pin.
644
- const published = await readPublishedLog({
756
+ const published = await readPublishedLogOrThrow({
645
757
  idStore,
646
758
  expectedDid: accountDid,
647
- ...pin
759
+ ...pin,
760
+ missingMessage: 'did:webvh: did.jsonl is missing; nothing to point at a client annex.'
648
761
  });
649
- if (published === undefined) {
650
- throw new Error('did:webvh: did.jsonl is missing; nothing to point at a client annex.');
651
- }
652
762
  // A racing ceremony that consumed the rung between this reveal and this
653
763
  // read leaves the ladder committed-only again, which the attribution
654
764
  // reports as `update-key-not-attributable`. Inside this loop that is a
@@ -674,7 +784,7 @@ async function movePointerAsLadder({ idStore, ladderSeed, clientAnnexDid, accoun
674
784
  }
675
785
  await setDelegatedClientsPointerOnce({
676
786
  idStore,
677
- updateKeys,
787
+ signer: { kind: 'client', updateKeys },
678
788
  clientAnnexDid,
679
789
  expectedDid: accountDid,
680
790
  logOnly: true,