@interop/wallet-core 0.62.0 → 0.66.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 +119 -35
- package/dist/clientAnnex/establish.d.ts.map +1 -1
- package/dist/clientAnnex/establish.js +227 -160
- package/dist/clientAnnex/establish.js.map +1 -1
- package/dist/clientAnnex/forget.d.ts +18 -8
- package/dist/clientAnnex/forget.d.ts.map +1 -1
- package/dist/clientAnnex/forget.js +37 -64
- package/dist/clientAnnex/forget.js.map +1 -1
- package/dist/clientAnnex/forgetLast.d.ts +85 -38
- package/dist/clientAnnex/forgetLast.d.ts.map +1 -1
- package/dist/clientAnnex/forgetLast.js +155 -98
- 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 +16 -7
- package/dist/clientAnnex/gc.js.map +1 -1
- package/dist/clientAnnex/heal.d.ts +65 -14
- package/dist/clientAnnex/heal.d.ts.map +1 -1
- package/dist/clientAnnex/heal.js +397 -298
- package/dist/clientAnnex/heal.js.map +1 -1
- package/dist/clientAnnex/index.d.ts +23 -7
- package/dist/clientAnnex/index.d.ts.map +1 -1
- package/dist/clientAnnex/index.js +26 -7
- 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 +249 -41
- 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 +237 -53
- package/dist/clientAnnex/log.d.ts.map +1 -1
- package/dist/clientAnnex/log.js +533 -198
- 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 +44 -72
- 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 +22 -8
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +20 -6
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterLogStore.d.ts +15 -12
- package/dist/keys/rosterLogStore.d.ts.map +1 -1
- package/dist/keys/rosterLogStore.js +21 -16
- 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/userKeyCascade.d.ts +8 -5
- package/dist/keys/userKeyCascade.d.ts.map +1 -1
- package/dist/keys/userKeyCascade.js +7 -6
- package/dist/keys/userKeyCascade.js.map +1 -1
- package/dist/keys/userKeyRoster.d.ts +95 -8
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +278 -35
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/keys/userKeyRosterCascade.d.ts +117 -16
- package/dist/keys/userKeyRosterCascade.d.ts.map +1 -1
- package/dist/keys/userKeyRosterCascade.js +184 -43
- 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 +13 -9
- package/dist/recovery/index.d.ts.map +1 -1
- package/dist/recovery/index.js +12 -8
- 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 +23 -0
- package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
- package/dist/recovery/recoveryDelegation.js +66 -46
- 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/appKey.d.ts +35 -1
- package/dist/request/appKey.d.ts.map +1 -1
- package/dist/request/appKey.js +29 -10
- package/dist/request/appKey.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, mintDelegatedClientsDelegation, mintGenerationDelegation, mintPointedClientAnnexGeneration, 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,259 +228,364 @@ 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
|
+
* The flip swallows nothing. The establishment's bootstrap arm tolerates
|
|
254
|
+
* an authorization-class refusal there because its Space may be a
|
|
255
|
+
* sibling-named one a concurrent run already flipped; this Space's id was
|
|
256
|
+
* minted a moment ago and no other run can hold it, so every failure is
|
|
257
|
+
* the transport or logic failure it looks like and propagates.
|
|
258
|
+
*
|
|
259
|
+
* @returns {Promise<string>} the fresh auxiliary Space's id
|
|
260
|
+
*/
|
|
261
|
+
async function mintFreshAnnexSpace() {
|
|
222
262
|
const freshSpaceId = mintSpaceId();
|
|
223
263
|
const keyAgent = await ladderVmAgent({ ladderSeed });
|
|
224
264
|
const bootstrapWas = bootstrapWasFor({ keyAgent });
|
|
225
|
-
const
|
|
265
|
+
const created = await ensureClientAnnexSpace({
|
|
226
266
|
was: bootstrapWas,
|
|
227
|
-
wasServerUrl,
|
|
228
267
|
spaceId: freshSpaceId,
|
|
229
|
-
controller: keyAgent.id
|
|
230
|
-
ladderSeed
|
|
231
|
-
});
|
|
232
|
-
// The delegation embeds while the Space still answers to the bootstrap
|
|
233
|
-
// did:key; the controller flip follows, then the pointer entry.
|
|
234
|
-
const ensured = await ensureGenerationDelegationCurrent({
|
|
235
|
-
store: clientAnnexLogStore({
|
|
236
|
-
was: bootstrapWas,
|
|
237
|
-
spaceId: freshSpaceId,
|
|
238
|
-
generationId: minted.generationId
|
|
239
|
-
}),
|
|
240
|
-
ladderSeed,
|
|
241
|
-
generationId: minted.generationId,
|
|
242
|
-
mintGenerationDelegation: mintDelegation,
|
|
243
|
-
expectedDid: minted.did,
|
|
244
|
-
...(pinStore !== undefined
|
|
245
|
-
? {
|
|
246
|
-
pinStore,
|
|
247
|
-
logId: clientAnnexLogPinId({
|
|
248
|
-
spaceId: freshSpaceId,
|
|
249
|
-
generationId: minted.generationId
|
|
250
|
-
})
|
|
251
|
-
}
|
|
252
|
-
: {}),
|
|
253
|
-
...(now !== undefined ? { now } : {})
|
|
268
|
+
controller: keyAgent.id
|
|
254
269
|
});
|
|
270
|
+
// The create's own answer is the current Description, so the flip carries
|
|
271
|
+
// it as `current` rather than re-reading what this call just wrote.
|
|
255
272
|
await bootstrapWas
|
|
256
273
|
.space(freshSpaceId)
|
|
257
|
-
.configure({ controller: account.did, force: true });
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
274
|
+
.configure({ current: created, controller: account.did, force: true });
|
|
275
|
+
return freshSpaceId;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* One Space Description read, judged by its HTTP STATUS alone. A 404 is
|
|
279
|
+
* `'not-found'`; a 2xx is `'present'`, whatever its body says, since a
|
|
280
|
+
* Space served with an unreadable body is a present Space and reading it
|
|
281
|
+
* as absence is exactly what would re-point a live account. Every other
|
|
282
|
+
* answer -- a transport failure, a 5xx, a 4xx that is not 404 -- throws,
|
|
283
|
+
* so nothing but a real 404 can ever reach the absence decision.
|
|
284
|
+
*
|
|
285
|
+
* The read goes through the raw signed request rather than the
|
|
286
|
+
* `describe()` handle, whose null-on-404 translation also swallows 401 and
|
|
287
|
+
* 403 and an unparseable body.
|
|
288
|
+
*
|
|
289
|
+
* @param options {object}
|
|
290
|
+
* @param options.was {WasClient} the client whose signer invokes
|
|
291
|
+
* @param options.annexSpaceId {string}
|
|
292
|
+
* @param [options.capability] {IZcap} the attached capability; absent
|
|
293
|
+
* means a root invocation
|
|
294
|
+
* @returns {Promise<'present' | 'not-found'>}
|
|
295
|
+
*/
|
|
296
|
+
async function readSpaceDescription({ was, annexSpaceId, capability }) {
|
|
297
|
+
let status;
|
|
298
|
+
try {
|
|
299
|
+
const response = await was.request({
|
|
300
|
+
path: spacePath(annexSpaceId),
|
|
301
|
+
method: 'GET',
|
|
302
|
+
...(capability !== undefined ? { capability } : {})
|
|
303
|
+
});
|
|
304
|
+
status = response.status;
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
if (rawRequestStatus(err) === 404) {
|
|
308
|
+
return 'not-found';
|
|
309
|
+
}
|
|
310
|
+
throw err;
|
|
311
|
+
}
|
|
312
|
+
if (status >= 200 && status < 300) {
|
|
313
|
+
return 'present';
|
|
314
|
+
}
|
|
315
|
+
if (status === 404) {
|
|
316
|
+
return 'not-found';
|
|
317
|
+
}
|
|
318
|
+
throw new Error(`client annex: the Space Description read for "${annexSpaceId}" ` +
|
|
319
|
+
`answered ${status}; the visit cannot tell whether the Space is gone.`);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Whether the auxiliary Space itself is gone from the server, asked only
|
|
323
|
+
* when the pointed generation's log did not read back. A storage server
|
|
324
|
+
* masks an unauthorized read as the same 404 an absent Space answers, so
|
|
325
|
+
* ONE 404 is not absence: it is "absent, or this reader has no authority
|
|
326
|
+
* here". Absence is therefore corroborated by two independent readers, and
|
|
327
|
+
* the Space is gone only when both answer a real 404.
|
|
328
|
+
*
|
|
329
|
+
* The first reader is a ladder-signed GET-only child of the Space's own
|
|
330
|
+
* root, which the account DID's document backs. The sibling delegation
|
|
331
|
+
* cannot carry the question: it targets the items subtree beneath the
|
|
332
|
+
* Space and says nothing about the Space Description.
|
|
333
|
+
*
|
|
334
|
+
* The second is a root invocation as the ladder VM's BARE did:key, the
|
|
335
|
+
* controller a torn establishment leaves behind when its flip never
|
|
336
|
+
* landed. That reader answers 2xx on exactly the Space the first reader
|
|
337
|
+
* has no authority over, so the pair covers both controllers a live annex
|
|
338
|
+
* Space of this credential's can have.
|
|
339
|
+
*
|
|
340
|
+
* The residual bound, stated because no read can close it: a server that
|
|
341
|
+
* does not admit the ladder delegation clause's single-verb predicate
|
|
342
|
+
* refuses the first probe with the same masked 404, and on an
|
|
343
|
+
* account-controlled Space the second probe is refused too. Both readers
|
|
344
|
+
* then say `'not-found'` about a live Space. That is a server older than
|
|
345
|
+
* the one this arm was built against, and the arm's cost there is a
|
|
346
|
+
* re-point of a live generation.
|
|
347
|
+
*
|
|
348
|
+
* @param options {object}
|
|
349
|
+
* @param options.annexSpaceId {string}
|
|
350
|
+
* @param options.was {WasClient} the standing client's storage client
|
|
351
|
+
* @returns {Promise<boolean>}
|
|
352
|
+
*/
|
|
353
|
+
async function annexSpaceAbsent({ annexSpaceId, was }) {
|
|
354
|
+
const probe = await mintSpaceRootVerbCapability({
|
|
268
355
|
zcapClient: ladderClient,
|
|
269
|
-
wasServerUrl,
|
|
270
|
-
|
|
356
|
+
storageServerUrl: wasServerUrl,
|
|
357
|
+
spaceId: annexSpaceId,
|
|
358
|
+
verb: 'GET',
|
|
271
359
|
controller: standingClient.did,
|
|
272
360
|
...(now !== undefined ? { now } : {})
|
|
273
361
|
});
|
|
362
|
+
const delegated = await readSpaceDescription({
|
|
363
|
+
was,
|
|
364
|
+
annexSpaceId,
|
|
365
|
+
capability: probe
|
|
366
|
+
});
|
|
367
|
+
if (delegated === 'present') {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
const bootstrapWas = bootstrapWasFor({
|
|
371
|
+
keyAgent: await ladderVmAgent({ ladderSeed })
|
|
372
|
+
});
|
|
373
|
+
const asBootstrap = await readSpaceDescription({
|
|
374
|
+
was: bootstrapWas,
|
|
375
|
+
annexSpaceId
|
|
376
|
+
});
|
|
377
|
+
return asBootstrap === 'not-found';
|
|
378
|
+
}
|
|
379
|
+
let spaceMinted = false;
|
|
380
|
+
let pointedSpaceMissing = false;
|
|
381
|
+
/**
|
|
382
|
+
* The arms that run inside one auxiliary Space: the sibling delegation,
|
|
383
|
+
* the pointed generation's renewal, and the fresh-generation mint with its
|
|
384
|
+
* pointer move. Called once on the resolved Space, and once more on a
|
|
385
|
+
* fresh Space when the pointed one turns out to be gone -- the replacement
|
|
386
|
+
* is decided before any write, so nothing is stranded by the re-run.
|
|
387
|
+
*
|
|
388
|
+
* @param options {object}
|
|
389
|
+
* @param options.annexSpaceId {string} the Space this run works in
|
|
390
|
+
* @param options.allowSpaceReplacement {boolean} whether an absent
|
|
391
|
+
* pointed generation may be checked against the Space itself, and a
|
|
392
|
+
* fresh Space minted when the Space is gone. False on the run that
|
|
393
|
+
* already works in a Space this visit created
|
|
394
|
+
* @param [options.pointer] {string} the pointed annex DID, when the
|
|
395
|
+
* document names one and this run works in its Space
|
|
396
|
+
* @returns {Promise<ClientAnnexGenerationEnsureOutcome>}
|
|
397
|
+
*/
|
|
398
|
+
async function runInAnnexSpace({ annexSpaceId, allowSpaceReplacement, pointer }) {
|
|
399
|
+
// A usable sibling first: absent, targeting a different Space than this
|
|
400
|
+
// run works in, or stale on either of the standing-zcap axes -- expiry
|
|
401
|
+
// (past, or inside the renewal window) and signer death (its proof key
|
|
402
|
+
// no longer under `capabilityDelegation` in the verified account
|
|
403
|
+
// document, the current-key-set rule) -- a fresh sibling is minted
|
|
404
|
+
// (local ladder-VM signing, which verifies because the gate above proved
|
|
405
|
+
// the VM a document verification method) so every annex request below
|
|
406
|
+
// can ride it.
|
|
407
|
+
let sibling = delegatedClients;
|
|
408
|
+
let siblingReminted = false;
|
|
409
|
+
const siblingStale = sibling !== undefined &&
|
|
410
|
+
standingZcapStale({
|
|
411
|
+
zcap: sibling,
|
|
412
|
+
doc: account.doc,
|
|
413
|
+
...(now !== undefined ? { now } : {})
|
|
414
|
+
});
|
|
415
|
+
if (sibling === undefined ||
|
|
416
|
+
siblingSpaceId !== annexSpaceId ||
|
|
417
|
+
siblingStale) {
|
|
418
|
+
sibling = await mintDelegatedClientsDelegation({
|
|
419
|
+
zcapClient: ladderClient,
|
|
420
|
+
wasServerUrl,
|
|
421
|
+
clientAnnexSpaceId: annexSpaceId,
|
|
422
|
+
controller: standingClient.did,
|
|
423
|
+
...(now !== undefined ? { now } : {})
|
|
424
|
+
});
|
|
425
|
+
siblingReminted = true;
|
|
426
|
+
}
|
|
427
|
+
const usableSibling = sibling;
|
|
428
|
+
const standingWas = new WasClient({
|
|
429
|
+
serverUrl: wasServerUrl,
|
|
430
|
+
zcapClient: standingClient.zcapClient
|
|
431
|
+
});
|
|
432
|
+
const storeFor = (generationId) => clientAnnexLogStore({
|
|
433
|
+
was: standingWas,
|
|
434
|
+
spaceId: annexSpaceId,
|
|
435
|
+
generationId,
|
|
436
|
+
capability: usableSibling
|
|
437
|
+
});
|
|
438
|
+
const annexPin = (generationId) => pinStore !== undefined
|
|
439
|
+
? {
|
|
440
|
+
pinStore,
|
|
441
|
+
logId: clientAnnexLogPinId({ spaceId: annexSpaceId, generationId })
|
|
442
|
+
}
|
|
443
|
+
: {};
|
|
444
|
+
// RENEW PRECEDES MINT: a live, verifiable pointed generation is renewed
|
|
445
|
+
// in place; only a rung this generation never committed falls through to
|
|
446
|
+
// the fresh mint (the GC swap's no-committed-survivor escape).
|
|
447
|
+
if (pointer !== undefined) {
|
|
448
|
+
const parts = clientAnnexDidParts({ did: pointer });
|
|
449
|
+
const pointedLog = await readPublishedLog({
|
|
450
|
+
idStore: storeFor(parts.generationId),
|
|
451
|
+
expectedDid: pointer,
|
|
452
|
+
...annexPin(parts.generationId)
|
|
453
|
+
});
|
|
454
|
+
if (pointedLog !== undefined) {
|
|
455
|
+
try {
|
|
456
|
+
const ensured = await ensureGenerationDelegationCurrent({
|
|
457
|
+
store: storeFor(parts.generationId),
|
|
458
|
+
ladderSeed,
|
|
459
|
+
generationId: parts.generationId,
|
|
460
|
+
mintGenerationDelegation: mintDelegation,
|
|
461
|
+
expectedDid: pointer,
|
|
462
|
+
accountDoc: account.doc,
|
|
463
|
+
// The head just read: on a healthy account this stage spends no
|
|
464
|
+
// second round trip on the same log, and hands its head back for
|
|
465
|
+
// the enrollment to build on.
|
|
466
|
+
published: pointedLog,
|
|
467
|
+
...annexPin(parts.generationId),
|
|
468
|
+
...(now !== undefined ? { now } : {})
|
|
469
|
+
});
|
|
470
|
+
const resealed = await resealRecord({
|
|
471
|
+
delegatedClients: usableSibling,
|
|
472
|
+
siblingReminted
|
|
473
|
+
});
|
|
474
|
+
return {
|
|
475
|
+
clientAnnexDid: pointer,
|
|
476
|
+
generationDelegation: ensured.delegation,
|
|
477
|
+
delegation: usableBridge,
|
|
478
|
+
delegatedClients: usableSibling,
|
|
479
|
+
generationMinted: false,
|
|
480
|
+
spaceMinted,
|
|
481
|
+
pointedSpaceMissing,
|
|
482
|
+
delegationRenewed: ensured.renewed,
|
|
483
|
+
siblingReminted,
|
|
484
|
+
bridgeReminted,
|
|
485
|
+
...(ensured.published !== undefined
|
|
486
|
+
? { generationLog: ensured.published }
|
|
487
|
+
: {}),
|
|
488
|
+
...resealed
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
catch (err) {
|
|
492
|
+
if (err.name !==
|
|
493
|
+
'ClientAnnexRungUncommittedError') {
|
|
494
|
+
throw err;
|
|
495
|
+
}
|
|
496
|
+
// This credential's rung was never committed into the pointed
|
|
497
|
+
// generation (bound mid-generation): fall through to the fresh
|
|
498
|
+
// mint, which commits it with the fresh genesis.
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
else if (allowSpaceReplacement &&
|
|
502
|
+
(await annexSpaceAbsent({ annexSpaceId, was: standingWas }))) {
|
|
503
|
+
// THE POINTED SPACE IS GONE. A missing generation log inside a live
|
|
504
|
+
// Space is the fresh-generation arm's case; a missing SPACE is not,
|
|
505
|
+
// since every write below would land in a Space that does not exist
|
|
506
|
+
// and the visit would fail on something other than the typed
|
|
507
|
+
// refusal. The Space is re-minted and the run starts over in it,
|
|
508
|
+
// before anything has been written.
|
|
509
|
+
await attributePointerEntryRung({ ladderSeed, log: account.log });
|
|
510
|
+
const freshSpaceId = await mintFreshAnnexSpace();
|
|
511
|
+
spaceMinted = true;
|
|
512
|
+
pointedSpaceMissing = true;
|
|
513
|
+
return runInAnnexSpace({
|
|
514
|
+
annexSpaceId: freshSpaceId,
|
|
515
|
+
allowSpaceReplacement: false
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
// THE FRESH-GENERATION ARM: pre-flight attribution first (never mint a
|
|
520
|
+
// generation the pointer entry cannot then name), then the GC swap's
|
|
521
|
+
// stage order minus its revoke -- mint, install the delegation,
|
|
522
|
+
// re-point. The fresh genesis commits only the acting credential's annex
|
|
523
|
+
// rung; other standing credentials' per-generation rungs are re-committed
|
|
524
|
+
// only by their own later ceremonies (a property of every generation
|
|
525
|
+
// swap).
|
|
526
|
+
await attributePointerEntryRung({ ladderSeed, log: account.log });
|
|
527
|
+
const generation = await mintPointedClientAnnexGeneration({
|
|
528
|
+
was: standingWas,
|
|
529
|
+
wasServerUrl,
|
|
530
|
+
spaceId: annexSpaceId,
|
|
531
|
+
controller: account.did,
|
|
532
|
+
ladderSeed,
|
|
533
|
+
capability: usableSibling,
|
|
534
|
+
mintGenerationDelegation: mintDelegation,
|
|
535
|
+
// No revocation of the superseded generation's delegation is
|
|
536
|
+
// attempted: a transient visit has no reach that could invoke it (the
|
|
537
|
+
// standing client is neither the Space controller nor in that
|
|
538
|
+
// delegation's chain). The pointer move itself retires it on a
|
|
539
|
+
// conforming server -- the inspector clause compares the delegation's
|
|
540
|
+
// controller against the document's pointer -- and it otherwise rots
|
|
541
|
+
// on its TTL.
|
|
542
|
+
point: clientAnnexDid => movePointerAsLadder({
|
|
543
|
+
idStore,
|
|
544
|
+
ladderSeed,
|
|
545
|
+
clientAnnexDid,
|
|
546
|
+
accountDid: account.did,
|
|
547
|
+
...(pinStore !== undefined
|
|
548
|
+
? { pinStore, logId: accountLogPinId({ spaceId }) }
|
|
549
|
+
: {})
|
|
550
|
+
}),
|
|
551
|
+
...(pinStore !== undefined ? { pinStore } : {}),
|
|
552
|
+
...(now !== undefined ? { now } : {})
|
|
553
|
+
});
|
|
274
554
|
const resealed = await resealRecord({
|
|
275
|
-
delegatedClients:
|
|
276
|
-
siblingReminted
|
|
555
|
+
delegatedClients: usableSibling,
|
|
556
|
+
siblingReminted
|
|
277
557
|
});
|
|
278
558
|
return {
|
|
279
|
-
clientAnnexDid:
|
|
280
|
-
generationDelegation:
|
|
559
|
+
clientAnnexDid: generation.clientAnnexDid,
|
|
560
|
+
generationDelegation: generation.generationDelegation,
|
|
281
561
|
delegation: usableBridge,
|
|
282
|
-
delegatedClients:
|
|
562
|
+
delegatedClients: usableSibling,
|
|
283
563
|
generationMinted: true,
|
|
284
|
-
spaceMinted
|
|
564
|
+
spaceMinted,
|
|
565
|
+
pointedSpaceMissing,
|
|
285
566
|
delegationRenewed: false,
|
|
286
|
-
siblingReminted
|
|
567
|
+
siblingReminted,
|
|
287
568
|
bridgeReminted,
|
|
288
569
|
...resealed
|
|
289
570
|
};
|
|
290
571
|
}
|
|
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)
|
|
572
|
+
if (annexSpaceId === undefined) {
|
|
573
|
+
// NEITHER THE POINTER NOR A SIBLING NAMES A SPACE. The pre-flight
|
|
574
|
+
// attribution runs before any Space or generation is minted (a bridge
|
|
575
|
+
// delegation mint writes nothing durable).
|
|
576
|
+
await attributePointerEntryRung({ ladderSeed, log: account.log });
|
|
577
|
+
const freshSpaceId = await mintFreshAnnexSpace();
|
|
578
|
+
spaceMinted = true;
|
|
579
|
+
return runInAnnexSpace({
|
|
580
|
+
annexSpaceId: freshSpaceId,
|
|
581
|
+
allowSpaceReplacement: false
|
|
345
582
|
});
|
|
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
583
|
}
|
|
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
|
|
584
|
+
return runInAnnexSpace({
|
|
585
|
+
annexSpaceId,
|
|
586
|
+
allowSpaceReplacement: true,
|
|
587
|
+
...(pointer !== undefined ? { pointer } : {})
|
|
400
588
|
});
|
|
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
|
-
: {})
|
|
424
|
-
});
|
|
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
589
|
}
|
|
469
590
|
/**
|
|
470
591
|
* The annex Space, in the settled resolution order: the account document's
|
|
@@ -497,85 +618,65 @@ export function resolveClientAnnexSpaceId({ doc, delegatedClients }) {
|
|
|
497
618
|
};
|
|
498
619
|
}
|
|
499
620
|
/**
|
|
500
|
-
* The pre-flight rung attribution
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
* {@link ClientAnnexGenerationUnavailableError} before
|
|
507
|
-
*
|
|
508
|
-
*
|
|
621
|
+
* The pre-flight rung attribution every pointer-moving arm runs before
|
|
622
|
+
* minting anything: this ladder has a rung the pointer entry will be able to
|
|
623
|
+
* sign with, either standing in `updateKeys` already (`revealed`) or
|
|
624
|
+
* committed in `nextKeyHashes` and revealable by {@link movePointerAsLadder}
|
|
625
|
+
* (`committed`). A ladder the log carries no rung of at all, and an
|
|
626
|
+
* ambiguous attribution, refuse with
|
|
627
|
+
* {@link ClientAnnexGenerationUnavailableError} before a generation or a
|
|
628
|
+
* Space is minted -- the one place the ladder's `LadderAttributionError`
|
|
629
|
+
* maps onto that refusal.
|
|
509
630
|
*
|
|
510
631
|
* @param options {object}
|
|
511
632
|
* @param options.ladderSeed {Uint8Array}
|
|
512
633
|
* @param options.log {DIDLog} the VERIFIED account log
|
|
513
|
-
* @returns {Promise<
|
|
634
|
+
* @returns {Promise<{ rung: LadderRung, state: LadderRungState }>}
|
|
514
635
|
*/
|
|
515
|
-
export async function
|
|
516
|
-
const
|
|
517
|
-
const current = params[params.length - 1] ?? {
|
|
518
|
-
updateKeys: [],
|
|
519
|
-
nextKeyHashes: []
|
|
520
|
-
};
|
|
521
|
-
const unattributable = () => new ClientAnnexGenerationUnavailableError({
|
|
522
|
-
reason: 'update-key-not-attributable',
|
|
523
|
-
message: "No current account-log update key is a rung of this credential's " +
|
|
524
|
-
'ladder; the pointer entry could not be signed, so nothing is minted.'
|
|
525
|
-
});
|
|
526
|
-
let attributed;
|
|
636
|
+
export async function attributePointerEntryRung({ ladderSeed, log }) {
|
|
637
|
+
const current = currentLogParameters({ log });
|
|
527
638
|
try {
|
|
528
|
-
|
|
639
|
+
return await attributeLadderRung({ ladderSeed, published: current });
|
|
529
640
|
}
|
|
530
641
|
catch (err) {
|
|
531
642
|
if (err.name === 'LadderAttributionError') {
|
|
532
|
-
throw
|
|
643
|
+
throw new ClientAnnexGenerationUnavailableError({
|
|
644
|
+
reason: 'update-key-not-attributable',
|
|
645
|
+
message: "The account log carries no rung of this credential's ladder, or " +
|
|
646
|
+
'the attribution is ambiguous; the pointer entry could not be ' +
|
|
647
|
+
'signed, so nothing is minted.'
|
|
648
|
+
});
|
|
533
649
|
}
|
|
534
650
|
throw err;
|
|
535
651
|
}
|
|
536
|
-
if (attributed.state !== 'revealed') {
|
|
537
|
-
throw unattributable();
|
|
538
|
-
}
|
|
539
|
-
const staged = await ladderRung({
|
|
540
|
-
ladderSeed,
|
|
541
|
-
index: attributed.rung.index + 1
|
|
542
|
-
});
|
|
543
|
-
return { updateSeed: attributed.rung.seed, stagedSeed: staged.seed };
|
|
544
652
|
}
|
|
545
653
|
/**
|
|
546
|
-
* The
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
* Space is minted.
|
|
654
|
+
* The `{ updateSeed, stagedSeed }` pair the pointer entry signs with, over
|
|
655
|
+
* {@link attributePointerEntryRung}. The signer must be a REVEALED rung (the
|
|
656
|
+
* entry verifies against the log's `updateKeys`), with the next rung staged
|
|
657
|
+
* per the carry-over convention; a rung standing only as a committed hash
|
|
658
|
+
* cannot sign and refuses the same way. Exported for the establishment's
|
|
659
|
+
* stage-3 primitive, whose pointer entry signs by the same attribution.
|
|
553
660
|
*
|
|
554
661
|
* @param options {object}
|
|
555
662
|
* @param options.ladderSeed {Uint8Array}
|
|
556
663
|
* @param options.log {DIDLog} the VERIFIED account log
|
|
557
|
-
* @returns {Promise<
|
|
664
|
+
* @returns {Promise<ClientWebvhUpdateKeys>}
|
|
558
665
|
*/
|
|
559
|
-
async function
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
catch (err) {
|
|
569
|
-
if (err.name === 'LadderAttributionError') {
|
|
570
|
-
throw new ClientAnnexGenerationUnavailableError({
|
|
571
|
-
reason: 'update-key-not-attributable',
|
|
572
|
-
message: "The account log carries no rung of this credential's ladder, or " +
|
|
573
|
-
'the attribution is ambiguous; the pointer entry could not be ' +
|
|
574
|
-
'signed, so nothing is minted.'
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
throw err;
|
|
666
|
+
export async function pointerEntryUpdateKeys({ ladderSeed, log }) {
|
|
667
|
+
const attributed = await attributePointerEntryRung({ ladderSeed, log });
|
|
668
|
+
if (attributed.state !== 'revealed') {
|
|
669
|
+
throw new ClientAnnexGenerationUnavailableError({
|
|
670
|
+
reason: 'update-key-not-attributable',
|
|
671
|
+
message: "No current account-log update key is a rung of this credential's " +
|
|
672
|
+
'ladder; the pointer entry could not be signed, so nothing is minted.'
|
|
673
|
+
});
|
|
578
674
|
}
|
|
675
|
+
const staged = await ladderRung({
|
|
676
|
+
ladderSeed,
|
|
677
|
+
index: attributed.rung.index + 1
|
|
678
|
+
});
|
|
679
|
+
return { updateSeed: attributed.rung.seed, stagedSeed: staged.seed };
|
|
579
680
|
}
|
|
580
681
|
/**
|
|
581
682
|
* The `#DelegatedClients` pointer move as a credential-only visit makes it:
|
|
@@ -614,7 +715,7 @@ async function assertPointerEntryAttributable({ ladderSeed, log }) {
|
|
|
614
715
|
* racing entry landing between the attribution and the PUT loses the CAS and
|
|
615
716
|
* surfaces as a `WebvhLogConflictError` -- the refusal the outer loop
|
|
616
717
|
* re-attributes from. The pre-flight guard
|
|
617
|
-
* ({@link
|
|
718
|
+
* ({@link attributePointerEntryRung}) therefore cannot fire from
|
|
618
719
|
* staleness here: it runs on the caller's snapshot before anything is minted,
|
|
619
720
|
* while every entry this function publishes is built on a head it read
|
|
620
721
|
* itself.
|
|
@@ -641,14 +742,12 @@ async function movePointerAsLadder({ idStore, ladderSeed, clientAnnexDid, accoun
|
|
|
641
742
|
});
|
|
642
743
|
// The head the reveal entry just published (or the unchanged head, when
|
|
643
744
|
// the rung was revealed already), under the same pin.
|
|
644
|
-
const published = await
|
|
745
|
+
const published = await readPublishedLogOrThrow({
|
|
645
746
|
idStore,
|
|
646
747
|
expectedDid: accountDid,
|
|
647
|
-
...pin
|
|
748
|
+
...pin,
|
|
749
|
+
missingMessage: 'did:webvh: did.jsonl is missing; nothing to point at a client annex.'
|
|
648
750
|
});
|
|
649
|
-
if (published === undefined) {
|
|
650
|
-
throw new Error('did:webvh: did.jsonl is missing; nothing to point at a client annex.');
|
|
651
|
-
}
|
|
652
751
|
// A racing ceremony that consumed the rung between this reveal and this
|
|
653
752
|
// read leaves the ladder committed-only again, which the attribution
|
|
654
753
|
// reports as `update-key-not-attributable`. Inside this loop that is a
|
|
@@ -674,7 +773,7 @@ async function movePointerAsLadder({ idStore, ladderSeed, clientAnnexDid, accoun
|
|
|
674
773
|
}
|
|
675
774
|
await setDelegatedClientsPointerOnce({
|
|
676
775
|
idStore,
|
|
677
|
-
updateKeys,
|
|
776
|
+
signer: { kind: 'client', updateKeys },
|
|
678
777
|
clientAnnexDid,
|
|
679
778
|
expectedDid: accountDid,
|
|
680
779
|
logOnly: true,
|