@interop/wallet-core 0.65.0 → 0.67.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 (256) hide show
  1. package/README.md +12 -8
  2. package/dist/clientAnnex/credentialAnchoredGenesis.d.ts +5 -4
  3. package/dist/clientAnnex/credentialAnchoredGenesis.d.ts.map +1 -1
  4. package/dist/clientAnnex/credentialAnchoredGenesis.js +32 -50
  5. package/dist/clientAnnex/credentialAnchoredGenesis.js.map +1 -1
  6. package/dist/clientAnnex/establish.d.ts +112 -21
  7. package/dist/clientAnnex/establish.d.ts.map +1 -1
  8. package/dist/clientAnnex/establish.js +248 -180
  9. package/dist/clientAnnex/establish.js.map +1 -1
  10. package/dist/clientAnnex/forget.d.ts +2 -6
  11. package/dist/clientAnnex/forget.d.ts.map +1 -1
  12. package/dist/clientAnnex/forget.js +31 -61
  13. package/dist/clientAnnex/forget.js.map +1 -1
  14. package/dist/clientAnnex/forgetLast.d.ts +48 -132
  15. package/dist/clientAnnex/forgetLast.d.ts.map +1 -1
  16. package/dist/clientAnnex/forgetLast.js +88 -221
  17. package/dist/clientAnnex/forgetLast.js.map +1 -1
  18. package/dist/clientAnnex/gc.d.ts.map +1 -1
  19. package/dist/clientAnnex/gc.js +9 -0
  20. package/dist/clientAnnex/gc.js.map +1 -1
  21. package/dist/clientAnnex/heal.d.ts +97 -13
  22. package/dist/clientAnnex/heal.d.ts.map +1 -1
  23. package/dist/clientAnnex/heal.js +108 -174
  24. package/dist/clientAnnex/heal.js.map +1 -1
  25. package/dist/clientAnnex/index.d.ts +8 -8
  26. package/dist/clientAnnex/index.d.ts.map +1 -1
  27. package/dist/clientAnnex/index.js +6 -6
  28. package/dist/clientAnnex/index.js.map +1 -1
  29. package/dist/clientAnnex/ladder.d.ts +51 -4
  30. package/dist/clientAnnex/ladder.d.ts.map +1 -1
  31. package/dist/clientAnnex/ladder.js +310 -55
  32. package/dist/clientAnnex/ladder.js.map +1 -1
  33. package/dist/clientAnnex/ladderAnchored.d.ts +37 -3
  34. package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -1
  35. package/dist/clientAnnex/ladderAnchored.js +69 -34
  36. package/dist/clientAnnex/ladderAnchored.js.map +1 -1
  37. package/dist/clientAnnex/log.d.ts +148 -72
  38. package/dist/clientAnnex/log.d.ts.map +1 -1
  39. package/dist/clientAnnex/log.js +211 -137
  40. package/dist/clientAnnex/log.js.map +1 -1
  41. package/dist/clientAnnex/mend.d.ts.map +1 -1
  42. package/dist/clientAnnex/mend.js +63 -81
  43. package/dist/clientAnnex/mend.js.map +1 -1
  44. package/dist/clientAnnex/recoveryLadderAnchored.d.ts +20 -1
  45. package/dist/clientAnnex/recoveryLadderAnchored.d.ts.map +1 -1
  46. package/dist/clientAnnex/recoveryLadderAnchored.js +77 -294
  47. package/dist/clientAnnex/recoveryLadderAnchored.js.map +1 -1
  48. package/dist/clientAnnex/rosterDeliveredEpochs.d.ts +13 -5
  49. package/dist/clientAnnex/rosterDeliveredEpochs.d.ts.map +1 -1
  50. package/dist/clientAnnex/rosterDeliveredEpochs.js +18 -9
  51. package/dist/clientAnnex/rosterDeliveredEpochs.js.map +1 -1
  52. package/dist/clientAnnex/selfEnroll.js +1 -1
  53. package/dist/clientAnnex/selfEnroll.js.map +1 -1
  54. package/dist/clientAnnex/zcap.d.ts +19 -0
  55. package/dist/clientAnnex/zcap.d.ts.map +1 -1
  56. package/dist/clientAnnex/zcap.js +80 -12
  57. package/dist/clientAnnex/zcap.js.map +1 -1
  58. package/dist/clients/index.d.ts +3 -2
  59. package/dist/clients/index.d.ts.map +1 -1
  60. package/dist/clients/index.js +3 -2
  61. package/dist/clients/index.js.map +1 -1
  62. package/dist/clients/listing.d.ts.map +1 -1
  63. package/dist/clients/listing.js +33 -15
  64. package/dist/clients/listing.js.map +1 -1
  65. package/dist/clients/policy.d.ts +18 -0
  66. package/dist/clients/policy.d.ts.map +1 -1
  67. package/dist/clients/policy.js +22 -8
  68. package/dist/clients/policy.js.map +1 -1
  69. package/dist/clients/revocation.d.ts +18 -30
  70. package/dist/clients/revocation.d.ts.map +1 -1
  71. package/dist/clients/revocation.js +12 -27
  72. package/dist/clients/revocation.js.map +1 -1
  73. package/dist/clients/rosterPolicy.d.ts +6 -1
  74. package/dist/clients/rosterPolicy.d.ts.map +1 -1
  75. package/dist/clients/rosterPolicy.js +27 -30
  76. package/dist/clients/rosterPolicy.js.map +1 -1
  77. package/dist/descriptors/errors.d.ts +6 -5
  78. package/dist/descriptors/errors.d.ts.map +1 -1
  79. package/dist/descriptors/errors.js +6 -5
  80. package/dist/descriptors/errors.js.map +1 -1
  81. package/dist/descriptors/index.d.ts +7 -3
  82. package/dist/descriptors/index.d.ts.map +1 -1
  83. package/dist/descriptors/index.js +7 -3
  84. package/dist/descriptors/index.js.map +1 -1
  85. package/dist/descriptors/logSource.d.ts +28 -6
  86. package/dist/descriptors/logSource.d.ts.map +1 -1
  87. package/dist/descriptors/logSource.js +33 -7
  88. package/dist/descriptors/logSource.js.map +1 -1
  89. package/dist/enrollment/enrollment.d.ts.map +1 -1
  90. package/dist/enrollment/enrollment.js +3 -7
  91. package/dist/enrollment/enrollment.js.map +1 -1
  92. package/dist/genesis/accountGenesis.d.ts +8 -10
  93. package/dist/genesis/accountGenesis.d.ts.map +1 -1
  94. package/dist/genesis/accountGenesis.js +39 -41
  95. package/dist/genesis/accountGenesis.js.map +1 -1
  96. package/dist/genesis/kmsAuthentication.d.ts +50 -0
  97. package/dist/genesis/kmsAuthentication.d.ts.map +1 -0
  98. package/dist/genesis/kmsAuthentication.js +49 -0
  99. package/dist/genesis/kmsAuthentication.js.map +1 -0
  100. package/dist/keyring/kdf.d.ts +16 -20
  101. package/dist/keyring/kdf.d.ts.map +1 -1
  102. package/dist/keyring/kdf.js +2 -2
  103. package/dist/keyring/kdf.js.map +1 -1
  104. package/dist/keyring/unlockSpace.d.ts +8 -30
  105. package/dist/keyring/unlockSpace.d.ts.map +1 -1
  106. package/dist/keyring/unlockSpace.js +8 -31
  107. package/dist/keyring/unlockSpace.js.map +1 -1
  108. package/dist/keys/clientKeyRecord.d.ts +2 -1
  109. package/dist/keys/clientKeyRecord.d.ts.map +1 -1
  110. package/dist/keys/clientKeyRecord.js +28 -11
  111. package/dist/keys/clientKeyRecord.js.map +1 -1
  112. package/dist/keys/index.d.ts +19 -5
  113. package/dist/keys/index.d.ts.map +1 -1
  114. package/dist/keys/index.js +17 -3
  115. package/dist/keys/index.js.map +1 -1
  116. package/dist/keys/rosterLogStore.d.ts +3 -1
  117. package/dist/keys/rosterLogStore.d.ts.map +1 -1
  118. package/dist/keys/rosterLogStore.js +20 -8
  119. package/dist/keys/rosterLogStore.js.map +1 -1
  120. package/dist/keys/spaceEpochs.d.ts +92 -3
  121. package/dist/keys/spaceEpochs.d.ts.map +1 -1
  122. package/dist/keys/spaceEpochs.js +110 -4
  123. package/dist/keys/spaceEpochs.js.map +1 -1
  124. package/dist/keys/userKeyCascade.d.ts +8 -5
  125. package/dist/keys/userKeyCascade.d.ts.map +1 -1
  126. package/dist/keys/userKeyCascade.js +7 -6
  127. package/dist/keys/userKeyCascade.js.map +1 -1
  128. package/dist/keys/userKeyRoster.d.ts +68 -4
  129. package/dist/keys/userKeyRoster.d.ts.map +1 -1
  130. package/dist/keys/userKeyRoster.js +146 -33
  131. package/dist/keys/userKeyRoster.js.map +1 -1
  132. package/dist/keys/userKeyRosterCascade.d.ts +110 -10
  133. package/dist/keys/userKeyRosterCascade.d.ts.map +1 -1
  134. package/dist/keys/userKeyRosterCascade.js +184 -40
  135. package/dist/keys/userKeyRosterCascade.js.map +1 -1
  136. package/dist/recovery/continuation.d.ts +255 -0
  137. package/dist/recovery/continuation.d.ts.map +1 -0
  138. package/dist/recovery/continuation.js +471 -0
  139. package/dist/recovery/continuation.js.map +1 -0
  140. package/dist/recovery/index.d.ts +12 -8
  141. package/dist/recovery/index.d.ts.map +1 -1
  142. package/dist/recovery/index.js +11 -7
  143. package/dist/recovery/index.js.map +1 -1
  144. package/dist/recovery/recoveryDelegation.d.ts +40 -120
  145. package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
  146. package/dist/recovery/recoveryDelegation.js +36 -268
  147. package/dist/recovery/recoveryDelegation.js.map +1 -1
  148. package/dist/recovery/recoveryWebvh.d.ts +42 -83
  149. package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
  150. package/dist/recovery/recoveryWebvh.js +44 -380
  151. package/dist/recovery/recoveryWebvh.js.map +1 -1
  152. package/dist/request/appKey.d.ts +35 -1
  153. package/dist/request/appKey.d.ts.map +1 -1
  154. package/dist/request/appKey.js +29 -10
  155. package/dist/request/appKey.js.map +1 -1
  156. package/dist/request/classify.d.ts +3 -14
  157. package/dist/request/classify.d.ts.map +1 -1
  158. package/dist/request/classify.js +19 -40
  159. package/dist/request/classify.js.map +1 -1
  160. package/dist/request/index.d.ts +1 -0
  161. package/dist/request/index.d.ts.map +1 -1
  162. package/dist/request/index.js +1 -0
  163. package/dist/request/index.js.map +1 -1
  164. package/dist/request/onboarding.d.ts.map +1 -1
  165. package/dist/request/onboarding.js +19 -27
  166. package/dist/request/onboarding.js.map +1 -1
  167. package/dist/request/parse.d.ts +5 -3
  168. package/dist/request/parse.d.ts.map +1 -1
  169. package/dist/request/parse.js +7 -6
  170. package/dist/request/parse.js.map +1 -1
  171. package/dist/request/processRequest.d.ts.map +1 -1
  172. package/dist/request/processRequest.js +2 -1
  173. package/dist/request/processRequest.js.map +1 -1
  174. package/dist/request/queryPredicates.d.ts +98 -0
  175. package/dist/request/queryPredicates.d.ts.map +1 -0
  176. package/dist/request/queryPredicates.js +107 -0
  177. package/dist/request/queryPredicates.js.map +1 -0
  178. package/dist/resourceLog/document.d.ts +39 -0
  179. package/dist/resourceLog/document.d.ts.map +1 -1
  180. package/dist/resourceLog/document.js +41 -0
  181. package/dist/resourceLog/document.js.map +1 -1
  182. package/dist/resourceLog/ladderRungs.d.ts.map +1 -1
  183. package/dist/resourceLog/ladderRungs.js +3 -2
  184. package/dist/resourceLog/ladderRungs.js.map +1 -1
  185. package/dist/sync/contactsConflict.d.ts.map +1 -1
  186. package/dist/sync/contactsConflict.js +8 -2
  187. package/dist/sync/contactsConflict.js.map +1 -1
  188. package/dist/sync/engine.d.ts +38 -23
  189. package/dist/sync/engine.d.ts.map +1 -1
  190. package/dist/sync/engine.js +36 -5
  191. package/dist/sync/engine.js.map +1 -1
  192. package/dist/sync/index.d.ts +9 -12
  193. package/dist/sync/index.d.ts.map +1 -1
  194. package/dist/sync/index.js +8 -11
  195. package/dist/sync/index.js.map +1 -1
  196. package/dist/sync/push.d.ts.map +1 -1
  197. package/dist/sync/push.js +1 -2
  198. package/dist/sync/push.js.map +1 -1
  199. package/dist/sync/remint.d.ts +0 -31
  200. package/dist/sync/remint.d.ts.map +1 -1
  201. package/dist/sync/remint.js +32 -1
  202. package/dist/sync/remint.js.map +1 -1
  203. package/dist/sync/types.d.ts +4 -41
  204. package/dist/sync/types.d.ts.map +1 -1
  205. package/dist/sync/types.js +4 -47
  206. package/dist/sync/types.js.map +1 -1
  207. package/dist/unlock/index.d.ts +1 -1
  208. package/dist/unlock/index.d.ts.map +1 -1
  209. package/dist/unlock/index.js +1 -1
  210. package/dist/unlock/index.js.map +1 -1
  211. package/dist/unlock/retire.d.ts +16 -56
  212. package/dist/unlock/retire.d.ts.map +1 -1
  213. package/dist/unlock/retire.js +7 -76
  214. package/dist/unlock/retire.js.map +1 -1
  215. package/dist/unlock/standingWebvh.d.ts +20 -40
  216. package/dist/unlock/standingWebvh.d.ts.map +1 -1
  217. package/dist/unlock/standingWebvh.js +35 -76
  218. package/dist/unlock/standingWebvh.js.map +1 -1
  219. package/dist/unlock/unlockRecord.d.ts.map +1 -1
  220. package/dist/unlock/unlockRecord.js +69 -44
  221. package/dist/unlock/unlockRecord.js.map +1 -1
  222. package/dist/webvh/accountEntry.d.ts +63 -7
  223. package/dist/webvh/accountEntry.d.ts.map +1 -1
  224. package/dist/webvh/accountEntry.js +110 -19
  225. package/dist/webvh/accountEntry.js.map +1 -1
  226. package/dist/webvh/delegatedLogStore.d.ts +18 -12
  227. package/dist/webvh/delegatedLogStore.d.ts.map +1 -1
  228. package/dist/webvh/delegatedLogStore.js +32 -11
  229. package/dist/webvh/delegatedLogStore.js.map +1 -1
  230. package/dist/webvh/didWebvh.d.ts +39 -23
  231. package/dist/webvh/didWebvh.d.ts.map +1 -1
  232. package/dist/webvh/didWebvh.js +63 -45
  233. package/dist/webvh/didWebvh.js.map +1 -1
  234. package/dist/webvh/enrollClient.d.ts.map +1 -1
  235. package/dist/webvh/enrollClient.js +19 -23
  236. package/dist/webvh/enrollClient.js.map +1 -1
  237. package/dist/webvh/index.d.ts +11 -7
  238. package/dist/webvh/index.d.ts.map +1 -1
  239. package/dist/webvh/index.js +9 -6
  240. package/dist/webvh/index.js.map +1 -1
  241. package/dist/webvh/listClients.d.ts.map +1 -1
  242. package/dist/webvh/listClients.js +102 -65
  243. package/dist/webvh/listClients.js.map +1 -1
  244. package/dist/webvh/mergeMethods.d.ts +84 -0
  245. package/dist/webvh/mergeMethods.d.ts.map +1 -0
  246. package/dist/webvh/mergeMethods.js +46 -0
  247. package/dist/webvh/mergeMethods.js.map +1 -0
  248. package/dist/webvh/revokeClient.d.ts +12 -2
  249. package/dist/webvh/revokeClient.d.ts.map +1 -1
  250. package/dist/webvh/revokeClient.js +126 -48
  251. package/dist/webvh/revokeClient.js.map +1 -1
  252. package/dist/webvh/verifyLog.d.ts +21 -0
  253. package/dist/webvh/verifyLog.d.ts.map +1 -1
  254. package/dist/webvh/verifyLog.js +36 -14
  255. package/dist/webvh/verifyLog.js.map +1 -1
  256. package/package.json +11 -11
