@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.
- package/README.md +41 -16
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts +46 -26
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts.map +1 -1
- package/dist/clientAnnex/credentialAnchoredGenesis.js +91 -39
- package/dist/clientAnnex/credentialAnchoredGenesis.js.map +1 -1
- package/dist/clientAnnex/establish.d.ts +55 -34
- package/dist/clientAnnex/establish.d.ts.map +1 -1
- package/dist/clientAnnex/establish.js +102 -56
- package/dist/clientAnnex/establish.js.map +1 -1
- package/dist/clientAnnex/forget.d.ts +16 -2
- package/dist/clientAnnex/forget.d.ts.map +1 -1
- package/dist/clientAnnex/forget.js +11 -9
- package/dist/clientAnnex/forget.js.map +1 -1
- package/dist/clientAnnex/forgetLast.d.ts +62 -18
- package/dist/clientAnnex/forgetLast.d.ts.map +1 -1
- package/dist/clientAnnex/forgetLast.js +92 -26
- package/dist/clientAnnex/forgetLast.js.map +1 -1
- package/dist/clientAnnex/gc.d.ts +3 -2
- package/dist/clientAnnex/gc.d.ts.map +1 -1
- package/dist/clientAnnex/gc.js +7 -7
- package/dist/clientAnnex/gc.js.map +1 -1
- package/dist/clientAnnex/heal.d.ts +38 -5
- package/dist/clientAnnex/heal.d.ts.map +1 -1
- package/dist/clientAnnex/heal.js +346 -236
- package/dist/clientAnnex/heal.js.map +1 -1
- package/dist/clientAnnex/index.d.ts +21 -5
- package/dist/clientAnnex/index.d.ts.map +1 -1
- package/dist/clientAnnex/index.js +24 -5
- package/dist/clientAnnex/index.js.map +1 -1
- package/dist/clientAnnex/ladder.d.ts +58 -0
- package/dist/clientAnnex/ladder.d.ts.map +1 -1
- package/dist/clientAnnex/ladder.js +222 -33
- package/dist/clientAnnex/ladder.js.map +1 -1
- package/dist/clientAnnex/ladderAnchored.d.ts +148 -22
- package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -1
- package/dist/clientAnnex/ladderAnchored.js +391 -346
- package/dist/clientAnnex/ladderAnchored.js.map +1 -1
- package/dist/clientAnnex/log.d.ts +162 -43
- package/dist/clientAnnex/log.d.ts.map +1 -1
- package/dist/clientAnnex/log.js +423 -192
- package/dist/clientAnnex/log.js.map +1 -1
- package/dist/clientAnnex/mend.d.ts +12 -6
- package/dist/clientAnnex/mend.d.ts.map +1 -1
- package/dist/clientAnnex/mend.js +26 -12
- package/dist/clientAnnex/mend.js.map +1 -1
- package/dist/clientAnnex/recoveryLadderAnchored.d.ts +6 -4
- package/dist/clientAnnex/recoveryLadderAnchored.d.ts.map +1 -1
- package/dist/clientAnnex/recoveryLadderAnchored.js +56 -35
- package/dist/clientAnnex/recoveryLadderAnchored.js.map +1 -1
- package/dist/clientAnnex/spaceCapability.d.ts +123 -0
- package/dist/clientAnnex/spaceCapability.d.ts.map +1 -0
- package/dist/clientAnnex/spaceCapability.js +152 -0
- package/dist/clientAnnex/spaceCapability.js.map +1 -0
- package/dist/clientAnnex/stages.d.ts +63 -0
- package/dist/clientAnnex/stages.d.ts.map +1 -0
- package/dist/clientAnnex/stages.js +64 -0
- package/dist/clientAnnex/stages.js.map +1 -0
- package/dist/clientAnnex/zcap.d.ts +1 -1
- package/dist/clientAnnex/zcap.d.ts.map +1 -1
- package/dist/clientAnnex/zcap.js +42 -35
- package/dist/clientAnnex/zcap.js.map +1 -1
- package/dist/clients/policy.d.ts +15 -1
- package/dist/clients/policy.d.ts.map +1 -1
- package/dist/clients/policy.js +12 -6
- package/dist/clients/policy.js.map +1 -1
- package/dist/clients/revocation.d.ts +18 -10
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +13 -5
- package/dist/clients/revocation.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +10 -2
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +41 -24
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/descriptors/acquire.d.ts.map +1 -1
- package/dist/descriptors/acquire.js +6 -23
- package/dist/descriptors/acquire.js.map +1 -1
- package/dist/descriptors/cipher.d.ts.map +1 -1
- package/dist/descriptors/cipher.js +5 -0
- package/dist/descriptors/cipher.js.map +1 -1
- package/dist/descriptors/errors.d.ts +43 -0
- package/dist/descriptors/errors.d.ts.map +1 -0
- package/dist/descriptors/errors.js +45 -0
- package/dist/descriptors/errors.js.map +1 -0
- package/dist/descriptors/index.d.ts +5 -0
- package/dist/descriptors/index.d.ts.map +1 -1
- package/dist/descriptors/index.js +5 -0
- package/dist/descriptors/index.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts +37 -10
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +52 -15
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/genesis/accountGenesis.d.ts +42 -11
- package/dist/genesis/accountGenesis.d.ts.map +1 -1
- package/dist/genesis/accountGenesis.js +80 -22
- package/dist/genesis/accountGenesis.js.map +1 -1
- package/dist/genesis/index.d.ts +3 -1
- package/dist/genesis/index.d.ts.map +1 -1
- package/dist/genesis/index.js +3 -1
- package/dist/genesis/index.js.map +1 -1
- package/dist/identity/agents.d.ts +17 -1
- package/dist/identity/agents.d.ts.map +1 -1
- package/dist/identity/agents.js +23 -7
- package/dist/identity/agents.js.map +1 -1
- package/dist/identity/index.d.ts +3 -1
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +3 -1
- package/dist/identity/index.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/keyring/index.d.ts +2 -1
- package/dist/keyring/index.d.ts.map +1 -1
- package/dist/keyring/index.js +2 -1
- package/dist/keyring/index.js.map +1 -1
- package/dist/keyring/record.d.ts.map +1 -1
- package/dist/keyring/record.js +3 -6
- package/dist/keyring/record.js.map +1 -1
- package/dist/keyring/unlockSpace.d.ts +14 -5
- package/dist/keyring/unlockSpace.d.ts.map +1 -1
- package/dist/keyring/unlockSpace.js +31 -36
- package/dist/keyring/unlockSpace.js.map +1 -1
- package/dist/keys/index.d.ts +10 -6
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +9 -5
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterLogStore.d.ts +12 -11
- package/dist/keys/rosterLogStore.d.ts.map +1 -1
- package/dist/keys/rosterLogStore.js +15 -13
- package/dist/keys/rosterLogStore.js.map +1 -1
- package/dist/keys/rosterStore.d.ts +3 -6
- package/dist/keys/rosterStore.d.ts.map +1 -1
- package/dist/keys/rosterStore.js +10 -9
- package/dist/keys/rosterStore.js.map +1 -1
- package/dist/keys/spaceEpochs.d.ts.map +1 -1
- package/dist/keys/spaceEpochs.js +2 -3
- package/dist/keys/spaceEpochs.js.map +1 -1
- package/dist/keys/userKeyRoster.d.ts +57 -7
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +222 -17
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/keys/userKeyRosterCascade.d.ts +7 -6
- package/dist/keys/userKeyRosterCascade.d.ts.map +1 -1
- package/dist/keys/userKeyRosterCascade.js +7 -6
- package/dist/keys/userKeyRosterCascade.js.map +1 -1
- package/dist/keys/wasLabelsStore.d.ts +9 -2
- package/dist/keys/wasLabelsStore.d.ts.map +1 -1
- package/dist/keys/wasLabelsStore.js +14 -6
- package/dist/keys/wasLabelsStore.js.map +1 -1
- package/dist/log.d.ts +7 -2
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +6 -1
- package/dist/log.js.map +1 -1
- package/dist/recovery/index.d.ts +12 -8
- package/dist/recovery/index.d.ts.map +1 -1
- package/dist/recovery/index.js +11 -7
- package/dist/recovery/index.js.map +1 -1
- package/dist/recovery/recoveryCode.d.ts +27 -7
- package/dist/recovery/recoveryCode.d.ts.map +1 -1
- package/dist/recovery/recoveryCode.js +18 -6
- package/dist/recovery/recoveryCode.js.map +1 -1
- package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
- package/dist/recovery/recoveryDelegation.js +21 -34
- package/dist/recovery/recoveryDelegation.js.map +1 -1
- package/dist/recovery/recoveryWebvh.d.ts +75 -63
- package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
- package/dist/recovery/recoveryWebvh.js +127 -116
- package/dist/recovery/recoveryWebvh.js.map +1 -1
- package/dist/request/classify.d.ts +32 -8
- package/dist/request/classify.d.ts.map +1 -1
- package/dist/request/classify.js +39 -14
- package/dist/request/classify.js.map +1 -1
- package/dist/request/ephemeralExchange.d.ts +1 -6
- package/dist/request/ephemeralExchange.d.ts.map +1 -1
- package/dist/request/ephemeralExchange.js.map +1 -1
- package/dist/request/onboarding.d.ts.map +1 -1
- package/dist/request/onboarding.js +2 -2
- package/dist/request/onboarding.js.map +1 -1
- package/dist/request/parse.d.ts.map +1 -1
- package/dist/request/parse.js +2 -3
- package/dist/request/parse.js.map +1 -1
- package/dist/resourceLog/controller.d.ts +34 -12
- package/dist/resourceLog/controller.d.ts.map +1 -1
- package/dist/resourceLog/controller.js +79 -86
- package/dist/resourceLog/controller.js.map +1 -1
- package/dist/resourceLog/document.d.ts +182 -0
- package/dist/resourceLog/document.d.ts.map +1 -0
- package/dist/resourceLog/document.js +159 -0
- package/dist/resourceLog/document.js.map +1 -0
- package/dist/resourceLog/errors.d.ts +47 -8
- package/dist/resourceLog/errors.d.ts.map +1 -1
- package/dist/resourceLog/errors.js +54 -8
- package/dist/resourceLog/errors.js.map +1 -1
- package/dist/resourceLog/index.d.ts +7 -3
- package/dist/resourceLog/index.d.ts.map +1 -1
- package/dist/resourceLog/index.js +7 -3
- package/dist/resourceLog/index.js.map +1 -1
- package/dist/resourceLog/ladderRungs.d.ts +35 -0
- package/dist/resourceLog/ladderRungs.d.ts.map +1 -0
- package/dist/resourceLog/ladderRungs.js +352 -0
- package/dist/resourceLog/ladderRungs.js.map +1 -0
- package/dist/resourceLog/license.d.ts +42 -17
- package/dist/resourceLog/license.d.ts.map +1 -1
- package/dist/resourceLog/license.js +38 -24
- package/dist/resourceLog/license.js.map +1 -1
- package/dist/space/activity.d.ts +15 -15
- package/dist/space/activity.d.ts.map +1 -1
- package/dist/space/activity.js +15 -15
- package/dist/space/activity.js.map +1 -1
- package/dist/space/collections.d.ts +11 -0
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +13 -0
- package/dist/space/collections.js.map +1 -1
- package/dist/space/deleteSpace.d.ts +28 -0
- package/dist/space/deleteSpace.d.ts.map +1 -0
- package/dist/space/deleteSpace.js +44 -0
- package/dist/space/deleteSpace.js.map +1 -0
- package/dist/space/errors.d.ts.map +1 -1
- package/dist/space/errors.js +0 -1
- package/dist/space/errors.js.map +1 -1
- package/dist/space/index.d.ts +6 -0
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +6 -0
- package/dist/space/index.js.map +1 -1
- package/dist/space/plaintextCollection.d.ts +43 -0
- package/dist/space/plaintextCollection.d.ts.map +1 -0
- package/dist/space/plaintextCollection.js +17 -0
- package/dist/space/plaintextCollection.js.map +1 -0
- package/dist/stages.d.ts +23 -0
- package/dist/stages.d.ts.map +1 -0
- package/dist/stages.js +23 -0
- package/dist/stages.js.map +1 -0
- package/dist/sync/index.d.ts +7 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +7 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/push.js +4 -4
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/remint.js +2 -2
- package/dist/sync/remint.js.map +1 -1
- package/dist/sync/types.d.ts +41 -1
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/sync/types.js +47 -1
- package/dist/sync/types.js.map +1 -1
- package/dist/unlock/index.d.ts +5 -1
- package/dist/unlock/index.d.ts.map +1 -1
- package/dist/unlock/index.js +5 -1
- package/dist/unlock/index.js.map +1 -1
- package/dist/unlock/retire.d.ts +35 -7
- package/dist/unlock/retire.d.ts.map +1 -1
- package/dist/unlock/retire.js +52 -14
- package/dist/unlock/retire.js.map +1 -1
- package/dist/unlock/standingClient.d.ts.map +1 -1
- package/dist/unlock/standingClient.js +5 -1
- package/dist/unlock/standingClient.js.map +1 -1
- package/dist/unlock/standingWebvh.d.ts +217 -35
- package/dist/unlock/standingWebvh.d.ts.map +1 -1
- package/dist/unlock/standingWebvh.js +469 -210
- package/dist/unlock/standingWebvh.js.map +1 -1
- package/dist/webvh/accountEntry.d.ts +146 -0
- package/dist/webvh/accountEntry.d.ts.map +1 -0
- package/dist/webvh/accountEntry.js +239 -0
- package/dist/webvh/accountEntry.js.map +1 -0
- package/dist/webvh/didWeb.d.ts +12 -7
- package/dist/webvh/didWeb.d.ts.map +1 -1
- package/dist/webvh/didWeb.js +2 -2
- package/dist/webvh/didWeb.js.map +1 -1
- package/dist/webvh/didWebProjection.d.ts +164 -0
- package/dist/webvh/didWebProjection.d.ts.map +1 -0
- package/dist/webvh/didWebProjection.js +230 -0
- package/dist/webvh/didWebProjection.js.map +1 -0
- package/dist/webvh/didWebvh.d.ts +275 -136
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +307 -340
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/enrollClient.d.ts +65 -0
- package/dist/webvh/enrollClient.d.ts.map +1 -0
- package/dist/webvh/enrollClient.js +172 -0
- package/dist/webvh/enrollClient.js.map +1 -0
- package/dist/webvh/index.d.ts +37 -12
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +33 -10
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/listClients.d.ts +1 -35
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +2 -30
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts +41 -11
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +99 -48
- package/dist/webvh/revokeClient.js.map +1 -1
- package/dist/webvh/standingZcap.d.ts +61 -14
- package/dist/webvh/standingZcap.d.ts.map +1 -1
- package/dist/webvh/standingZcap.js +91 -0
- package/dist/webvh/standingZcap.js.map +1 -1
- package/dist/webvh/verifyLog.d.ts +59 -5
- package/dist/webvh/verifyLog.d.ts.map +1 -1
- package/dist/webvh/verifyLog.js +76 -11
- package/dist/webvh/verifyLog.js.map +1 -1
- package/dist/webvh/wasIdStore.d.ts +8 -8
- package/dist/webvh/wasIdStore.d.ts.map +1 -1
- package/dist/webvh/wasIdStore.js +39 -14
- package/dist/webvh/wasIdStore.js.map +1 -1
- package/dist/webvh/zcap.d.ts +14 -1
- package/dist/webvh/zcap.d.ts.map +1 -1
- package/dist/webvh/zcap.js +3 -27
- package/dist/webvh/zcap.js.map +1 -1
- package/package.json +2 -2
- package/dist/webvh/keyAgreement.d.ts +0 -97
- package/dist/webvh/keyAgreement.d.ts.map +0 -1
- package/dist/webvh/keyAgreement.js +0 -71
- package/dist/webvh/keyAgreement.js.map +0 -1
package/dist/clientAnnex/heal.js
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
import { WasClient } from '@interop/was-client';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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 {
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
|
259
|
+
const created = await ensureClientAnnexSpace({
|
|
226
260
|
was: bootstrapWas,
|
|
227
|
-
wasServerUrl,
|
|
228
261
|
spaceId: freshSpaceId,
|
|
229
|
-
controller: keyAgent.id
|
|
230
|
-
|
|
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:
|
|
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
|
-
...(
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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:
|
|
276
|
-
siblingReminted
|
|
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:
|
|
561
|
+
delegatedClients: usableSibling,
|
|
283
562
|
generationMinted: true,
|
|
284
|
-
spaceMinted
|
|
563
|
+
spaceMinted,
|
|
564
|
+
pointedSpaceMissing,
|
|
285
565
|
delegationRenewed: false,
|
|
286
|
-
siblingReminted
|
|
566
|
+
siblingReminted,
|
|
287
567
|
bridgeReminted,
|
|
288
568
|
...resealed
|
|
289
569
|
};
|
|
290
570
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
|
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
|
|
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
|
|
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,
|