@interop/wallet-core 0.108.0 → 0.110.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts +3 -3
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts.map +1 -1
- package/dist/clientAnnex/credentialAnchoredGenesis.js +3 -3
- package/dist/clientAnnex/credentialAnchoredGenesis.js.map +1 -1
- package/dist/clientAnnex/establish.d.ts +5 -5
- package/dist/clientAnnex/establish.d.ts.map +1 -1
- package/dist/clientAnnex/establish.js +15 -12
- package/dist/clientAnnex/establish.js.map +1 -1
- package/dist/clientAnnex/forgetLast.d.ts +2 -2
- package/dist/clientAnnex/forgetLast.d.ts.map +1 -1
- package/dist/clientAnnex/forgetLast.js +2 -2
- package/dist/clientAnnex/forgetLast.js.map +1 -1
- package/dist/clientAnnex/gc.d.ts +35 -6
- package/dist/clientAnnex/gc.d.ts.map +1 -1
- package/dist/clientAnnex/gc.js +50 -13
- package/dist/clientAnnex/gc.js.map +1 -1
- package/dist/clientAnnex/heal.d.ts +5 -5
- package/dist/clientAnnex/heal.d.ts.map +1 -1
- package/dist/clientAnnex/heal.js +29 -16
- package/dist/clientAnnex/heal.js.map +1 -1
- package/dist/clientAnnex/index.d.ts +2 -2
- package/dist/clientAnnex/index.d.ts.map +1 -1
- package/dist/clientAnnex/index.js +1 -1
- package/dist/clientAnnex/index.js.map +1 -1
- package/dist/clientAnnex/ladderAnchored.d.ts +5 -5
- package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -1
- package/dist/clientAnnex/ladderAnchored.js +7 -7
- package/dist/clientAnnex/ladderAnchored.js.map +1 -1
- package/dist/clientAnnex/log.d.ts +190 -33
- package/dist/clientAnnex/log.d.ts.map +1 -1
- package/dist/clientAnnex/log.js +269 -56
- package/dist/clientAnnex/log.js.map +1 -1
- package/dist/clientAnnex/mend.d.ts.map +1 -1
- package/dist/clientAnnex/mend.js +22 -16
- package/dist/clientAnnex/mend.js.map +1 -1
- package/dist/clientAnnex/selfEnroll.d.ts.map +1 -1
- package/dist/clientAnnex/selfEnroll.js +5 -6
- package/dist/clientAnnex/selfEnroll.js.map +1 -1
- package/dist/clientAnnex/spaceCapability.d.ts +6 -6
- package/dist/clientAnnex/spaceCapability.d.ts.map +1 -1
- package/dist/clientAnnex/spaceCapability.js +9 -12
- package/dist/clientAnnex/spaceCapability.js.map +1 -1
- package/dist/clients/index.d.ts +1 -1
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/listing.d.ts +12 -18
- package/dist/clients/listing.d.ts.map +1 -1
- package/dist/clients/listing.js +17 -13
- package/dist/clients/listing.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +4 -4
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +5 -4
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/connections/grantProof.d.ts.map +1 -1
- package/dist/connections/grantProof.js +4 -5
- package/dist/connections/grantProof.js.map +1 -1
- package/dist/connections/grants.d.ts +48 -3
- package/dist/connections/grants.d.ts.map +1 -1
- package/dist/connections/grants.js +54 -3
- package/dist/connections/grants.js.map +1 -1
- package/dist/connections/index.d.ts +7 -4
- package/dist/connections/index.d.ts.map +1 -1
- package/dist/connections/index.js +7 -4
- package/dist/connections/index.js.map +1 -1
- package/dist/connections/replicas.d.ts +43 -1
- package/dist/connections/replicas.d.ts.map +1 -1
- package/dist/connections/replicas.js +87 -14
- package/dist/connections/replicas.js.map +1 -1
- package/dist/connections/upsert.d.ts +52 -19
- package/dist/connections/upsert.d.ts.map +1 -1
- package/dist/connections/upsert.js +93 -41
- package/dist/connections/upsert.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +4 -5
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/genesis/accountGenesis.d.ts +4 -4
- package/dist/genesis/accountGenesis.d.ts.map +1 -1
- package/dist/genesis/accountGenesis.js +4 -4
- package/dist/genesis/accountGenesis.js.map +1 -1
- package/dist/keyring/fetch.d.ts +3 -3
- package/dist/keyring/fetch.d.ts.map +1 -1
- package/dist/keyring/fetch.js +3 -3
- package/dist/keyring/fetch.js.map +1 -1
- package/dist/keyring/record.d.ts.map +1 -1
- package/dist/keyring/record.js +1 -2
- package/dist/keyring/record.js.map +1 -1
- package/dist/keyring/recordEnvelope.d.ts +8 -6
- package/dist/keyring/recordEnvelope.d.ts.map +1 -1
- package/dist/keyring/recordEnvelope.js +12 -6
- package/dist/keyring/recordEnvelope.js.map +1 -1
- package/dist/keyring/unlockSpace.d.ts +15 -15
- package/dist/keyring/unlockSpace.d.ts.map +1 -1
- package/dist/keyring/unlockSpace.js +18 -19
- package/dist/keyring/unlockSpace.js.map +1 -1
- package/dist/keys/collectionLogStore.d.ts +3 -3
- package/dist/keys/collectionLogStore.d.ts.map +1 -1
- package/dist/keys/collectionLogStore.js +5 -7
- package/dist/keys/collectionLogStore.js.map +1 -1
- package/dist/keys/rosterStore.d.ts +3 -3
- package/dist/keys/rosterStore.d.ts.map +1 -1
- package/dist/keys/rosterStore.js +3 -4
- package/dist/keys/rosterStore.js.map +1 -1
- package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
- package/dist/recovery/recoveryDelegation.js +2 -21
- package/dist/recovery/recoveryDelegation.js.map +1 -1
- package/dist/space/collections.d.ts +2 -2
- package/dist/space/collections.js +2 -2
- package/dist/space/deleteSpace.d.ts +3 -3
- package/dist/space/deleteSpace.d.ts.map +1 -1
- package/dist/space/deleteSpace.js +3 -4
- package/dist/space/deleteSpace.js.map +1 -1
- package/dist/space/errors.d.ts +1 -1
- package/dist/space/errors.js +1 -1
- package/dist/space/index.d.ts +4 -4
- package/dist/space/index.js +3 -3
- package/dist/space/provisioning.d.ts.map +1 -1
- package/dist/space/provisioning.js +6 -5
- package/dist/space/provisioning.js.map +1 -1
- package/dist/space/publicLink.d.ts +4 -4
- package/dist/space/publicLink.d.ts.map +1 -1
- package/dist/space/publicLink.js +9 -8
- package/dist/space/publicLink.js.map +1 -1
- package/dist/space/pwsLink.d.ts +58 -0
- package/dist/space/pwsLink.d.ts.map +1 -0
- package/dist/space/{wasLink.js → pwsLink.js} +42 -37
- package/dist/space/pwsLink.js.map +1 -0
- package/dist/testing/accountBuilder.d.ts +19 -19
- package/dist/testing/accountBuilder.d.ts.map +1 -1
- package/dist/testing/accountBuilder.js +44 -40
- package/dist/testing/accountBuilder.js.map +1 -1
- package/dist/unlock/unlockRecord.d.ts.map +1 -1
- package/dist/unlock/unlockRecord.js +7 -7
- package/dist/unlock/unlockRecord.js.map +1 -1
- package/dist/webvh/clientAnnexDid.d.ts +21 -14
- package/dist/webvh/clientAnnexDid.d.ts.map +1 -1
- package/dist/webvh/clientAnnexDid.js +19 -14
- package/dist/webvh/clientAnnexDid.js.map +1 -1
- package/dist/webvh/delegatedLogStore.d.ts +3 -3
- package/dist/webvh/delegatedLogStore.d.ts.map +1 -1
- package/dist/webvh/delegatedLogStore.js +9 -8
- package/dist/webvh/delegatedLogStore.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts +6 -25
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +19 -34
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/index.d.ts +1 -1
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +1 -1
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/logLocation.d.ts +75 -0
- package/dist/webvh/logLocation.d.ts.map +1 -0
- package/dist/webvh/logLocation.js +102 -0
- package/dist/webvh/logLocation.js.map +1 -0
- package/dist/webvh/verifyLog.d.ts +9 -18
- package/dist/webvh/verifyLog.d.ts.map +1 -1
- package/dist/webvh/verifyLog.js +43 -50
- package/dist/webvh/verifyLog.js.map +1 -1
- package/package.json +5 -5
- package/dist/space/wasLink.d.ts +0 -57
- package/dist/space/wasLink.d.ts.map +0 -1
- package/dist/space/wasLink.js.map +0 -1
package/dist/clientAnnex/log.js
CHANGED
|
@@ -27,10 +27,13 @@
|
|
|
27
27
|
* portability move.
|
|
28
28
|
* - The genesis document is bare -- no verification methods, no service
|
|
29
29
|
* entries, the DID core context only. Transient verification methods are
|
|
30
|
-
* published per visit by later entries
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
30
|
+
* published per visit by later entries. The entry that installs the
|
|
31
|
+
* generation delegation (the swap's install stage, or the entry publishing
|
|
32
|
+
* the generation's first transient method) also carries the generation's
|
|
33
|
+
* replica pointers, one entry per replica server the caller restates.
|
|
34
|
+
* Genesis carries neither: the delegation's bytes would have to name the
|
|
35
|
+
* SCID the genesis hash derives from, and the pointers ride the same entry
|
|
36
|
+
* so a generation with no delegation points at no replica.
|
|
34
37
|
* - No `did:web` projection exists: the generation collection holds only its
|
|
35
38
|
* `did.jsonl`, capability-gated rather than world-readable.
|
|
36
39
|
*
|
|
@@ -47,13 +50,16 @@
|
|
|
47
50
|
* generation collection's name, and the annex DID string embeds it.
|
|
48
51
|
*/
|
|
49
52
|
import { createDID, deriveNextKeyHash, updateDID } from '@interop/did-method-webvh';
|
|
50
|
-
import {
|
|
53
|
+
import { createMultihash, MultihashAlgorithm } from '@interop/data-integrity-core/multihash';
|
|
54
|
+
import { rootCapabilityId, spaceUrlById } from '@interop/was-client/paths';
|
|
55
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
51
56
|
import { base64urlnopad } from '@scure/base';
|
|
52
57
|
import { isJsonObject } from '../jsonObject.js';
|
|
58
|
+
import { ID_COLLECTION } from '../space/collections.js';
|
|
53
59
|
import { plaintextCollection } from '../space/plaintextCollection.js';
|
|
54
60
|
import { clientAnnexRung } from './generationRung.js';
|
|
55
61
|
import { ladderRung } from '../webvh/ladderDerivation.js';
|
|
56
|
-
import { assertCarryOverCommitments, assertPublishedLogDid, currentLogParameters, didWebvhControllerTemplate, MULTIKEY_VM_TYPE, putLogResource, readPublishedLog, readPublishedLogOrThrow, updateKeySigner, withLogConflictRetry, withThreadedHeadOnce } from '../webvh/didWebvh.js';
|
|
62
|
+
import { assertCarryOverCommitments, assertPublishedLogDid, currentLogParameters, didWebvhControllerTemplate, didWebvhLogLocation, didWebvhLogPaths, MULTIKEY_VM_TYPE, putLogResource, readPublishedLog, readPublishedLogOrThrow, updateKeySigner, withLogConflictRetry, withThreadedHeadOnce } from '../webvh/didWebvh.js';
|
|
57
63
|
import { accountEntryHead, signAccountEntry } from '../webvh/accountEntry.js';
|
|
58
64
|
import { relationIds } from '../resourceLog/document.js';
|
|
59
65
|
import { delegationAtExpiry, delegationExpired, delegationSignerGone, STANDING_ZCAP_TTL_MS, standingZcapStale } from '../webvh/standingZcap.js';
|
|
@@ -160,7 +166,7 @@ const MULTIKEY_CONTEXT_URL = 'https://w3id.org/security/multikey/v1';
|
|
|
160
166
|
* publishing a generation no one can ever extend.
|
|
161
167
|
*
|
|
162
168
|
* @param options {object}
|
|
163
|
-
* @param options.
|
|
169
|
+
* @param options.baseServerUrl {string}
|
|
164
170
|
* @param options.spaceId {string} the auxiliary annex Space's id
|
|
165
171
|
* @param options.generationId {string} the generation collection's name
|
|
166
172
|
* @param options.updateKeyPublicKeyMultibase {string} the minting
|
|
@@ -171,7 +177,7 @@ const MULTIKEY_CONTEXT_URL = 'https://w3id.org/security/multikey/v1';
|
|
|
171
177
|
* @returns {Promise<object>} the one-entry log, its DID and document, and
|
|
172
178
|
* the resolver's meta for it
|
|
173
179
|
*/
|
|
174
|
-
export async function createClientAnnexLog({
|
|
180
|
+
export async function createClientAnnexLog({ baseServerUrl, spaceId, generationId, updateKeyPublicKeyMultibase, nextKeyHashes, signer }) {
|
|
175
181
|
assertGenerationId(generationId);
|
|
176
182
|
const carryOverHash = await deriveNextKeyHash(updateKeyPublicKeyMultibase);
|
|
177
183
|
if (!nextKeyHashes.includes(carryOverHash)) {
|
|
@@ -179,15 +185,14 @@ export async function createClientAnnexLog({ wasServerUrl, spaceId, generationId
|
|
|
179
185
|
"credential's own rung-0 hash (the carry-over commitment), or no " +
|
|
180
186
|
'later entry could ever re-state the revealed key.');
|
|
181
187
|
}
|
|
182
|
-
const { host } = new URL(wasServerUrl);
|
|
183
188
|
const controllerTemplate = didWebvhControllerTemplate({
|
|
184
|
-
|
|
189
|
+
baseServerUrl,
|
|
185
190
|
spaceId,
|
|
186
191
|
collectionId: generationId
|
|
187
192
|
});
|
|
188
193
|
const result = await createDID({
|
|
189
|
-
address:
|
|
190
|
-
paths:
|
|
194
|
+
address: baseServerUrl,
|
|
195
|
+
paths: didWebvhLogPaths({ spaceId, collectionId: generationId }),
|
|
191
196
|
signer,
|
|
192
197
|
updateKeys: [updateKeyPublicKeyMultibase],
|
|
193
198
|
nextKeyHashes,
|
|
@@ -295,7 +300,7 @@ function typedAnnexSpace({ spaceId, read }) {
|
|
|
295
300
|
* @param options {object}
|
|
296
301
|
* @param options.was {WasClient} the storage client, signing as an enrolled
|
|
297
302
|
* client (or the bootstrap controller on a ladder-anchored signup)
|
|
298
|
-
* @param options.
|
|
303
|
+
* @param options.baseServerUrl {string}
|
|
299
304
|
* @param options.spaceId {string} the auxiliary annex Space's id
|
|
300
305
|
* @param options.controller {string} the auxiliary Space's controller, used
|
|
301
306
|
* only when the Space does not exist yet
|
|
@@ -315,7 +320,7 @@ function typedAnnexSpace({ spaceId, read }) {
|
|
|
315
320
|
* controller afterwards need not re-read it. Always present here, since
|
|
316
321
|
* this minter always runs the ensure.
|
|
317
322
|
*/
|
|
318
|
-
export async function mintClientAnnexGeneration({ was,
|
|
323
|
+
export async function mintClientAnnexGeneration({ was, baseServerUrl, spaceId, controller, updateKeyPublicKeyMultibase, nextKeyHashes, signer, pinStore }) {
|
|
319
324
|
const spaceDescription = await ensureClientAnnexSpace({
|
|
320
325
|
was,
|
|
321
326
|
spaceId,
|
|
@@ -324,7 +329,7 @@ export async function mintClientAnnexGeneration({ was, wasServerUrl, spaceId, co
|
|
|
324
329
|
const generationId = mintGenerationId();
|
|
325
330
|
const published = await publishClientAnnexGenesis({
|
|
326
331
|
was,
|
|
327
|
-
|
|
332
|
+
baseServerUrl,
|
|
328
333
|
spaceId,
|
|
329
334
|
generationId,
|
|
330
335
|
updateKeyPublicKeyMultibase,
|
|
@@ -341,7 +346,7 @@ export async function mintClientAnnexGeneration({ was, wasServerUrl, spaceId, co
|
|
|
341
346
|
*
|
|
342
347
|
* @param options {object}
|
|
343
348
|
* @param options.was {WasClient}
|
|
344
|
-
* @param options.
|
|
349
|
+
* @param options.baseServerUrl {string}
|
|
345
350
|
* @param options.spaceId {string} the auxiliary annex Space's id
|
|
346
351
|
* @param options.generationId {string} the freshly minted generation id
|
|
347
352
|
* @param options.updateKeyPublicKeyMultibase {string}
|
|
@@ -361,7 +366,7 @@ export async function mintClientAnnexGeneration({ was, wasServerUrl, spaceId, co
|
|
|
361
366
|
* for itself rather than degrade its compare-and-swap to an unconditional
|
|
362
367
|
* write.
|
|
363
368
|
*/
|
|
364
|
-
async function publishClientAnnexGenesis({ was,
|
|
369
|
+
async function publishClientAnnexGenesis({ was, baseServerUrl, spaceId, generationId, updateKeyPublicKeyMultibase, nextKeyHashes, signer, pinStore, capability }) {
|
|
365
370
|
// The generation collection must exist before its first resource PUT; a
|
|
366
371
|
// fresh random generation id means this is always a create, so the truthful
|
|
367
372
|
// `current: null` skips was-client's pre-merge describe of a Collection
|
|
@@ -375,7 +380,7 @@ async function publishClientAnnexGenesis({ was, wasServerUrl, spaceId, generatio
|
|
|
375
380
|
capability
|
|
376
381
|
}).configure({ current: null, name: generationId, force: true });
|
|
377
382
|
const created = await createClientAnnexLog({
|
|
378
|
-
|
|
383
|
+
baseServerUrl,
|
|
379
384
|
spaceId,
|
|
380
385
|
generationId,
|
|
381
386
|
updateKeyPublicKeyMultibase,
|
|
@@ -413,7 +418,7 @@ async function publishClientAnnexGenesis({ was, wasServerUrl, spaceId, generatio
|
|
|
413
418
|
* @param options {object}
|
|
414
419
|
* @param options.was {WasClient} the storage client, signing as an enrolled
|
|
415
420
|
* client (or the bootstrap controller on a ladder-anchored signup)
|
|
416
|
-
* @param options.
|
|
421
|
+
* @param options.baseServerUrl {string}
|
|
417
422
|
* @param options.spaceId {string} the auxiliary annex Space's id
|
|
418
423
|
* @param options.controller {string} the auxiliary Space's controller, used
|
|
419
424
|
* only when the Space does not exist yet
|
|
@@ -447,7 +452,7 @@ async function publishClientAnnexGenesis({ was, wasServerUrl, spaceId, generatio
|
|
|
447
452
|
* controller afterwards need not re-read it. Present exactly when the
|
|
448
453
|
* ensure ran, so absent under a supplied `capability`.
|
|
449
454
|
*/
|
|
450
|
-
export async function mintCredentialClientAnnexGeneration({ was,
|
|
455
|
+
export async function mintCredentialClientAnnexGeneration({ was, baseServerUrl, spaceId, controller, ladderSeed, pinStore, standingRungHashes = [], capability }) {
|
|
451
456
|
const spaceDescription = capability === undefined
|
|
452
457
|
? await ensureClientAnnexSpace({ was, spaceId, controller })
|
|
453
458
|
: undefined;
|
|
@@ -456,7 +461,7 @@ export async function mintCredentialClientAnnexGeneration({ was, wasServerUrl, s
|
|
|
456
461
|
const ownHash = await deriveNextKeyHash(rung.keyMultibase);
|
|
457
462
|
const published = await publishClientAnnexGenesis({
|
|
458
463
|
was,
|
|
459
|
-
|
|
464
|
+
baseServerUrl,
|
|
460
465
|
spaceId,
|
|
461
466
|
generationId,
|
|
462
467
|
updateKeyPublicKeyMultibase: rung.keyMultibase,
|
|
@@ -601,9 +606,9 @@ export function delegatedClientsPointer({ doc }) {
|
|
|
601
606
|
*
|
|
602
607
|
* The account deletion ceremony is the reader: it must name each auxiliary
|
|
603
608
|
* Space it is about to destroy, and the log is the only durable record of
|
|
604
|
-
* the superseded ones. Each entry carries the annex DID and its
|
|
605
|
-
* the Space id, because an account that has migrated
|
|
606
|
-
* this deployment cannot address: deleting `spaceId` on the CURRENT
|
|
609
|
+
* the superseded ones. Each entry carries the annex DID and its base server URL beside
|
|
610
|
+
* the Space id, because an account that has migrated servers leaves entries
|
|
611
|
+
* this deployment cannot address: deleting `spaceId` on the CURRENT server
|
|
607
612
|
* would address a Space that is not the one the entry names, and a 404 there
|
|
608
613
|
* would otherwise read as a clean deletion. Such an entry is the caller's to
|
|
609
614
|
* report as a residue.
|
|
@@ -614,12 +619,15 @@ export function delegatedClientsPointer({ doc }) {
|
|
|
614
619
|
*
|
|
615
620
|
* An entry carrying no document state, and an endpoint that does not parse
|
|
616
621
|
* as a client-annex DID, are skipped rather than refused: the walk is an
|
|
617
|
-
* enumeration aid, and a caller cannot act on an id it could not read.
|
|
622
|
+
* enumeration aid, and a caller cannot act on an id it could not read. An
|
|
623
|
+
* annex DID whose location cannot be read back off it is refused instead,
|
|
624
|
+
* with the location reader's own error, since a deletion that skipped it
|
|
625
|
+
* would leave that Space standing unreported.
|
|
618
626
|
*
|
|
619
627
|
* @param options {object}
|
|
620
628
|
* @param options.log {DIDLog} the VERIFIED account log
|
|
621
|
-
* @returns {Array<{ did: string,
|
|
622
|
-
* Spaces, in log order
|
|
629
|
+
* @returns {Array<{ did: string, baseServerUrl: string, spaceId: string }>}
|
|
630
|
+
* the Spaces, in log order, each with the base server URL its DID locates
|
|
623
631
|
*/
|
|
624
632
|
export function delegatedClientsSpaceHistory({ log }) {
|
|
625
633
|
const spaces = [];
|
|
@@ -634,7 +642,8 @@ export function delegatedClientsSpaceHistory({ log }) {
|
|
|
634
642
|
if (spaces.some(space => space.spaceId === parts.spaceId)) {
|
|
635
643
|
continue;
|
|
636
644
|
}
|
|
637
|
-
|
|
645
|
+
const { baseServerUrl } = didWebvhLogLocation({ did: pointed });
|
|
646
|
+
spaces.push({ did: pointed, baseServerUrl, spaceId: parts.spaceId });
|
|
638
647
|
}
|
|
639
648
|
return spaces;
|
|
640
649
|
}
|
|
@@ -740,18 +749,17 @@ export const DELEGATED_CLIENTS_DELEGATION_TTL_MS = STANDING_ZCAP_TTL_MS;
|
|
|
740
749
|
* @param options {object}
|
|
741
750
|
* @param options.zcapClient {ZcapClient} the delegating signer (an
|
|
742
751
|
* enrolled client's promoted signer, or the account ladder VM)
|
|
743
|
-
* @param options.
|
|
744
|
-
* server (the account pointer's host)
|
|
752
|
+
* @param options.baseServerUrl {string} the server's base server URL
|
|
745
753
|
* @param options.clientAnnexSpaceId {string} the auxiliary annex
|
|
746
754
|
* Space's id
|
|
747
755
|
* @param options.controller {string} the credential-derived signing DID
|
|
748
756
|
* @param [options.now] {number} epoch milliseconds, for tests
|
|
749
757
|
* @returns {Promise<IZcap>}
|
|
750
758
|
*/
|
|
751
|
-
export async function mintDelegatedClientsDelegation({ zcapClient,
|
|
752
|
-
const spaceUrl =
|
|
753
|
-
|
|
754
|
-
|
|
759
|
+
export async function mintDelegatedClientsDelegation({ zcapClient, baseServerUrl, clientAnnexSpaceId, controller, now = Date.now() }) {
|
|
760
|
+
const spaceUrl = spaceUrlById({
|
|
761
|
+
baseServerUrl,
|
|
762
|
+
spaceId: clientAnnexSpaceId
|
|
755
763
|
});
|
|
756
764
|
return (await zcapClient.delegate({
|
|
757
765
|
capability: rootCapabilityId(spaceUrl),
|
|
@@ -774,11 +782,10 @@ export async function mintDelegatedClientsDelegation({ zcapClient, wasServerUrl,
|
|
|
774
782
|
* @param options.doc {object} the locally verified account document
|
|
775
783
|
* @param options.zcapClient {ZcapClient} the acting client's promoted
|
|
776
784
|
* signer, which mints the fresh delegations
|
|
777
|
-
* @param options.
|
|
778
|
-
* server (the account pointer's host)
|
|
785
|
+
* @param options.baseServerUrl {string} the server's base server URL
|
|
779
786
|
* @returns {Function} `({ controller }) => Promise<IZcap | undefined>`
|
|
780
787
|
*/
|
|
781
|
-
export function delegatedClientsDelegationMinter({ doc, zcapClient,
|
|
788
|
+
export function delegatedClientsDelegationMinter({ doc, zcapClient, baseServerUrl }) {
|
|
782
789
|
return async ({ controller }) => {
|
|
783
790
|
const clientAnnexDid = delegatedClientsPointer({
|
|
784
791
|
doc: doc
|
|
@@ -795,7 +802,7 @@ export function delegatedClientsDelegationMinter({ doc, zcapClient, wasServerUrl
|
|
|
795
802
|
}
|
|
796
803
|
return mintDelegatedClientsDelegation({
|
|
797
804
|
zcapClient,
|
|
798
|
-
|
|
805
|
+
baseServerUrl,
|
|
799
806
|
clientAnnexSpaceId,
|
|
800
807
|
controller
|
|
801
808
|
});
|
|
@@ -937,15 +944,15 @@ export const GENERATION_DELEGATION_TTL_MS = STANDING_ZCAP_TTL_MS;
|
|
|
937
944
|
* @param options {object}
|
|
938
945
|
* @param options.zcapClient {ZcapClient} the delegating signer (ladder VM
|
|
939
946
|
* or an enrolled client's promoted signer)
|
|
940
|
-
* @param options.
|
|
947
|
+
* @param options.baseServerUrl {string} the ACCOUNT Space's storage server
|
|
941
948
|
* @param options.spaceId {string} the ACCOUNT Space's id
|
|
942
949
|
* @param options.clientAnnexDid {string} the generation's annex DID
|
|
943
950
|
* @param [options.now] {number} epoch milliseconds, for tests
|
|
944
951
|
* @returns {Promise<IZcap>}
|
|
945
952
|
*/
|
|
946
|
-
export async function mintGenerationDelegation({ zcapClient,
|
|
953
|
+
export async function mintGenerationDelegation({ zcapClient, baseServerUrl, spaceId, clientAnnexDid, now = Date.now() }) {
|
|
947
954
|
clientAnnexDidParts({ did: clientAnnexDid });
|
|
948
|
-
const spaceUrl =
|
|
955
|
+
const spaceUrl = spaceUrlById({ baseServerUrl, spaceId });
|
|
949
956
|
return (await zcapClient.delegate({
|
|
950
957
|
capability: rootCapabilityId(spaceUrl),
|
|
951
958
|
// Subtree marker: pending the profile change; flip this target to `${spaceUrl}*` when it ships.
|
|
@@ -1017,6 +1024,187 @@ export function embeddedGenerationDelegation({ doc }) {
|
|
|
1017
1024
|
endpoint: 'map'
|
|
1018
1025
|
});
|
|
1019
1026
|
}
|
|
1027
|
+
/**
|
|
1028
|
+
* The type IRI of the annex document's replica pointer entries: one entry per
|
|
1029
|
+
* replica server the account registers, each naming that server's DID. The
|
|
1030
|
+
* term is the PWS companion spec's, since replication is its domain.
|
|
1031
|
+
* Wire-level and permanent (app-connect-spec decision 0001): the source
|
|
1032
|
+
* server gates a ladder-signed pull on it, and readers dispatch on this IRI
|
|
1033
|
+
* rather than on the entry's fragment id.
|
|
1034
|
+
*/
|
|
1035
|
+
export const REPLICA_SERVER_SERVICE_TYPE = 'https://w3id.org/pws#ReplicaServer';
|
|
1036
|
+
/**
|
|
1037
|
+
* The Space id a replica server publishes its own did:webvh log under.
|
|
1038
|
+
*/
|
|
1039
|
+
const REPLICA_SERVER_SPACE_ID = 'server';
|
|
1040
|
+
/**
|
|
1041
|
+
* Refuses, with a `TypeError`, a replica server DID that is not a did:webvh
|
|
1042
|
+
* whose path is `space:server:id` (app-connect-spec decision 0003, predicate
|
|
1043
|
+
* 6: the source server checks the grantee's shape beside the pointer). A
|
|
1044
|
+
* malformed value would land permanently in a hash-chained annex entry the
|
|
1045
|
+
* server refuses anyway, so the wallet refuses it before minting the entry.
|
|
1046
|
+
*
|
|
1047
|
+
* @param options {object}
|
|
1048
|
+
* @param options.serverDid {string}
|
|
1049
|
+
*/
|
|
1050
|
+
export function assertReplicaServerDid({ serverDid }) {
|
|
1051
|
+
let location;
|
|
1052
|
+
try {
|
|
1053
|
+
location = didWebvhLogLocation({ did: serverDid });
|
|
1054
|
+
}
|
|
1055
|
+
catch {
|
|
1056
|
+
location = undefined;
|
|
1057
|
+
}
|
|
1058
|
+
if (location === undefined ||
|
|
1059
|
+
location.spaceId !== REPLICA_SERVER_SPACE_ID ||
|
|
1060
|
+
location.collectionId !== ID_COLLECTION.id) {
|
|
1061
|
+
throw new TypeError('A replica server DID is a did:webvh whose path is ' +
|
|
1062
|
+
`space:${REPLICA_SERVER_SPACE_ID}:${ID_COLLECTION.id}; got ` +
|
|
1063
|
+
`"${serverDid}".`);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* The fragment id of a replica pointer entry: `replica-` followed by the
|
|
1068
|
+
* SHA-256 multihash of the replica server's DID string (its UTF-8 bytes),
|
|
1069
|
+
* base64url with no padding. Derived rather than random, so one server's
|
|
1070
|
+
* entry has the same id on every restate. Wire-level and permanent; readers
|
|
1071
|
+
* still dispatch on {@link REPLICA_SERVER_SERVICE_TYPE}.
|
|
1072
|
+
*
|
|
1073
|
+
* @param options {object}
|
|
1074
|
+
* @param options.serverDid {string} the replica server's DID
|
|
1075
|
+
* @returns {string} the fragment, without the `#`
|
|
1076
|
+
*/
|
|
1077
|
+
export function replicaServerServiceFragment({ serverDid }) {
|
|
1078
|
+
const digest = sha256(new TextEncoder().encode(serverDid));
|
|
1079
|
+
const multihash = createMultihash(digest, MultihashAlgorithm.SHA2_256);
|
|
1080
|
+
return `replica-${base64urlnopad.encode(multihash)}`;
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Builds a replica pointer entry for an annex document. The
|
|
1084
|
+
* `serviceEndpoint` is the replica server's bare DID STRING, and the entry
|
|
1085
|
+
* carries nothing beside it. Refuses a malformed `serverDid`
|
|
1086
|
+
* ({@link assertReplicaServerDid}).
|
|
1087
|
+
*
|
|
1088
|
+
* @param options {object}
|
|
1089
|
+
* @param options.clientAnnexDid {string} the generation's annex DID
|
|
1090
|
+
* @param options.serverDid {string} the replica server's DID
|
|
1091
|
+
* @returns {ServiceEndpoint}
|
|
1092
|
+
*/
|
|
1093
|
+
export function replicaServerServiceEntry({ clientAnnexDid, serverDid }) {
|
|
1094
|
+
assertReplicaServerDid({ serverDid });
|
|
1095
|
+
return {
|
|
1096
|
+
id: `${clientAnnexDid}#${replicaServerServiceFragment({ serverDid })}`,
|
|
1097
|
+
type: REPLICA_SERVER_SERVICE_TYPE,
|
|
1098
|
+
serviceEndpoint: serverDid
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* The replica servers an annex document points at: the `serviceEndpoint` of
|
|
1103
|
+
* every entry whose `type` names (or includes)
|
|
1104
|
+
* {@link REPLICA_SERVER_SERVICE_TYPE}, in document order, each DID once.
|
|
1105
|
+
* Only a bare DID-string endpoint counts, the same predicate the server's
|
|
1106
|
+
* replica-pointer clause evaluates, so wallet and server read the same
|
|
1107
|
+
* pointer set off one document.
|
|
1108
|
+
*
|
|
1109
|
+
* @param options {object}
|
|
1110
|
+
* @param options.doc {DIDDoc} the resolved (and verified) annex document
|
|
1111
|
+
* @returns {string[]}
|
|
1112
|
+
*/
|
|
1113
|
+
export function replicaServerPointers({ doc }) {
|
|
1114
|
+
return [
|
|
1115
|
+
...new Set(serviceEntriesWith({
|
|
1116
|
+
doc,
|
|
1117
|
+
type: REPLICA_SERVER_SERVICE_TYPE,
|
|
1118
|
+
endpoint: 'string'
|
|
1119
|
+
}).map(entry => entry.serviceEndpoint))
|
|
1120
|
+
];
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Whether an annex document carries a replica pointer at `serverDid`: a
|
|
1124
|
+
* replica pointer entry whose endpoint is the server's DID. The match is by
|
|
1125
|
+
* endpoint alone, the one the server's replica-pointer clause makes; an
|
|
1126
|
+
* entry's fragment id is a selector and names no server.
|
|
1127
|
+
*
|
|
1128
|
+
* @param options {object}
|
|
1129
|
+
* @param options.doc {DIDDoc} the resolved (and verified) annex document
|
|
1130
|
+
* @param options.serverDid {string} the replica server's DID
|
|
1131
|
+
* @returns {boolean}
|
|
1132
|
+
*/
|
|
1133
|
+
export function replicaServerPointerStands({ doc, serverDid }) {
|
|
1134
|
+
return replicaServerPointers({ doc }).includes(serverDid);
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* The replica servers of `serverDids`, each once, that an annex document
|
|
1138
|
+
* carries no pointer at ({@link replicaServerPointerStands}). The set the
|
|
1139
|
+
* installing entry adds, and what a caller whose install pass published
|
|
1140
|
+
* nothing reads off the head that pass stood on.
|
|
1141
|
+
*
|
|
1142
|
+
* @param options {object}
|
|
1143
|
+
* @param options.doc {DIDDoc}
|
|
1144
|
+
* @param options.serverDids {string[]}
|
|
1145
|
+
* @returns {string[]}
|
|
1146
|
+
*/
|
|
1147
|
+
export function replicaServersMissing({ doc, serverDids }) {
|
|
1148
|
+
const standing = new Set(replicaServerPointers({ doc }));
|
|
1149
|
+
return [...new Set(serverDids)].filter(serverDid => !standing.has(serverDid));
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* An {@link InstalledServices} hook that points the generation at
|
|
1153
|
+
* `serverDids`: a replica pointer entry for each one the document does not
|
|
1154
|
+
* already carry ({@link replicaServerPointerStands}). Every standing entry,
|
|
1155
|
+
* replica pointers among them, is carried through untouched: the hook only
|
|
1156
|
+
* adds, since dropping a pointer is the replica pass's decision, made against
|
|
1157
|
+
* the connections directory.
|
|
1158
|
+
*
|
|
1159
|
+
* The hook refuses, before any entry is minted, a malformed server DID
|
|
1160
|
+
* ({@link assertReplicaServerDid}) with a `TypeError`, standing ones
|
|
1161
|
+
* included, and with an `Error` a document that already carries a service
|
|
1162
|
+
* entry under the id an added pointer would take (one of another type,
|
|
1163
|
+
* another endpoint, or an endpoint that is not a DID string): a second entry
|
|
1164
|
+
* under one id is a document no resolver admits, and the entry standing
|
|
1165
|
+
* there was not written by this hook.
|
|
1166
|
+
*
|
|
1167
|
+
* @param options {object}
|
|
1168
|
+
* @param options.serverDids {string[]} the replica servers to point at
|
|
1169
|
+
* @returns {InstalledServices}
|
|
1170
|
+
*/
|
|
1171
|
+
export function replicaPointerInstaller({ serverDids }) {
|
|
1172
|
+
return ({ doc, clientAnnexDid }) => {
|
|
1173
|
+
for (const serverDid of serverDids) {
|
|
1174
|
+
assertReplicaServerDid({ serverDid });
|
|
1175
|
+
}
|
|
1176
|
+
const added = replicaServersMissing({ doc, serverDids }).map(serverDid => replicaServerServiceEntry({ clientAnnexDid, serverDid }));
|
|
1177
|
+
const taken = new Set((doc.service ?? []).map(entry => entry.id));
|
|
1178
|
+
for (const entry of added) {
|
|
1179
|
+
if (taken.has(entry.id)) {
|
|
1180
|
+
throw new Error(`client annex: the document already carries a service entry at ` +
|
|
1181
|
+
`"${entry.id}" that is not the replica pointer at ` +
|
|
1182
|
+
`"${entry.serviceEndpoint}"; nothing was written.`);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return added;
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* The service list the entry installing a generation delegation publishes:
|
|
1190
|
+
* the delegation entry ({@link withGenerationDelegationEntry}) followed by
|
|
1191
|
+
* whatever the caller's {@link InstalledServices} hook adds. The one
|
|
1192
|
+
* composition both installing writers run, so an install-time entry can
|
|
1193
|
+
* never land in an entry other than the delegation's.
|
|
1194
|
+
*
|
|
1195
|
+
* @param options {object}
|
|
1196
|
+
* @param options.doc {DIDDoc} the annex document as published
|
|
1197
|
+
* @param options.clientAnnexDid {string}
|
|
1198
|
+
* @param options.delegation {IZcap}
|
|
1199
|
+
* @param [options.installedServices] {InstalledServices}
|
|
1200
|
+
* @returns {ServiceEndpoint[]}
|
|
1201
|
+
*/
|
|
1202
|
+
function withInstalledEntries({ doc, clientAnnexDid, delegation, installedServices }) {
|
|
1203
|
+
return [
|
|
1204
|
+
...withGenerationDelegationEntry({ doc, clientAnnexDid, delegation }),
|
|
1205
|
+
...(installedServices?.({ doc, clientAnnexDid }) ?? [])
|
|
1206
|
+
];
|
|
1207
|
+
}
|
|
1020
1208
|
/**
|
|
1021
1209
|
* Every generation delegation a generation's log has ever embedded, in log
|
|
1022
1210
|
* order and deduplicated by zcap id -- the annex-log HISTORY WALK the
|
|
@@ -1392,9 +1580,13 @@ export async function readClientAnnexLogOrAbsent({ store, expectedDid }) {
|
|
|
1392
1580
|
* delegation this entry installs when it publishes the generation's FIRST
|
|
1393
1581
|
* transient verification method (and the document carries no delegation
|
|
1394
1582
|
* entry yet). Never invoked otherwise: the delegation is installed with
|
|
1395
|
-
* the first transient VM or by the GC ceremony's own install stage,
|
|
1396
|
-
* by genesis (a genesis-embedded signed zcap can never verify -- its
|
|
1583
|
+
* the first transient VM or by the GC ceremony's own install stage, and
|
|
1584
|
+
* not by genesis (a genesis-embedded signed zcap can never verify -- its
|
|
1397
1585
|
* `controller` embeds the SCID the genesis hash derives from)
|
|
1586
|
+
* @param [options.installedServices] {InstalledServices} the service
|
|
1587
|
+
* entries the installing entry writes beside the delegation (the replica
|
|
1588
|
+
* pointers, {@link replicaPointerInstaller}). Invoked only by the entry
|
|
1589
|
+
* that installs the delegation; ignored on every other entry
|
|
1398
1590
|
* @param [options.expectedDid] {string} the annex DID the log must
|
|
1399
1591
|
* resolve to, from the account document's pointer. The read and the publish
|
|
1400
1592
|
* run under the store's own chain-head pin
|
|
@@ -1422,7 +1614,7 @@ export async function enrollClientAnnexTransientClient({ published: threadedHead
|
|
|
1422
1614
|
* @param options {object} see {@link enrollClientAnnexTransientClient}
|
|
1423
1615
|
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>}
|
|
1424
1616
|
*/
|
|
1425
|
-
async function enrollClientAnnexTransientClientOnce({ store, ladderSeed, transientKeyMultibase, services, mintGenerationDelegation: mintDelegation, expectedDid, published: alreadyRead }) {
|
|
1617
|
+
async function enrollClientAnnexTransientClientOnce({ store, ladderSeed, transientKeyMultibase, services, mintGenerationDelegation: mintDelegation, installedServices, expectedDid, published: alreadyRead }) {
|
|
1426
1618
|
const published = alreadyRead !== undefined
|
|
1427
1619
|
? assertPublishedLogDid({
|
|
1428
1620
|
published: alreadyRead,
|
|
@@ -1456,16 +1648,18 @@ async function enrollClientAnnexTransientClientOnce({ store, ladderSeed, transie
|
|
|
1456
1648
|
// The generation delegation installs with the first transient VM (never at
|
|
1457
1649
|
// genesis): a delegation-less document about to receive its first method
|
|
1458
1650
|
// gets the entry minted and appended here, so a generation with no visits
|
|
1459
|
-
// never carries a delegation and stays authorization-inert.
|
|
1651
|
+
// never carries a delegation and stays authorization-inert. The replica
|
|
1652
|
+
// pointers ride the same entry.
|
|
1460
1653
|
if (services === undefined &&
|
|
1461
1654
|
mintDelegation !== undefined &&
|
|
1462
1655
|
existingMethods.length === 0 &&
|
|
1463
1656
|
embeddedGenerationDelegation({ doc }) === undefined) {
|
|
1464
1657
|
const delegation = await mintDelegation({ clientAnnexDid: did });
|
|
1465
|
-
services =
|
|
1658
|
+
services = withInstalledEntries({
|
|
1466
1659
|
doc,
|
|
1467
1660
|
clientAnnexDid: did,
|
|
1468
|
-
delegation
|
|
1661
|
+
delegation,
|
|
1662
|
+
...(installedServices !== undefined ? { installedServices } : {})
|
|
1469
1663
|
});
|
|
1470
1664
|
}
|
|
1471
1665
|
const transientMethod = {
|
|
@@ -1711,6 +1905,9 @@ export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAn
|
|
|
1711
1905
|
* {@link enrollClientAnnexTransientClient}). The closure receives whichever
|
|
1712
1906
|
* annex DID the round enrolls into, so a GC-race re-enroll mints for
|
|
1713
1907
|
* the fresh generation
|
|
1908
|
+
* @param [options.installedServices] {InstalledServices} forwarded to
|
|
1909
|
+
* the enrollment entry: what the installing entry writes beside the
|
|
1910
|
+
* delegation
|
|
1714
1911
|
* @param [options.maxRounds] {number} how many pointer moves to chase
|
|
1715
1912
|
* before giving up (a GC pass is quarterly, so more than one mid-ceremony
|
|
1716
1913
|
* move means something else is wrong)
|
|
@@ -1722,7 +1919,7 @@ export async function setDelegatedClientsPointerOnce({ idStore, signer, clientAn
|
|
|
1722
1919
|
* every later round does
|
|
1723
1920
|
* @returns {Promise<{ clientAnnexDid: string, doc: DIDDoc, log: DIDLog }>}
|
|
1724
1921
|
*/
|
|
1725
|
-
export async function enrollTransientClient({ readAccountDocument, storeForGenerationId, ladderSeed, transientKeyMultibase, mintGenerationDelegation: mintDelegation, maxRounds = 3, published: threadedHead }) {
|
|
1922
|
+
export async function enrollTransientClient({ readAccountDocument, storeForGenerationId, ladderSeed, transientKeyMultibase, mintGenerationDelegation: mintDelegation, installedServices, maxRounds = 3, published: threadedHead }) {
|
|
1726
1923
|
let accountDoc = await readAccountDocument();
|
|
1727
1924
|
for (let round = 0; round < maxRounds; round++) {
|
|
1728
1925
|
const clientAnnexDid = delegatedClientsPointer({ doc: accountDoc });
|
|
@@ -1745,7 +1942,8 @@ export async function enrollTransientClient({ readAccountDocument, storeForGener
|
|
|
1745
1942
|
...(head !== undefined ? { published: head } : {}),
|
|
1746
1943
|
...(mintDelegation !== undefined
|
|
1747
1944
|
? { mintGenerationDelegation: mintDelegation }
|
|
1748
|
-
: {})
|
|
1945
|
+
: {}),
|
|
1946
|
+
...(installedServices !== undefined ? { installedServices } : {})
|
|
1749
1947
|
});
|
|
1750
1948
|
// The GC-race re-read: an unchanged pointer means the enrollment stands
|
|
1751
1949
|
// in the pointed generation; a moved one means a concurrent GC abandoned
|
|
@@ -1781,7 +1979,7 @@ export async function enrollTransientClient({ readAccountDocument, storeForGener
|
|
|
1781
1979
|
* @param options {object}
|
|
1782
1980
|
* @param options.was {WasClient} the storage client the mint and the
|
|
1783
1981
|
* install write through
|
|
1784
|
-
* @param options.
|
|
1982
|
+
* @param options.baseServerUrl {string}
|
|
1785
1983
|
* @param options.spaceId {string} the auxiliary annex Space's id
|
|
1786
1984
|
* @param options.controller {string} the Space's creation controller (see
|
|
1787
1985
|
* {@link mintCredentialClientAnnexGeneration})
|
|
@@ -1799,6 +1997,10 @@ export async function enrollTransientClient({ readAccountDocument, storeForGener
|
|
|
1799
1997
|
* generation's standing set, restated in the fresh genesis (see
|
|
1800
1998
|
* {@link mintCredentialClientAnnexGeneration}); absent on a first
|
|
1801
1999
|
* generation and wherever no superseded log was readable
|
|
2000
|
+
* @param [options.installedServices] {InstalledServices} what the
|
|
2001
|
+
* install entry writes beside the delegation, the restated replica pointers
|
|
2002
|
+
* ({@link replicaPointerInstaller}); absent on a first generation and
|
|
2003
|
+
* wherever the caller holds no list
|
|
1802
2004
|
* @param [options.beforePointerEntry] {Function}
|
|
1803
2005
|
* `({ minted }) => Promise<void>` -- runs after the install and before the
|
|
1804
2006
|
* pointer entry, with the mint's published head (its `spaceDescription`
|
|
@@ -1807,10 +2009,10 @@ export async function enrollTransientClient({ readAccountDocument, storeForGener
|
|
|
1807
2009
|
* @returns {Promise<{ clientAnnexDid: string, generationDelegation: IZcap,
|
|
1808
2010
|
* pointed: T }>}
|
|
1809
2011
|
*/
|
|
1810
|
-
export async function mintPointedClientAnnexGeneration({ was,
|
|
2012
|
+
export async function mintPointedClientAnnexGeneration({ was, baseServerUrl, spaceId, controller, ladderSeed, mintGenerationDelegation, point, pinStore, capability, standingRungHashes, installedServices, beforePointerEntry, now }) {
|
|
1811
2013
|
const minted = await mintCredentialClientAnnexGeneration({
|
|
1812
2014
|
was,
|
|
1813
|
-
|
|
2015
|
+
baseServerUrl,
|
|
1814
2016
|
spaceId,
|
|
1815
2017
|
controller,
|
|
1816
2018
|
ladderSeed,
|
|
@@ -1828,6 +2030,7 @@ export async function mintPointedClientAnnexGeneration({ was, wasServerUrl, spac
|
|
|
1828
2030
|
}),
|
|
1829
2031
|
ladderSeed,
|
|
1830
2032
|
mintGenerationDelegation,
|
|
2033
|
+
...(installedServices !== undefined ? { installedServices } : {}),
|
|
1831
2034
|
expectedDid: minted.did,
|
|
1832
2035
|
...(minted.etag !== undefined ? { published: minted } : {}),
|
|
1833
2036
|
...(now !== undefined ? { now } : {})
|
|
@@ -1899,6 +2102,14 @@ export async function mintPointedClientAnnexGeneration({ was, wasServerUrl, spac
|
|
|
1899
2102
|
* its own ladder VM (whose delegations it revokes server-side in the next
|
|
1900
2103
|
* breath, a state no client-side predicate can read) and the client its
|
|
1901
2104
|
* removal entry has yet to strike
|
|
2105
|
+
* @param [options.installedServices] {InstalledServices} the service
|
|
2106
|
+
* entries the installing entry writes beside the delegation, the replica
|
|
2107
|
+
* pointers ({@link replicaPointerInstaller}): a fresh generation's install
|
|
2108
|
+
* stage writes them beside the delegation, and a renewal on a live
|
|
2109
|
+
* generation adds what the document lacks and keeps every standing entry
|
|
2110
|
+
* through the prior-state clone. A pass that publishes nothing never
|
|
2111
|
+
* invokes the hook; the caller reads what the head still lacks off the
|
|
2112
|
+
* `published` it hands back ({@link replicaServersMissing})
|
|
1902
2113
|
* @param [options.now] {number} epoch milliseconds, for tests
|
|
1903
2114
|
* @param [options.published] {PublishedWebvhLog} a head the caller already
|
|
1904
2115
|
* read and verified under this same pin slot, so the stage builds on it
|
|
@@ -1933,7 +2144,7 @@ export async function ensureGenerationDelegationCurrent({ published: threadedHea
|
|
|
1933
2144
|
* @returns {Promise<{ delegation: IZcap, renewed: boolean,
|
|
1934
2145
|
* published?: PublishedWebvhLog }>}
|
|
1935
2146
|
*/
|
|
1936
|
-
async function ensureGenerationDelegationCurrentOnce({ store, ladderSeed, mintGenerationDelegation: mintDelegation, expectedDid, accountDoc, retiringKeyMultibases = [], now, published: alreadyRead }) {
|
|
2147
|
+
async function ensureGenerationDelegationCurrentOnce({ store, ladderSeed, mintGenerationDelegation: mintDelegation, expectedDid, accountDoc, retiringKeyMultibases = [], installedServices, now, published: alreadyRead }) {
|
|
1937
2148
|
const published = alreadyRead !== undefined
|
|
1938
2149
|
? assertPublishedLogDid({
|
|
1939
2150
|
published: alreadyRead,
|
|
@@ -1974,13 +2185,15 @@ async function ensureGenerationDelegationCurrentOnce({ store, ladderSeed, mintGe
|
|
|
1974
2185
|
// The writer's rung-0 key reveals at its first annex write, exactly
|
|
1975
2186
|
// as the enrollment entry does; `nextKeyHashes` is re-stated verbatim,
|
|
1976
2187
|
// never inherited. Verification methods, relationship arrays, and every
|
|
1977
|
-
// other service entry
|
|
2188
|
+
// other service entry (the standing replica pointers among them) ride
|
|
2189
|
+
// the library's prior-state clone untouched.
|
|
1978
2190
|
updateKeys: [...new Set([...published.updateKeys, rung.keyMultibase])],
|
|
1979
2191
|
nextKeyHashes: [...published.nextKeyHashes],
|
|
1980
|
-
services:
|
|
2192
|
+
services: withInstalledEntries({
|
|
1981
2193
|
doc,
|
|
1982
2194
|
clientAnnexDid: did,
|
|
1983
|
-
delegation: fresh
|
|
2195
|
+
delegation: fresh,
|
|
2196
|
+
...(installedServices !== undefined ? { installedServices } : {})
|
|
1984
2197
|
})
|
|
1985
2198
|
});
|
|
1986
2199
|
// The publish advances the store's chain-head pin to what it just wrote, so
|