@@ -54,9 +54,9 @@ import { base64urlnopad } from '@scure/base';
54
54
  import { DID_LOG_RESOURCE } from '../space/collections.js';
55
55
  import { plaintextCollection } from '../space/plaintextCollection.js';
56
56
  import { resourceLogPinId } from '@interop/vh-resource-log';
57
- import { clientAnnexRung } from './ladder.js';
58
- import { assertCarryOverCommitments, assertPublishedLogDid, concludeWithPublishedLog, didWebvhControllerTemplate, MULTIKEY_VM_TYPE, pinOfLog, putLogResource, readPublishedLogOrThrow, updateKeySigner, WebvhLogConflictError, withLogConflictRetry } from '../webvh/didWebvh.js';
59
- import { signAccountEntry } from '../webvh/accountEntry.js';
57
+ import { clientAnnexRung, ladderRung } from './ladder.js';
58
+ import { advanceLogPin, assertCarryOverCommitments, assertPublishedLogDid, concludeWithPublishedLog, currentLogParameters, didWebvhControllerTemplate, MULTIKEY_VM_TYPE, putLogResource, readPublishedLogOrThrow, updateKeySigner, withLogConflictRetry, withThreadedHeadOnce } from '../webvh/didWebvh.js';
59
+ import { accountEntryHead, signAccountEntry } from '../webvh/accountEntry.js';
60
60
  import { relationIds } from '../resourceLog/document.js';
61
61
  import { STANDING_ZCAP_TTL_MS, standingZcapStale } from '../webvh/standingZcap.js';
62
62
  import { wasWebvhLogStore } from '../webvh/wasIdStore.js';
@@ -315,11 +315,14 @@ export async function ensureClientAnnexSpace({ was, spaceId, controller }) {
315
315
  * @param options.nextKeyHashes {string[]} every standing credential's
316
316
  * rung-0 hash, the minting credential's included
317
317
  * @param options.signer {Signer} the minting credential's rung-0 signer
318
- * @returns {Promise<{ did: string; generationId: string; log: DIDLog;
319
- * doc: DIDDoc; spaceDescription?: SpaceDescription }>} `spaceDescription`
320
- * is the auxiliary Space's Description as the ensure read or wrote it, so a
321
- * caller flipping the controller afterwards need not re-read it. Always
322
- * present here, since this minter always runs the ensure.
318
+ * @returns {Promise<PublishedWebvhLog & { generationId: string;
319
+ * spaceDescription?: SpaceDescription }>} the published head of the
320
+ * genesis log, which a stage building the generation's next entry can
321
+ * stand on instead of re-reading it, carrying the PUT's own ETag when the
322
+ * store handed one back. `spaceDescription` is the auxiliary Space's
323
+ * Description as the ensure read or wrote it, so a caller flipping the
324
+ * controller afterwards need not re-read it. Always present here, since
325
+ * this minter always runs the ensure.
323
326
  */
324
327
  export async function mintClientAnnexGeneration({ was, wasServerUrl, spaceId, controller, updateKeyPublicKeyMultibase, nextKeyHashes, signer }) {
325
328
  const spaceDescription = await ensureClientAnnexSpace({
@@ -354,8 +357,15 @@ export async function mintClientAnnexGeneration({ was, wasServerUrl, spaceId, co
354
357
  * @param options.signer {Signer}
355
358
  * @param [options.capability] {IZcap} an invocation capability the
356
359
  * collection create and the genesis publish ride (a delegated minter)
357
- * @returns {Promise<{ did: string; generationId: string; log: DIDLog;
358
- * doc: DIDDoc }>}
360
+ * @returns {Promise<PublishedWebvhLog & { generationId: string }>} the
361
+ * published head of the log this call just wrote -- the genesis log, its
362
+ * DID and document, the effective update-key parameters, and the PUT's own
363
+ * ETag when the store handed one back. It is what a stage building the
364
+ * generation's next entry can stand on instead of re-reading the log
365
+ * (see {@link ensureGenerationDelegationCurrent}'s `published`); the ETag
366
+ * is absent against a backend that serves none, where a caller must read
367
+ * for itself rather than degrade its compare-and-swap to an unconditional
368
+ * write.
359
369
  */
360
370
  async function publishClientAnnexGenesis({ was, wasServerUrl, spaceId, generationId, updateKeyPublicKeyMultibase, nextKeyHashes, signer, capability }) {
361
371
  // The generation collection must exist before its first resource PUT; a
@@ -378,7 +388,7 @@ async function publishClientAnnexGenesis({ was, wasServerUrl, spaceId, generatio
378
388
  nextKeyHashes,
379
389
  signer
380
390
  });
381
- await putLogResource({
391
+ const written = await putLogResource({
382
392
  store: clientAnnexLogStore({
383
393
  was,
384
394
  spaceId,
@@ -388,7 +398,12 @@ async function publishClientAnnexGenesis({ was, wasServerUrl, spaceId, generatio
388
398
  log: created.log,
389
399
  ifNoneMatch: true
390
400
  });
391
- return { ...created, generationId };
401
+ return {
402
+ ...created,
403
+ generationId,
404
+ ...currentLogParameters(created),
405
+ ...(written.etag !== undefined ? { etag: written.etag } : {})
406
+ };
392
407
  }
393
408
  /**
394
409
  * Mints a fresh annex generation signed by a standing CREDENTIAL's
@@ -422,11 +437,14 @@ async function publishClientAnnexGenesis({ was, wasServerUrl, spaceId, generatio
422
437
  * subtree). The typed-Space ensure is then skipped: the delegation's target
423
438
  * covers the collections beneath the Space, never the Space Description,
424
439
  * and a standing sibling delegation presupposes the auxiliary Space
425
- * @returns {Promise<{ did: string; generationId: string; log: DIDLog;
426
- * doc: DIDDoc; spaceDescription?: SpaceDescription }>} `spaceDescription`
427
- * is the auxiliary Space's Description as the ensure read or wrote it, so a
428
- * caller flipping the controller afterwards need not re-read it. Present
429
- * exactly when the ensure ran, so absent under a supplied `capability`.
440
+ * @returns {Promise<PublishedWebvhLog & { generationId: string;
441
+ * spaceDescription?: SpaceDescription }>} the published head of the
442
+ * genesis log, which a stage building the generation's next entry can
443
+ * stand on instead of re-reading it, carrying the PUT's own ETag when the
444
+ * store handed one back. `spaceDescription` is the auxiliary Space's
445
+ * Description as the ensure read or wrote it, so a caller flipping the
446
+ * controller afterwards need not re-read it. Present exactly when the
447
+ * ensure ran, so absent under a supplied `capability`.
430
448
  */
431
449
  export async function mintCredentialClientAnnexGeneration({ was, wasServerUrl, spaceId, controller, ladderSeed, extraNextKeyHashes = [], capability }) {
432
450
  const spaceDescription = capability === undefined
@@ -606,8 +624,8 @@ export const DELEGATED_CLIENTS_DELEGATION_ACTIONS = ['GET', 'PUT'];
606
624
  /**
607
625
  * The sibling delegation's lifetime: the house standing-zcap value (one
608
626
  * year; see `standingZcap.ts`). It rots on exactly the account bridge's axis
609
- * -- same signer, same current-key-set rule, same renewal window -- so the
610
- * re-mint pass that refreshes the bridge refreshes it too.
627
+ * -- same signer, same current-key-set rule, same renewal window -- so
628
+ * whatever refreshes the bridge refreshes it too.
611
629
  */
612
630
  export const DELEGATED_CLIENTS_DELEGATION_TTL_MS = STANDING_ZCAP_TTL_MS;
613
631
  /**
@@ -658,15 +676,14 @@ export async function mintDelegatedClientsDelegation({ zcapClient, wasServerUrl,
658
676
  }));
659
677
  }
660
678
  /**
661
- * Builds the annex-side sibling-delegation minter the enrolled-client record
662
- * re-mint orchestrator (`recovery/remintRecoveryDelegations`) takes as an
663
- * injected closure -- the boundary keeping that base orchestrator free of
664
- * annex imports. The returned closure reads the auxiliary annex Space id off
665
- * the verified document's delegated-clients service entry (the annex DID
666
- * string embeds it) and mints a fresh {@link mintDelegatedClientsDelegation}
667
- * to the named controller; it resolves `undefined` while the document points
668
- * at no generation, which the orchestrator reads as "carry the old sealed
669
- * member verbatim".
679
+ * Builds the annex-side sibling-delegation minter a record re-bind takes as
680
+ * an injected closure -- the boundary keeping a caller outside this subpath
681
+ * free of annex imports. The returned closure reads the auxiliary annex Space
682
+ * id off the verified document's delegated-clients service entry (the annex
683
+ * DID string embeds it) and mints a fresh
684
+ * {@link mintDelegatedClientsDelegation} to the named controller; it resolves
685
+ * `undefined` while the document points at no generation, which a caller
686
+ * reads as "carry the old sealed member verbatim".
670
687
  * @param options {object}
671
688
  * @param options.doc {object} the locally verified account document
672
689
  * @param options.zcapClient {ZcapClient} the acting client's promoted
@@ -945,7 +962,7 @@ export async function revokeTreatingAlreadyRevokedAsSuccess({ revoke, delegation
945
962
  await revoke(delegation);
946
963
  }
947
964
  catch (err) {
948
- if (err.name === 'ValidationError') {
965
+ if (err?.name === 'ValidationError') {
949
966
  return;
950
967
  }
951
968
  throw err;
@@ -1160,23 +1177,10 @@ async function readClientAnnexLogOrThrow({ store, expectedDid, pinStore, logId }
1160
1177
  * @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>}
1161
1178
  */
1162
1179
  export async function enrollClientAnnexTransientClient({ published: threadedHead, ...rest }) {
1163
- if (threadedHead !== undefined) {
1164
- try {
1165
- return await enrollClientAnnexTransientClientOnce({
1166
- ...rest,
1167
- published: threadedHead
1168
- });
1169
- }
1170
- catch (err) {
1171
- // A lost compare-and-swap on the threaded head says only that the head
1172
- // is stale; the retry below re-reads under the pin with its whole
1173
- // budget. Every other failure is the caller's.
1174
- if (!(err instanceof WebvhLogConflictError)) {
1175
- throw err;
1176
- }
1177
- }
1178
- }
1179
- return withLogConflictRetry(() => enrollClientAnnexTransientClientOnce(rest));
1180
+ return withThreadedHeadOnce({
1181
+ published: threadedHead,
1182
+ attempt: published => enrollClientAnnexTransientClientOnce({ ...rest, published })
1183
+ });
1180
1184
  }
1181
1185
  /**
1182
1186
  * One attempt of {@link enrollClientAnnexTransientClient}, re-invoked by the
@@ -1276,18 +1280,25 @@ async function enrollClientAnnexTransientClientOnce({ store, ladderSeed, generat
1276
1280
  // pre-entry log straight afterwards is refused as a rollback on the next
1277
1281
  // read (equal-to-pin would otherwise be accepted, and a later stage built on
1278
1282
  // the stale head would miss this entry).
1279
- if (pinStore && logId !== undefined) {
1280
- await pinStore.write({ logId, pin: pinOfLog(updated.log) });
1281
- }
1283
+ await advanceLogPin({ pinStore, logId, log: updated.log });
1282
1284
  return { did: updated.did, doc: updated.doc, log: updated.log };
1283
1285
  }
1284
1286
  /**
1285
1287
  * Points the account document's delegated-clients service entry at a
1286
1288
  * annex DID -- the first install after a generation's genesis, and the GC
1287
- * swap's re-point alike. One ordinary document-update entry, signed by an
1288
- * enrolled client's active update key; the annex log always
1289
- * publishes FIRST (see {@link mintClientAnnexGeneration}), so a tear leaves an
1290
- * unpointed, authorization-inert generation, never a dangling pointer.
1289
+ * swap's re-point alike. One ordinary document-update entry on either signer
1290
+ * arm; the annex log always publishes FIRST (see
1291
+ * {@link mintClientAnnexGeneration}), so a tear leaves an unpointed,
1292
+ * authorization-inert generation, never a dangling pointer.
1293
+ *
1294
+ * On the ladder arm the entry is the pointer move a credential-only caller
1295
+ * makes (the transient readiness pass, the establishment's stage 3): the
1296
+ * seam attributes the ladder's current rung per attempt, the rung reveals
1297
+ * itself in the entry it signs, and when it stood only committed the entry
1298
+ * also commits the next rung's hash, so one entry does what a reveal entry
1299
+ * followed by a client-signed pointer entry used to. A lost race re-runs the
1300
+ * attribution from the winner's head, which is what climbs to the winner's
1301
+ * committed rung (retry-up-the-ladder).
1291
1302
  *
1292
1303
  * An existing delegated-clients entry is re-pointed in place, its fragment id
1293
1304
  * preserved verbatim (the id is non-semantic and stable); absent one, a fresh
@@ -1295,18 +1306,19 @@ async function enrollClientAnnexTransientClientOnce({ store, ladderSeed, generat
1295
1306
  * service entry, the verification methods, and the relationship arrays are
1296
1307
  * preserved untouched. Idempotent: a document already pointing at the DID is
1297
1308
  * a no-op on the log (and, unless `logOnly`, it republishes `did.json` from
1298
- * the resolved log, which the enrolled-client caller has the authority to
1309
+ * the resolved log, which a controller-invoking caller has the authority to
1299
1310
  * do).
1300
1311
  *
1301
1312
  * @param options {object}
1302
1313
  * @param options.idStore {WebvhIdStore} the ACCOUNT log's store; with
1303
1314
  * `logOnly`, only its log read and `did.jsonl` PUT are used, so the narrow
1304
1315
  * delegated seam satisfies it
1305
- * @param options.signer {AccountLogSigner} who signs the pointer entry:
1306
- * this enrolled client's update-key seeds -- or the ladder-rung idiom on a
1307
- * ladder-anchored account (`{ updateSeed: rung0.seed, stagedSeed:
1308
- * rung1.seed }`), as the credential-anchored genesis and the
1309
- * transient-recovery continuation pass
1316
+ * @param options.signer {AccountLogSigner} who signs the pointer entry: an
1317
+ * enrolled client's own update-key seeds (`{ kind: 'client', updateKeys }`,
1318
+ * the GC swap's re-point and an enrolled client's stage-3 fold), or a
1319
+ * standing credential's ladder seed (`{ kind: 'ladder', ladderSeed }`),
1320
+ * under which the acting rung is attributed from the head each attempt
1321
+ * builds on
1310
1322
  * @param options.clientAnnexDid {string} the generation to point at
1311
1323
  * @param [options.expectedDid] {string} the account DID the log must
1312
1324
  * resolve to, from the account pointer
@@ -1316,13 +1328,16 @@ async function enrollClientAnnexTransientClientOnce({ store, ladderSeed, generat
1316
1328
  * `accountLogPinId({ spaceId })`; required whenever a `pinStore` is
1317
1329
  * supplied
1318
1330
  * @param [options.logOnly] {boolean} publish `did.jsonl` only, never the
1319
- * `did.json` projection -- the transient-recovery continuation writing
1320
- * through the record's bridge delegation, whose narrow scope covers nothing
1321
- * but the log. The projection then lags until some caller holding an
1322
- * `id`-collection writer runs `ensureDidWebProjection` over the resolved
1323
- * log; on a client-less account that is a transient visit under its
1324
- * generation delegation. The log stays the source of truth meanwhile, and
1325
- * the server reads it rather than the projection, so the lag is a `did:web`
1331
+ * `did.json` projection. Defaults per arm, as {@link signAccountEntry}
1332
+ * does: `true` on the ladder arm, since a transient visit writes through
1333
+ * the record's bridge delegation, whose narrow scope covers nothing but the
1334
+ * log, and `false` on the client arm. The establishment's stage 3, a ladder
1335
+ * signer over a root-invoking store, passes `false` explicitly. A lagging
1336
+ * projection is republished when some caller holding an `id`-collection
1337
+ * writer runs `ensureDidWebProjection` over the resolved log; on a
1338
+ * client-less account that is a transient visit under its generation
1339
+ * delegation. The log stays the source of truth meanwhile, and the server
1340
+ * reads it rather than the projection, so the lag is a `did:web`
1326
1341
  * verifier's concern alone
1327
1342
  * @param [options.published] {PublishedWebvhLog} a head the caller already
1328
1343
  * read and verified under this same pin slot, so the pointer entry builds
@@ -1333,55 +1348,36 @@ async function enrollClientAnnexTransientClientOnce({ store, ladderSeed, generat
1333
1348
  * threaded attempt is EXTRA rather than one of the retry's three: a caller
1334
1349
  * who saved a read is left with the same conflict budget as one who did not
1335
1350
  * @returns {Promise<{ did: string, doc: DIDDoc,
1336
- * published: PublishedWebvhLog }>} `published` is the head this call
1337
- * leaves standing: the post-entry one, paired with its publish's own ETag,
1338
- * when the entry was appended; the head it stood on verbatim when the
1339
- * document already pointed at the DID
1351
+ * published: PublishedWebvhLog, rung?: LadderRung }>} `published` is the
1352
+ * head this call leaves standing: the post-entry one, paired with its
1353
+ * publish's own ETag, when the entry was appended; the head it stood on
1354
+ * verbatim when the document already pointed at the DID. `rung` stands on
1355
+ * the ladder arm alone: the rung the entry was signed with, or, when the
1356
+ * document already pointed, the ladder's currently attributed rung
1340
1357
  */
1341
1358
  export async function setDelegatedClientsPointer({ published: threadedHead, ...rest }) {
1342
- if (threadedHead !== undefined) {
1343
- try {
1344
- return await setDelegatedClientsPointerOnce({
1345
- ...rest,
1346
- published: threadedHead
1347
- });
1348
- }
1349
- catch (err) {
1350
- // A lost compare-and-swap on the threaded head says only that the head
1351
- // is stale; the retry below re-reads under the pin with its whole
1352
- // budget. Every other failure is the caller's.
1353
- if (!(err instanceof WebvhLogConflictError)) {
1354
- throw err;
1355
- }
1356
- }
1357
- }
1358
- return withLogConflictRetry(() => setDelegatedClientsPointerOnce(rest));
1359
+ return withThreadedHeadOnce({
1360
+ published: threadedHead,
1361
+ attempt: published => setDelegatedClientsPointerOnce({ ...rest, published })
1362
+ });
1359
1363
  }
1360
1364
  /**
1361
1365
  * ONE attempt of {@link setDelegatedClientsPointer}, re-invoked by that
1362
- * function's conflict retry and exported for a caller that runs its own.
1363
- * A caller whose retry loop also attributes the signing rung must use this
1364
- * form: the wrapper's inner retry would re-invoke the attempt with the SAME
1365
- * signer, and a rung a racing ceremony consumed meanwhile can never
1366
- * become authorized by re-reading, so the attempt would fail on the plain
1367
- * not-authorized refusal instead of surfacing the conflict the caller's loop
1368
- * knows how to re-attribute from.
1369
- *
1370
- * A caller that already read the head its signer was attributed
1371
- * against passes it as `published`, and the entry is built on exactly that
1372
- * head. A racing entry landing in between then loses the CAS on the PUT and
1373
- * surfaces as a {@link WebvhLogConflictError}, which is what a re-attributing
1374
- * loop retries -- rather than as the not-authorized refusal a fresh read of
1375
- * the winner's head would produce.
1366
+ * function's conflict retry and exported for a caller that runs its own
1367
+ * retry around it.
1368
+ *
1369
+ * A caller that already read the head passes it as `published`, and the
1370
+ * entry is built on exactly that head. A racing entry landing in between
1371
+ * then loses the CAS on the PUT and surfaces as a
1372
+ * {@link WebvhLogConflictError} for the retry to re-run.
1376
1373
  *
1377
1374
  * @param options {object} see {@link setDelegatedClientsPointer}, plus:
1378
1375
  * @param [options.published] {PublishedWebvhLog} the verified head to build
1379
1376
  * this entry on, when the caller has already read it under the same pin;
1380
1377
  * absent, the attempt reads the head itself
1381
- * @returns {Promise<{ did: string, doc: DIDDoc,
1382
- * published: PublishedWebvhLog }>}
1378
+ * @returns {Promise<PointerEntryOutcome>}
1383
1379
  */
1384
- export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAnnexDid, expectedDid, pinStore, logId, logOnly = false, published: alreadyRead }) {
1380
+ export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAnnexDid, expectedDid, pinStore, logId, logOnly = signer.kind === 'ladder', published: alreadyRead }) {
1385
1381
  // Refuses a malformed target before anything is read or written.
1386
1382
  clientAnnexDidParts({ did: clientAnnexDid });
1387
1383
  let settled;
@@ -1395,10 +1391,10 @@ export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAn
1395
1391
  missingMessage: 'did:webvh: did.jsonl is missing; nothing to point at a client annex.',
1396
1392
  verb: 're-pointing the delegated-clients entry',
1397
1393
  logOnly,
1398
- build: async ({ published }) => {
1394
+ build: async ({ published, rung, state }) => {
1399
1395
  const { did, doc } = published;
1400
1396
  if (delegatedClientsPointer({ doc }) === clientAnnexDid) {
1401
- if (!logOnly && signer.kind === 'client') {
1397
+ if (!logOnly) {
1402
1398
  await concludeWithPublishedLog({ idStore, published });
1403
1399
  }
1404
1400
  // The head verbatim: the projection PUT touches no log, so this
@@ -1406,7 +1402,20 @@ export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAn
1406
1402
  settled = { did, doc, published };
1407
1403
  return undefined;
1408
1404
  }
1405
+ // A ladder rung standing only as a committed hash reveals itself
1406
+ // through the seam's reveal union; this entry commits the next rung
1407
+ // beside it, so the ladder stays prerotated past the move. An already
1408
+ // revealed rung re-states the parameters verbatim.
1409
+ const commitHashes = signer.kind === 'ladder' && state === 'committed'
1410
+ ? [
1411
+ await deriveNextKeyHash((await ladderRung({
1412
+ ladderSeed: signer.ladderSeed,
1413
+ index: rung.index + 1
1414
+ })).keyMultibase)
1415
+ ]
1416
+ : undefined;
1409
1417
  return {
1418
+ ...(commitHashes !== undefined ? { commitHashes } : {}),
1410
1419
  services: servicesPointedAtClientAnnex({
1411
1420
  doc,
1412
1421
  accountDid: did,
@@ -1415,8 +1424,9 @@ export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAn
1415
1424
  };
1416
1425
  }
1417
1426
  });
1427
+ const ladderRungPart = outcome.rung !== undefined ? { rung: outcome.rung } : {};
1418
1428
  if (settled) {
1419
- return settled;
1429
+ return { ...settled, ...ladderRungPart };
1420
1430
  }
1421
1431
  const updated = outcome.updated;
1422
1432
  return {
@@ -1425,16 +1435,8 @@ export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAn
1425
1435
  // The post-entry head, from what `updateDID` already resolved plus this
1426
1436
  // publish's own validator: the update-key parameters are the ones the
1427
1437
  // entry re-stated unchanged above, so nothing is re-resolved or re-read.
1428
- published: {
1429
- log: updated.log,
1430
- did: updated.did,
1431
- // Detached from the entry's own `state`, as every other producer of
1432
- // this type is, so a consumer editing the document cannot edit the log.
1433
- doc: structuredClone(updated.doc),
1434
- updateKeys: updated.meta.updateKeys,
1435
- nextKeyHashes: updated.meta.nextKeyHashes,
1436
- ...(outcome.etag !== undefined ? { etag: outcome.etag } : {})
1437
- }
1438
+ published: accountEntryHead({ outcome }),
1439
+ ...ladderRungPart
1438
1440
  };
1439
1441
  }
1440
1442
  /**
@@ -1522,6 +1524,93 @@ export async function enrollTransientClient({ readAccountDocument, storeForGener
1522
1524
  throw new Error('client annex: the delegated-clients pointer kept moving across ' +
1523
1525
  `${String(maxRounds)} enrollment rounds; giving up.`);
1524
1526
  }
1527
+ /**
1528
+ * The fresh-generation block every separate-pointer-entry caller runs: mint
1529
+ * a generation in the annex Space, install its generation delegation, then
1530
+ * append the account document's pointer entry naming it. The pointer write is
1531
+ * the injected step (`point`): an enrolled client signs it under its own
1532
+ * update keys, and a credential-only caller (the establishment, the
1533
+ * transient visit) moves it as the ladder, one rung-signed entry per attempt. A
1534
+ * caller with a step that must land
1535
+ * between the install and the pointer entry (the establishment's bootstrap
1536
+ * arm, whose Space still answers to its creation controller until it flips
1537
+ * it to the account DID) supplies `beforePointerEntry`.
1538
+ *
1539
+ * The install stands on the head the mint just published rather than
1540
+ * re-reading the log this run wrote a moment ago -- but only when that head
1541
+ * carries the PUT's own ETag, since the install's entry publishes under a
1542
+ * compare-and-swap and a head with no validator would degrade that to an
1543
+ * unconditional write. With no ETag the install reads for itself. Either way
1544
+ * its own publish advances the pin, so this generation's pin slot is
1545
+ * established by this run.
1546
+ *
1547
+ * @param options {object}
1548
+ * @param options.was {WasClient} the storage client the mint and the
1549
+ * install write through
1550
+ * @param options.wasServerUrl {string}
1551
+ * @param options.spaceId {string} the auxiliary annex Space's id
1552
+ * @param options.controller {string} the Space's creation controller (see
1553
+ * {@link mintCredentialClientAnnexGeneration})
1554
+ * @param options.ladderSeed {Uint8Array} the minting credential's ladder
1555
+ * seed
1556
+ * @param options.mintGenerationDelegation {Function}
1557
+ * `({ clientAnnexDid }) => Promise<IZcap>`
1558
+ * @param options.point {Function} `(clientAnnexDid) => Promise<T>` -- the
1559
+ * pointer entry, whose result rides the return verbatim
1560
+ * @param [options.capability] {IZcap} the sibling delegation the annex
1561
+ * writes ride, for a caller holding a standing invocation authority
1562
+ * @param [options.beforePointerEntry] {Function}
1563
+ * `({ minted }) => Promise<void>` -- runs after the install and before the
1564
+ * pointer entry, with the mint's published head (its `spaceDescription`
1565
+ * included)
1566
+ * @param [options.pinStore] {ResourceLogPinStore} chain-head pins; the
1567
+ * generation's slot is derived here
1568
+ * @param [options.now] {number} epoch milliseconds, for tests
1569
+ * @returns {Promise<{ clientAnnexDid: string, generationDelegation: IZcap,
1570
+ * pointed: T }>}
1571
+ */
1572
+ export async function mintPointedClientAnnexGeneration({ was, wasServerUrl, spaceId, controller, ladderSeed, mintGenerationDelegation, point, capability, beforePointerEntry, pinStore, now }) {
1573
+ const minted = await mintCredentialClientAnnexGeneration({
1574
+ was,
1575
+ wasServerUrl,
1576
+ spaceId,
1577
+ controller,
1578
+ ladderSeed,
1579
+ ...(capability !== undefined ? { capability } : {})
1580
+ });
1581
+ const ensured = await ensureGenerationDelegationCurrent({
1582
+ store: clientAnnexLogStore({
1583
+ was,
1584
+ spaceId,
1585
+ generationId: minted.generationId,
1586
+ ...(capability !== undefined ? { capability } : {})
1587
+ }),
1588
+ ladderSeed,
1589
+ generationId: minted.generationId,
1590
+ mintGenerationDelegation,
1591
+ expectedDid: minted.did,
1592
+ ...(minted.etag !== undefined ? { published: minted } : {}),
1593
+ ...(pinStore !== undefined
1594
+ ? {
1595
+ pinStore,
1596
+ logId: clientAnnexLogPinId({
1597
+ spaceId,
1598
+ generationId: minted.generationId
1599
+ })
1600
+ }
1601
+ : {}),
1602
+ ...(now !== undefined ? { now } : {})
1603
+ });
1604
+ if (beforePointerEntry !== undefined) {
1605
+ await beforePointerEntry({ minted });
1606
+ }
1607
+ const pointed = await point(minted.did);
1608
+ return {
1609
+ clientAnnexDid: minted.did,
1610
+ generationDelegation: ensured.delegation,
1611
+ pointed
1612
+ };
1613
+ }
1525
1614
  /**
1526
1615
  * RENEW PRECEDES MINT: the blocking pre-mint stage a transient App Connect
1527
1616
  * approval runs before delegating any grant. Reads the annex document
@@ -1603,23 +1692,10 @@ export async function enrollTransientClient({ readAccountDocument, storeForGener
1603
1692
  * wanting one reads for itself
1604
1693
  */
1605
1694
  export async function ensureGenerationDelegationCurrent({ published: threadedHead, ...rest }) {
1606
- if (threadedHead !== undefined) {
1607
- try {
1608
- return await ensureGenerationDelegationCurrentOnce({
1609
- ...rest,
1610
- published: threadedHead
1611
- });
1612
- }
1613
- catch (err) {
1614
- // A lost compare-and-swap on the threaded head says only that the head
1615
- // is stale; the retry below re-reads under the pin with its whole
1616
- // budget. Every other failure is the caller's.
1617
- if (!(err instanceof WebvhLogConflictError)) {
1618
- throw err;
1619
- }
1620
- }
1621
- }
1622
- return withLogConflictRetry(() => ensureGenerationDelegationCurrentOnce(rest));
1695
+ return withThreadedHeadOnce({
1696
+ published: threadedHead,
1697
+ attempt: published => ensureGenerationDelegationCurrentOnce({ ...rest, published })
1698
+ });
1623
1699
  }
1624
1700
  /**
1625
1701
  * One attempt of {@link ensureGenerationDelegationCurrent}, re-invoked by the
@@ -1689,9 +1765,7 @@ async function ensureGenerationDelegationCurrentOnce({ store, ladderSeed, genera
1689
1765
  // pre-entry log straight afterwards is refused as a rollback on the next
1690
1766
  // read (equal-to-pin would otherwise be accepted, and a later stage built on
1691
1767
  // the stale head would miss this entry).
1692
- if (pinStore && logId !== undefined) {
1693
- await pinStore.write({ logId, pin: pinOfLog(updated.log) });
1694
- }
1768
+ await advanceLogPin({ pinStore, logId, log: updated.log });
1695
1769
  return { delegation: fresh, renewed: true };
1696
1770
  }
1697
1771
  /**