@interop/wallet-core 0.48.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts +118 -0
- package/dist/clientAnnex/credentialAnchoredGenesis.d.ts.map +1 -0
- package/dist/clientAnnex/credentialAnchoredGenesis.js +174 -0
- package/dist/clientAnnex/credentialAnchoredGenesis.js.map +1 -0
- package/dist/clientAnnex/forget.d.ts +138 -0
- package/dist/clientAnnex/forget.d.ts.map +1 -0
- package/dist/clientAnnex/forget.js +133 -0
- package/dist/clientAnnex/forget.js.map +1 -0
- package/dist/clientAnnex/forgetLast.d.ts +267 -0
- package/dist/clientAnnex/forgetLast.d.ts.map +1 -0
- package/dist/clientAnnex/forgetLast.js +374 -0
- package/dist/clientAnnex/forgetLast.js.map +1 -0
- package/dist/clientAnnex/gc.d.ts +255 -0
- package/dist/clientAnnex/gc.d.ts.map +1 -0
- package/dist/clientAnnex/gc.js +445 -0
- package/dist/clientAnnex/gc.js.map +1 -0
- package/dist/clientAnnex/index.d.ts +60 -0
- package/dist/clientAnnex/index.d.ts.map +1 -0
- package/dist/clientAnnex/index.js +60 -0
- package/dist/clientAnnex/index.js.map +1 -0
- package/dist/{unlock → clientAnnex}/ladder.d.ts +99 -23
- package/dist/clientAnnex/ladder.d.ts.map +1 -0
- package/dist/clientAnnex/ladder.js +474 -0
- package/dist/clientAnnex/ladder.js.map +1 -0
- package/dist/clientAnnex/ladderAnchored.d.ts +276 -0
- package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -0
- package/dist/clientAnnex/ladderAnchored.js +631 -0
- package/dist/clientAnnex/ladderAnchored.js.map +1 -0
- package/dist/{webvh/companion.d.ts → clientAnnex/log.d.ts} +373 -152
- package/dist/clientAnnex/log.d.ts.map +1 -0
- package/dist/{webvh/companion.js → clientAnnex/log.js} +654 -261
- package/dist/clientAnnex/log.js.map +1 -0
- package/dist/clientAnnex/recoveryLadderAnchored.d.ts +103 -0
- package/dist/clientAnnex/recoveryLadderAnchored.d.ts.map +1 -0
- package/dist/clientAnnex/recoveryLadderAnchored.js +263 -0
- package/dist/clientAnnex/recoveryLadderAnchored.js.map +1 -0
- package/dist/{unlock → clientAnnex}/selfEnroll.d.ts +1 -1
- package/dist/clientAnnex/selfEnroll.d.ts.map +1 -0
- package/dist/{unlock → clientAnnex}/selfEnroll.js +1 -1
- package/dist/clientAnnex/selfEnroll.js.map +1 -0
- package/dist/clientAnnex/zcap.d.ts +49 -0
- package/dist/clientAnnex/zcap.d.ts.map +1 -0
- package/dist/clientAnnex/zcap.js +101 -0
- package/dist/clientAnnex/zcap.js.map +1 -0
- package/dist/clients/index.d.ts +9 -6
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +8 -5
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/listing.d.ts +32 -0
- package/dist/clients/listing.d.ts.map +1 -1
- package/dist/clients/listing.js +47 -1
- package/dist/clients/listing.js.map +1 -1
- package/dist/clients/revocation.d.ts +33 -1
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +16 -4
- package/dist/clients/revocation.js.map +1 -1
- package/dist/enrollment/index.d.ts +6 -4
- package/dist/enrollment/index.d.ts.map +1 -1
- package/dist/enrollment/index.js +6 -4
- package/dist/enrollment/index.js.map +1 -1
- package/dist/enrollment/onboardingInvite.d.ts +5 -88
- package/dist/enrollment/onboardingInvite.d.ts.map +1 -1
- package/dist/enrollment/onboardingInvite.js +5 -168
- package/dist/enrollment/onboardingInvite.js.map +1 -1
- package/dist/genesis/index.d.ts +5 -0
- package/dist/genesis/index.d.ts.map +1 -1
- package/dist/genesis/index.js +5 -0
- package/dist/genesis/index.js.map +1 -1
- package/dist/keys/index.d.ts +1 -1
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +1 -1
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/spaceEpochs.d.ts +7 -2
- package/dist/keys/spaceEpochs.d.ts.map +1 -1
- package/dist/keys/spaceEpochs.js +8 -2
- package/dist/keys/spaceEpochs.js.map +1 -1
- package/dist/keys/userKeyRoster.d.ts +39 -0
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +43 -1
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/recovery/index.d.ts +5 -3
- package/dist/recovery/index.d.ts.map +1 -1
- package/dist/recovery/index.js +4 -2
- package/dist/recovery/index.js.map +1 -1
- package/dist/recovery/recoveryDelegation.d.ts +35 -12
- package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
- package/dist/recovery/recoveryDelegation.js +84 -86
- package/dist/recovery/recoveryDelegation.js.map +1 -1
- package/dist/recovery/recoveryWebvh.d.ts +32 -1
- package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
- package/dist/recovery/recoveryWebvh.js +2 -2
- package/dist/recovery/recoveryWebvh.js.map +1 -1
- package/dist/request/capabilityRequest.d.ts +33 -0
- package/dist/request/capabilityRequest.d.ts.map +1 -0
- package/dist/request/capabilityRequest.js +35 -0
- package/dist/request/capabilityRequest.js.map +1 -0
- package/dist/request/ephemeralExchange.d.ts +118 -0
- package/dist/request/ephemeralExchange.d.ts.map +1 -0
- package/dist/request/ephemeralExchange.js +224 -0
- package/dist/request/ephemeralExchange.js.map +1 -0
- package/dist/request/index.d.ts +6 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +6 -0
- package/dist/request/index.js.map +1 -1
- package/dist/space/activity.d.ts +38 -0
- package/dist/space/activity.d.ts.map +1 -1
- package/dist/space/activity.js +41 -1
- package/dist/space/activity.js.map +1 -1
- package/dist/space/index.d.ts +1 -1
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +1 -1
- package/dist/space/index.js.map +1 -1
- package/dist/unlock/index.d.ts +11 -23
- package/dist/unlock/index.d.ts.map +1 -1
- package/dist/unlock/index.js +10 -21
- package/dist/unlock/index.js.map +1 -1
- package/dist/unlock/retire.d.ts +47 -3
- package/dist/unlock/retire.d.ts.map +1 -1
- package/dist/unlock/retire.js +21 -5
- package/dist/unlock/retire.js.map +1 -1
- package/dist/unlock/standingWebvh.d.ts +37 -82
- package/dist/unlock/standingWebvh.d.ts.map +1 -1
- package/dist/unlock/standingWebvh.js +64 -247
- package/dist/unlock/standingWebvh.js.map +1 -1
- package/dist/unlock/unlockRecord.d.ts +13 -6
- package/dist/unlock/unlockRecord.d.ts.map +1 -1
- package/dist/unlock/unlockRecord.js +14 -8
- package/dist/unlock/unlockRecord.js.map +1 -1
- package/dist/webvh/delegatedLogStore.d.ts +5 -5
- package/dist/webvh/delegatedLogStore.js +1 -1
- package/dist/webvh/didWebvh.d.ts +20 -10
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +17 -17
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/index.d.ts +9 -23
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +9 -22
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts +77 -5
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +154 -61
- package/dist/webvh/revokeClient.js.map +1 -1
- package/dist/webvh/standingZcap.d.ts +11 -1
- package/dist/webvh/standingZcap.d.ts.map +1 -1
- package/dist/webvh/standingZcap.js +13 -14
- package/dist/webvh/standingZcap.js.map +1 -1
- package/dist/webvh/wasIdStore.d.ts +13 -7
- package/dist/webvh/wasIdStore.d.ts.map +1 -1
- package/dist/webvh/wasIdStore.js +8 -4
- package/dist/webvh/wasIdStore.js.map +1 -1
- package/dist/webvh/zcap.d.ts +0 -24
- package/dist/webvh/zcap.d.ts.map +1 -1
- package/dist/webvh/zcap.js +0 -42
- package/dist/webvh/zcap.js.map +1 -1
- package/package.json +40 -34
- package/dist/unlock/ladder.d.ts.map +0 -1
- package/dist/unlock/ladder.js +0 -254
- package/dist/unlock/ladder.js.map +0 -1
- package/dist/unlock/selfEnroll.d.ts.map +0 -1
- package/dist/unlock/selfEnroll.js.map +0 -1
- package/dist/webvh/companion.d.ts.map +0 -1
- package/dist/webvh/companion.js.map +0 -1
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The ladder-anchored ceremonies on the ACCOUNT log -- everything a standing
|
|
6
|
+
* credential's ladder does to the world-readable `did.jsonl` beyond the
|
|
7
|
+
* split-posture edits (which stay in `unlock/standingWebvh.ts`):
|
|
8
|
+
*
|
|
9
|
+
* - {@link createLadderAnchoredAccountLog} / {@link ensureLadderAnchoredDidWebvh}
|
|
10
|
+
* -- the genesis of an account with zero enrolled durable clients, anchored
|
|
11
|
+
* on the credential's ladder alone (rung 0 signs, the ladder VM and the
|
|
12
|
+
* credential's `keyAgreement` posture fold into the one entry).
|
|
13
|
+
* - {@link selfEnrollWebvhClient} -- the self-enrolling continuation a fresh
|
|
14
|
+
* browser runs with nothing but the credential: two entries through the
|
|
15
|
+
* record's delegated `did.jsonl` bridge --
|
|
16
|
+
*
|
|
17
|
+
* 1. **Reveal + commit**: ladder rung `i` joins `updateKeys` (its hash
|
|
18
|
+
* stands committed, which is what makes the entry verify) and
|
|
19
|
+
* `nextKeyHashes` extends with the new ordinary client's update- and
|
|
20
|
+
* staged-key hashes plus `hash(rung i + 1)` -- the credential's next
|
|
21
|
+
* standing commitment.
|
|
22
|
+
* 2. **Add + retire the rung**: signed by the new client's update key
|
|
23
|
+
* (revealed from the commit), this entry publishes the new client's
|
|
24
|
+
* verification methods and update key and drops the spent rung and its
|
|
25
|
+
* hash. The credential's own posture -- its `keyAgreement` entry and the
|
|
26
|
+
* freshly committed `hash(rung i + 1)` -- stands untouched, ready for
|
|
27
|
+
* the next self-enrollment. Nothing is spent, and no replacement exists.
|
|
28
|
+
* When the account was LADDER-ANCHORED, the same atomic entry removes
|
|
29
|
+
* the ladder VM from the document and its relations -- the transitional
|
|
30
|
+
* key exists only while no durable client does, and folding the removal
|
|
31
|
+
* in leaves no window with neither.
|
|
32
|
+
*
|
|
33
|
+
* - {@link forgetWebvhClient} -- self-enrollment in reverse: one atomic
|
|
34
|
+
* ladder-signed removal entry through the bridge takes a durable client's
|
|
35
|
+
* whole document footprint out; the last enrolled durable client refuses
|
|
36
|
+
* ({@link LastDurableClientForgetError}).
|
|
37
|
+
* - {@link installLadderVmWebvh} / {@link forgetLastWebvhClient} -- the two
|
|
38
|
+
* entries of the LAST durable client's forget (decision 0004's 2026-08-19
|
|
39
|
+
* amendment): an install entry publishing the ladder VM while the client
|
|
40
|
+
* stands (the both-present transitional state), then -- after the
|
|
41
|
+
* revocations the composed ceremony runs in between -- a removal entry
|
|
42
|
+
* that takes the client out while the installed VM keeps the account
|
|
43
|
+
* ladder-anchored. The composed ceremony is `forgetLast.ts`.
|
|
44
|
+
*
|
|
45
|
+
* Which rung is current is recovered from the log itself
|
|
46
|
+
* (`attributeLadderRung`, fail-closed); a lost compare-and-swap race re-runs,
|
|
47
|
+
* re-attributes, and climbs to the winner's committed rung -- the
|
|
48
|
+
* retry-up-the-ladder resolution. Every stage is idempotent and resumable
|
|
49
|
+
* from durable state alone, on the recovery continuation's pattern.
|
|
50
|
+
*/
|
|
51
|
+
import { deriveNextKeyHash, updateDID } from '@interop/did-method-webvh';
|
|
52
|
+
import { assertCarryOverCommitments, concludeWithPublishedLog, createLadderAnchoredWebvhLog, didWebvhControllerTemplate, genesisNextKeyHashes, ladderVerificationMethod, markedVerificationMethodPair, pinOfLog, publishWebvhLog, putLogResource, readPublishedLog, relationIds, updateKeySigner, withLogConflictRetry } from '../webvh/didWebvh.js';
|
|
53
|
+
import { accountLogPinId } from '../webvh/verifyLog.js';
|
|
54
|
+
import { ladderVmIds } from '../webvh/listClients.js';
|
|
55
|
+
import { clientRemovalFields, clientRemovalTarget } from '../webvh/revokeClient.js';
|
|
56
|
+
import { readLogOrThrow, unlockKeyVerificationMethod } from '../unlock/standingWebvh.js';
|
|
57
|
+
import { attributeLadderRung, ladderRung, ladderVmKeyMultibase } from './ladder.js';
|
|
58
|
+
/**
|
|
59
|
+
* LADDER-ANCHORED GENESIS: assembles the one-entry did:webvh log of an account
|
|
60
|
+
* with zero enrolled durable clients, anchored on the minting credential's
|
|
61
|
+
* ladder alone. Everything derives from the ladder seed: rung 0 is the sole
|
|
62
|
+
* `updateKeys` member and signs the entry, `nextKeyHashes` commits rung 0's
|
|
63
|
+
* own carry-over hash plus rung 1 (the staged rung) -- the carry-over hash is
|
|
64
|
+
* what the first durable self-enrollment's reveal-and-commit entry,
|
|
65
|
+
* re-stating `updateKeys` containing rung 0, requires --
|
|
66
|
+
* and the ladder VM (the stable sibling) is published under `assertionMethod`
|
|
67
|
+
* and `capabilityDelegation` only. The credential's `keyAgreement` posture
|
|
68
|
+
* entry is FOLDED INTO GENESIS -- no enrolled client exists to run the
|
|
69
|
+
* separate bind entry ({@link publishUnlockKey}) -- so the genesis
|
|
70
|
+
* `keyAgreement` array holds only the credential's entry.
|
|
71
|
+
*
|
|
72
|
+
* The ladder-anchored window this opens is closed by the credential's first
|
|
73
|
+
* durable self-enrollment ({@link selfEnrollWebvhClient}), whose add entry
|
|
74
|
+
* atomically publishes the client, retires rung 0, and removes the ladder VM.
|
|
75
|
+
*
|
|
76
|
+
* The caller owns publication (conditional, create-only) and the pointer
|
|
77
|
+
* write that follows; this assembles and signs the log only.
|
|
78
|
+
*
|
|
79
|
+
* @param options {object}
|
|
80
|
+
* @param options.wasServerUrl {string}
|
|
81
|
+
* @param options.spaceId {string}
|
|
82
|
+
* @param options.ladderSeed {Uint8Array} the credential's ladder seed
|
|
83
|
+
* @param options.keyAgreement {UnlockKeyAgreementPublication} the
|
|
84
|
+
* credential's key-agreement publication (commitment or verbatim)
|
|
85
|
+
* @returns {Promise<{ log: DIDLog, webDoc: object, did: string }>}
|
|
86
|
+
*/
|
|
87
|
+
export async function createLadderAnchoredAccountLog({ wasServerUrl, spaceId, ladderSeed, keyAgreement }) {
|
|
88
|
+
const rung0 = await ladderRung({ ladderSeed, index: 0 });
|
|
89
|
+
const rung1 = await ladderRung({ ladderSeed, index: 1 });
|
|
90
|
+
const controllerTemplate = didWebvhControllerTemplate({
|
|
91
|
+
wasServerUrl,
|
|
92
|
+
spaceId
|
|
93
|
+
});
|
|
94
|
+
return createLadderAnchoredWebvhLog({
|
|
95
|
+
wasServerUrl,
|
|
96
|
+
spaceId,
|
|
97
|
+
ladderVmKeyMultibase: await ladderVmKeyMultibase({ ladderSeed }),
|
|
98
|
+
credentialKeyAgreementMethod: unlockKeyVerificationMethod({
|
|
99
|
+
did: controllerTemplate,
|
|
100
|
+
keyAgreement
|
|
101
|
+
}),
|
|
102
|
+
updateKeyPublicKeyMultibase: rung0.keyMultibase,
|
|
103
|
+
nextKeyHashes: await genesisNextKeyHashes({
|
|
104
|
+
activeKeyMultibase: rung0.keyMultibase,
|
|
105
|
+
stagedKeyMultibase: rung1.keyMultibase
|
|
106
|
+
}),
|
|
107
|
+
signer: await updateKeySigner({ seed: rung0.seed })
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* LADDER-ANCHORED GENESIS AS AN ENSURE: probe, adopt, or create-and-publish --
|
|
112
|
+
* {@link createLadderAnchoredAccountLog} with the durable-flow `ensureDidWebvh`
|
|
113
|
+
* convention wrapped around it. The convergence rule is what makes signup a
|
|
114
|
+
* ceremony rather than a bare create: `createDID` timestamps the genesis
|
|
115
|
+
* entry, so a naive re-run of a torn signup mints a DIFFERENT SCID and its
|
|
116
|
+
* create-if-absent PUT can never land. So a published log is ADOPTED instead
|
|
117
|
+
* -- iff `attributeLadderRung` attributes its update parameters to this
|
|
118
|
+
* credential's ladder (rung revealed or committed; a foreign log fails
|
|
119
|
+
* closed with `LadderAttributionError` and is never built on).
|
|
120
|
+
*
|
|
121
|
+
* The publish is a conditional create-if-absent, so a concurrent signup's
|
|
122
|
+
* winner is adopted on the conflict re-run rather than erased. On the create
|
|
123
|
+
* path a supplied `pinStore` is written from the log this run minted (the
|
|
124
|
+
* account-log trust-on-first-use convention: the creator knows the true
|
|
125
|
+
* genesis); on the probe path the read itself carries the pin check.
|
|
126
|
+
*
|
|
127
|
+
* @param options {object}
|
|
128
|
+
* @param options.idStore {WebvhIdStore}
|
|
129
|
+
* @param options.wasServerUrl {string}
|
|
130
|
+
* @param options.spaceId {string}
|
|
131
|
+
* @param options.ladderSeed {Uint8Array} the credential's ladder seed
|
|
132
|
+
* @param options.keyAgreement {UnlockKeyAgreementPublication} the
|
|
133
|
+
* credential's key-agreement publication (commitment or verbatim)
|
|
134
|
+
* @param [options.expectedDid] {string} the DID the published log must
|
|
135
|
+
* resolve to, when the caller holds the account pointer; a heal login on a
|
|
136
|
+
* fresh terminal legitimately holds none
|
|
137
|
+
* @param [options.pinStore] {ResourceLogPinStore} this client's chain-head
|
|
138
|
+
* pins; the account log's slot is keyed by `accountLogPinId` over the
|
|
139
|
+
* `spaceId` above
|
|
140
|
+
* @returns {Promise<{ did: string }>}
|
|
141
|
+
*/
|
|
142
|
+
export async function ensureLadderAnchoredDidWebvh(options) {
|
|
143
|
+
return withLogConflictRetry(() => ensureLadderAnchoredDidWebvhOnce(options));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* One attempt of {@link ensureLadderAnchoredDidWebvh}, re-invoked by the
|
|
147
|
+
* conflict retry.
|
|
148
|
+
*
|
|
149
|
+
* @param options {object} see {@link ensureLadderAnchoredDidWebvh}
|
|
150
|
+
* @returns {Promise<{ did: string }>}
|
|
151
|
+
*/
|
|
152
|
+
async function ensureLadderAnchoredDidWebvhOnce({ idStore, wasServerUrl, spaceId, ladderSeed, keyAgreement, expectedDid, pinStore }) {
|
|
153
|
+
const logId = accountLogPinId({ spaceId });
|
|
154
|
+
const published = await readPublishedLog({
|
|
155
|
+
idStore,
|
|
156
|
+
...(expectedDid !== undefined ? { expectedDid } : {}),
|
|
157
|
+
...(pinStore ? { pinStore, logId } : {})
|
|
158
|
+
});
|
|
159
|
+
if (published) {
|
|
160
|
+
// Adoption: a torn earlier signup (or a concurrent one) already published
|
|
161
|
+
// the log. Adopt it iff this credential's ladder attributes it -- the
|
|
162
|
+
// ladder-anchored analog of the durable path's "authorizes one of this
|
|
163
|
+
// client's seeds" check. The attribution accepts a revealed rung too, so
|
|
164
|
+
// an account that has since self-enrolled a durable client (retiring
|
|
165
|
+
// rung 0) still adopts here rather than hard-failing.
|
|
166
|
+
await attributeLadderRung({ ladderSeed, published });
|
|
167
|
+
// Heals a did.json left lagging by a torn earlier publish.
|
|
168
|
+
const { did } = await concludeWithPublishedLog({ idStore, published });
|
|
169
|
+
return { did };
|
|
170
|
+
}
|
|
171
|
+
const created = await createLadderAnchoredAccountLog({
|
|
172
|
+
wasServerUrl,
|
|
173
|
+
spaceId,
|
|
174
|
+
ladderSeed,
|
|
175
|
+
keyAgreement
|
|
176
|
+
});
|
|
177
|
+
await publishWebvhLog({
|
|
178
|
+
idStore,
|
|
179
|
+
log: created.log,
|
|
180
|
+
webDoc: created.webDoc,
|
|
181
|
+
// Create-if-absent: a concurrent signup that already published its own
|
|
182
|
+
// log wins, and this run re-reads and adopts (or refuses) instead of
|
|
183
|
+
// erasing it.
|
|
184
|
+
ifNoneMatch: true
|
|
185
|
+
});
|
|
186
|
+
// Trust-on-first-use, established by the creator itself: this run minted the
|
|
187
|
+
// genesis, so the pin it writes needs no served log to be believed.
|
|
188
|
+
if (pinStore) {
|
|
189
|
+
await pinStore.write({ logId, pin: pinOfLog(created.log) });
|
|
190
|
+
}
|
|
191
|
+
return { did: created.did };
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Publishes `did.jsonl` through the narrow seam -- the log only, never
|
|
195
|
+
* `did.json` (the bridge delegation covers nothing else; the enrolled session
|
|
196
|
+
* republishes the projection once it is the controller). Conditional on the
|
|
197
|
+
* read the entry was built on; a lost race surfaces as a
|
|
198
|
+
* `WebvhLogConflictError` (the mapping lives in `putLogResource`).
|
|
199
|
+
*
|
|
200
|
+
* @param options {object}
|
|
201
|
+
* @param options.store {UnlockLogStore}
|
|
202
|
+
* @param options.log {DIDLog}
|
|
203
|
+
* @param [options.ifMatch] {string} publish only if `did.jsonl` is unchanged
|
|
204
|
+
* @returns {Promise<void>}
|
|
205
|
+
*/
|
|
206
|
+
async function publishLogOnly({ store, log, ifMatch }) {
|
|
207
|
+
await putLogResource({ store, log, ifMatch });
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* SELF-ENROLLMENT (run by the credential-derived client through the delegated
|
|
211
|
+
* `did.jsonl` PUT): writes the standing continuation described in the module
|
|
212
|
+
* doc -- the reveal-and-commit entry signed by the attributed ladder rung,
|
|
213
|
+
* then the add entry signed by the new ordinary client's update key, which
|
|
214
|
+
* also retires the spent rung. Resumable from durable state alone: a
|
|
215
|
+
* completed continuation is detected by the new client's update key already
|
|
216
|
+
* being authorized (no-op), a torn one by the attribution finding the rung
|
|
217
|
+
* already revealed. Both entries publish conditionally on the read they were
|
|
218
|
+
* built on, and a race lost to a concurrent ceremony re-runs from the top --
|
|
219
|
+
* re-attributing, which is exactly the retry-up-the-ladder resolution.
|
|
220
|
+
*
|
|
221
|
+
* @param options {object}
|
|
222
|
+
* @param options.store {UnlockLogStore} public log read + delegated PUT
|
|
223
|
+
* @param options.ladderSeed {Uint8Array} the credential's ladder seed, from
|
|
224
|
+
* its unlock record
|
|
225
|
+
* @param options.newClientKeys {WebvhEnrollmentKeys} the new ordinary
|
|
226
|
+
* client's public halves
|
|
227
|
+
* @param options.newClientUpdateSeeds {ClientWebvhUpdateKeys} the new
|
|
228
|
+
* client's update-key seeds (minted by the self-enrolling flow, which
|
|
229
|
+
* therefore holds them and can sign the add entry)
|
|
230
|
+
* @param [options.expectedDid] {string} the account DID the log must resolve
|
|
231
|
+
* to, from the credential-authenticated pointer
|
|
232
|
+
* @returns {Promise<{ did: string, webDoc?: object }>} the account DID and,
|
|
233
|
+
* when the add entry ran here, the final `did.json` projection for the
|
|
234
|
+
* enrolled session to republish
|
|
235
|
+
*/
|
|
236
|
+
export async function selfEnrollWebvhClient(options) {
|
|
237
|
+
return withLogConflictRetry(() => selfEnrollWebvhClientOnce(options));
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* One attempt of {@link selfEnrollWebvhClient}, re-invoked by the conflict
|
|
241
|
+
* retry.
|
|
242
|
+
*
|
|
243
|
+
* @param options {object} see {@link selfEnrollWebvhClient}
|
|
244
|
+
* @returns {Promise<{ did: string, webDoc?: object }>}
|
|
245
|
+
*/
|
|
246
|
+
async function selfEnrollWebvhClientOnce({ store, ladderSeed, newClientKeys, newClientUpdateSeeds, expectedDid }) {
|
|
247
|
+
let published = await readLogOrThrow({
|
|
248
|
+
store,
|
|
249
|
+
...(expectedDid !== undefined ? { expectedDid } : {})
|
|
250
|
+
});
|
|
251
|
+
// Already complete (a torn earlier run finished the add entry): the new
|
|
252
|
+
// client's update key is authorized, which only the add entry writes.
|
|
253
|
+
if (published.updateKeys.includes(newClientKeys.updateKeyMultibase)) {
|
|
254
|
+
return { did: published.did };
|
|
255
|
+
}
|
|
256
|
+
// Which rung is current, recovered from the log itself. Fails closed with
|
|
257
|
+
// `LadderAttributionError` for a revoked (or never-bound) credential and
|
|
258
|
+
// for any ambiguous history.
|
|
259
|
+
const { rung, state } = await attributeLadderRung({ ladderSeed, published });
|
|
260
|
+
const nextRung = await ladderRung({ ladderSeed, index: rung.index + 1 });
|
|
261
|
+
const rungHash = await deriveNextKeyHash(rung.keyMultibase);
|
|
262
|
+
const newUpdateHash = await deriveNextKeyHash(newClientKeys.updateKeyMultibase);
|
|
263
|
+
const newStagedHash = await deriveNextKeyHash(newClientKeys.stagedUpdateKeyMultibase);
|
|
264
|
+
const nextRungHash = await deriveNextKeyHash(nextRung.keyMultibase);
|
|
265
|
+
// The reveal-and-commit entry, skipped when a torn earlier run already
|
|
266
|
+
// published it (the rung revealed AND every needed hash committed).
|
|
267
|
+
const revealed = state === 'revealed';
|
|
268
|
+
const committed = [newUpdateHash, newStagedHash, nextRungHash].every(hash => published.nextKeyHashes.includes(hash));
|
|
269
|
+
if (!revealed || !committed) {
|
|
270
|
+
await assertCarryOverCommitments({ published });
|
|
271
|
+
const signer = await updateKeySigner({ seed: rung.seed });
|
|
272
|
+
const updated = await updateDID({
|
|
273
|
+
log: published.log,
|
|
274
|
+
signer,
|
|
275
|
+
alsoKnownAsWeb: true,
|
|
276
|
+
updateKeys: [...new Set([...published.updateKeys, rung.keyMultibase])],
|
|
277
|
+
// The spent rung's own hash is kept through this entry (so a resumed
|
|
278
|
+
// commit can re-state the revealed key); the add entry drops it, while
|
|
279
|
+
// the next rung's hash stays as the credential's standing commitment.
|
|
280
|
+
nextKeyHashes: [
|
|
281
|
+
...new Set([
|
|
282
|
+
...published.nextKeyHashes,
|
|
283
|
+
rungHash,
|
|
284
|
+
newUpdateHash,
|
|
285
|
+
newStagedHash,
|
|
286
|
+
nextRungHash
|
|
287
|
+
])
|
|
288
|
+
]
|
|
289
|
+
});
|
|
290
|
+
await publishLogOnly({ store, log: updated.log, ifMatch: published.etag });
|
|
291
|
+
// The same account the reveal entry just extended.
|
|
292
|
+
published = await readLogOrThrow({ store, expectedDid: published.did });
|
|
293
|
+
}
|
|
294
|
+
// The add entry: the new client's verification methods and update key in;
|
|
295
|
+
// the spent rung's key and hash out. The credential's keyAgreement entry
|
|
296
|
+
// and the next rung's committed hash stand untouched. Signed by the new
|
|
297
|
+
// client's update key, whose hash the commit entry just committed.
|
|
298
|
+
const { did, doc } = published;
|
|
299
|
+
const vmId = (publicKeyMultibase) => `${did}#${publicKeyMultibase}`;
|
|
300
|
+
// When this is the FIRST durable enrollment of a ladder-anchored account, the
|
|
301
|
+
// same atomic entry ends the ladder-anchored window: every ladder VM (the
|
|
302
|
+
// relation-asymmetry recognition) leaves the document and its relations
|
|
303
|
+
// here, so no window exists where the account has neither a durable client
|
|
304
|
+
// nor the ladder VM. On an account with enrolled clients the recognition
|
|
305
|
+
// finds none and the filters are no-ops.
|
|
306
|
+
const ladderVms = ladderVmIds({ doc });
|
|
307
|
+
const addedMethods = markedVerificationMethodPair({
|
|
308
|
+
controller: did,
|
|
309
|
+
signingKeyMultibase: newClientKeys.signingKeyMultibase,
|
|
310
|
+
keyAgreementKeyMultibase: newClientKeys.keyAgreementKeyMultibase
|
|
311
|
+
});
|
|
312
|
+
const existingMethods = (doc.verificationMethod ?? []);
|
|
313
|
+
const verificationMethods = [
|
|
314
|
+
...existingMethods.filter(method => !addedMethods.some(added => added.id === method.id) &&
|
|
315
|
+
(method.id === undefined || !ladderVms.includes(method.id))),
|
|
316
|
+
...addedMethods
|
|
317
|
+
];
|
|
318
|
+
const withReference = (relation, id) => [...new Set([...relationIds(relation), id])].filter(referencedId => !ladderVms.includes(referencedId));
|
|
319
|
+
const signingVmId = vmId(newClientKeys.signingKeyMultibase);
|
|
320
|
+
const signer = await updateKeySigner({
|
|
321
|
+
seed: newClientUpdateSeeds.updateSeed
|
|
322
|
+
});
|
|
323
|
+
const updated = await updateDID({
|
|
324
|
+
log: published.log,
|
|
325
|
+
signer,
|
|
326
|
+
alsoKnownAsWeb: true,
|
|
327
|
+
updateKeys: [
|
|
328
|
+
...new Set([
|
|
329
|
+
...published.updateKeys.filter(key => key !== rung.keyMultibase),
|
|
330
|
+
newClientKeys.updateKeyMultibase
|
|
331
|
+
])
|
|
332
|
+
],
|
|
333
|
+
nextKeyHashes: published.nextKeyHashes.filter(hash => hash !== rungHash),
|
|
334
|
+
verificationMethods,
|
|
335
|
+
authentication: withReference(doc.authentication, signingVmId),
|
|
336
|
+
assertionMethod: withReference(doc.assertionMethod, signingVmId),
|
|
337
|
+
keyAgreement: withReference(doc.keyAgreement, vmId(newClientKeys.keyAgreementKeyMultibase)),
|
|
338
|
+
capabilityInvocation: withReference(doc.capabilityInvocation, signingVmId),
|
|
339
|
+
capabilityDelegation: withReference(doc.capabilityDelegation, signingVmId)
|
|
340
|
+
});
|
|
341
|
+
// Conditional on the read this entry was built on: the re-read above when
|
|
342
|
+
// the commit entry ran here, the first read when it was skipped.
|
|
343
|
+
await publishLogOnly({ store, log: updated.log, ifMatch: published.etag });
|
|
344
|
+
return { did: updated.did, webDoc: updated.webDoc };
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Thrown when the client being forgotten is the account's LAST enrolled
|
|
348
|
+
* durable client. Removing it through this entry would leave the document
|
|
349
|
+
* with no client and no ladder verification method -- an account nothing can
|
|
350
|
+
* invoke for -- so that case is its own ceremony (the two-entry
|
|
351
|
+
* ladder-VM-install shape), and this primitive refuses rather than
|
|
352
|
+
* transitioning the account by accident.
|
|
353
|
+
*
|
|
354
|
+
* **`name` is a stable contract.** It is always the string
|
|
355
|
+
* `'LastDurableClientForgetError'`, and a consumer should match on that
|
|
356
|
+
* rather than on `instanceof`: a wallet app that links this package (or holds
|
|
357
|
+
* two copies of it through a dependency tree) gets a different class object
|
|
358
|
+
* for the same error, so `instanceof` silently fails there while the name
|
|
359
|
+
* does not.
|
|
360
|
+
*/
|
|
361
|
+
export class LastDurableClientForgetError extends Error {
|
|
362
|
+
constructor() {
|
|
363
|
+
super('did:webvh: the client being forgotten is the last enrolled durable ' +
|
|
364
|
+
'client; forgetting it takes the ladder-anchored transition ceremony, ' +
|
|
365
|
+
'not the plain removal entry.');
|
|
366
|
+
this.name = 'LastDurableClientForgetError';
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* FORGET (run by the forgetting client itself, through the standing
|
|
371
|
+
* credential's bridge): removes THIS browser's enrolled client from the
|
|
372
|
+
* published document in ONE atomic ladder-signed entry -- self-enrollment in
|
|
373
|
+
* reverse, collapsed to a single entry because a removal reveals no new key.
|
|
374
|
+
* The signer is the credential's current ladder rung, recovered from the log
|
|
375
|
+
* itself ({@link attributeLadderRung}): its hash stands committed by the
|
|
376
|
+
* credential's posture (or the rung is already revealed), which is exactly
|
|
377
|
+
* what lets it reveal itself in the entry it signs under prerotation. The
|
|
378
|
+
* entry's members are the revocation removal's, verbatim
|
|
379
|
+
* (`clientRemovalTarget` / `clientRemovalFields`, shared with
|
|
380
|
+
* `revokeWebvhClient` so the two removal shapes cannot drift): the client's
|
|
381
|
+
* verification methods out of the document and all five relations, its update
|
|
382
|
+
* key out of `updateKeys`, and its carry-over and staged hashes out of
|
|
383
|
+
* `nextKeyHashes` -- plus the acting rung into `updateKeys` with its own hash
|
|
384
|
+
* kept committed (the carry-over convention).
|
|
385
|
+
*
|
|
386
|
+
* Atomicity is the point of the one-entry shape: no torn state exists where
|
|
387
|
+
* the rung is revealed and the client still stands. The honest residue is the
|
|
388
|
+
* acting rung itself -- no entry can remove its own signing key, so the rung
|
|
389
|
+
* stands REVEALED in `updateKeys` afterwards (the same standing state the
|
|
390
|
+
* ladder-anchored postures live in). That is credential-held authority, not
|
|
391
|
+
* the forgotten client's: only the ladder seed derives it, the credential's
|
|
392
|
+
* next self-enrollment consumes and retires it, and retiring the credential
|
|
393
|
+
* itself strikes it (`attributeLadderPosture`).
|
|
394
|
+
*
|
|
395
|
+
* Forgetting the LAST enrolled durable client is refused
|
|
396
|
+
* ({@link LastDurableClientForgetError}): that transition -- to the
|
|
397
|
+
* client-less, ladder-anchored state -- is its own two-entry ceremony.
|
|
398
|
+
*
|
|
399
|
+
* Idempotent: a client with no remaining presence is a no-op that returns the
|
|
400
|
+
* published state unchanged, so a naive re-run after a torn ceremony
|
|
401
|
+
* converges. The entry publishes conditionally on the log this call read; a
|
|
402
|
+
* lost race re-runs, re-attributes, and rebases on the winner's head.
|
|
403
|
+
*
|
|
404
|
+
* @param options {object}
|
|
405
|
+
* @param options.store {UnlockLogStore} the credential's delegated
|
|
406
|
+
* `did.jsonl` bridge store
|
|
407
|
+
* @param options.ladderSeed {Uint8Array} the credential's ladder seed
|
|
408
|
+
* @param options.forgottenClient {RevokedClientKeys} this client's public
|
|
409
|
+
* halves; an `updateKeyMultibase` the log does not authorize (stale, or the
|
|
410
|
+
* staged key) is re-derived from the log
|
|
411
|
+
* @param [options.knownLatentHashes] {string[]} standing latent commitments
|
|
412
|
+
* the caller vouches for (the recovery registry's update-key hashes),
|
|
413
|
+
* excluded from the staged-hash attribution
|
|
414
|
+
* @param [options.expectedDid] {string} the account DID the log must resolve
|
|
415
|
+
* to, from the caller's stored account pointer
|
|
416
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>} the account
|
|
417
|
+
* DID and the document and log as the removal entry leaves them (unchanged
|
|
418
|
+
* on the idempotent no-op path)
|
|
419
|
+
*/
|
|
420
|
+
export async function forgetWebvhClient(options) {
|
|
421
|
+
return withLogConflictRetry(() => clientForgetEntryOnce({ ...options, transition: false }));
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* THE LAST-CLIENT REMOVAL ENTRY (the two-entry transition ceremony's second
|
|
425
|
+
* entry): {@link forgetWebvhClient}'s removal shape with the last-client
|
|
426
|
+
* refusal inverted -- the forgotten client IS the last enrolled durable
|
|
427
|
+
* client, and the account stays invocable because the ladder VM the install
|
|
428
|
+
* entry published ({@link installLadderVmWebvh}) remains in the document. A
|
|
429
|
+
* document NOT carrying this credential's ladder VM refuses: publishing the
|
|
430
|
+
* entry would strand the account with neither a durable client nor the
|
|
431
|
+
* ladder anchor. Run only from the composed ceremony
|
|
432
|
+
* (`forgetLastDurableClient`), which sequences the install entry and the
|
|
433
|
+
* delegation revocations before it.
|
|
434
|
+
*
|
|
435
|
+
* @param options {object} see {@link forgetWebvhClient}
|
|
436
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>}
|
|
437
|
+
*/
|
|
438
|
+
export async function forgetLastWebvhClient(options) {
|
|
439
|
+
return withLogConflictRetry(() => clientForgetEntryOnce({ ...options, transition: true }));
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* One attempt of {@link forgetWebvhClient} or {@link forgetLastWebvhClient},
|
|
443
|
+
* re-invoked by the conflict retry. The two share everything but the guard:
|
|
444
|
+
* the plain forget refuses the last durable client, the transition removal
|
|
445
|
+
* requires the ladder VM already installed instead.
|
|
446
|
+
*
|
|
447
|
+
* @param options {object} see {@link forgetWebvhClient}, plus:
|
|
448
|
+
* @param options.transition {boolean} `true` for the last-client removal
|
|
449
|
+
* entry (require the installed ladder VM), `false` for the plain forget
|
|
450
|
+
* (refuse the last client)
|
|
451
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog }>}
|
|
452
|
+
*/
|
|
453
|
+
async function clientForgetEntryOnce({ store, ladderSeed, forgottenClient, knownLatentHashes = [], expectedDid, transition }) {
|
|
454
|
+
const published = await readLogOrThrow({
|
|
455
|
+
store,
|
|
456
|
+
...(expectedDid !== undefined ? { expectedDid } : {})
|
|
457
|
+
});
|
|
458
|
+
const { did, doc } = published;
|
|
459
|
+
const target = await clientRemovalTarget({
|
|
460
|
+
published,
|
|
461
|
+
client: forgottenClient
|
|
462
|
+
});
|
|
463
|
+
if (!target.present) {
|
|
464
|
+
// Already forgotten (a torn earlier run finished the entry). No did.json
|
|
465
|
+
// heal here: the bridge covers did.jsonl only.
|
|
466
|
+
return { did, doc, log: published.log };
|
|
467
|
+
}
|
|
468
|
+
if (transition) {
|
|
469
|
+
// The no-neither invariant, checked rather than assumed: the removal may
|
|
470
|
+
// only publish while the ladder VM stands in the document (the install
|
|
471
|
+
// entry ran), or the account would land with nothing that can anchor it.
|
|
472
|
+
const ladderVmId = `${did}#${await ladderVmKeyMultibase({ ladderSeed })}`;
|
|
473
|
+
if (!ladderVmIds({ doc }).includes(ladderVmId)) {
|
|
474
|
+
throw new Error('did:webvh: the ladder VM is not installed in the document; the ' +
|
|
475
|
+
'last-client removal entry would strand the account (the install ' +
|
|
476
|
+
'entry runs first).');
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
// The last-client refusal: capabilityInvocation lists exactly the
|
|
481
|
+
// enrolled clients' signing keys (a recovery code's key is
|
|
482
|
+
// keyAgreement-only and the KMS convenience authentication-only), so the
|
|
483
|
+
// forgotten client standing alone there means removing it strands the
|
|
484
|
+
// account.
|
|
485
|
+
const invocationIds = relationIds(doc.capabilityInvocation);
|
|
486
|
+
if (invocationIds.includes(target.signingVmId) &&
|
|
487
|
+
invocationIds.every(id => id === target.signingVmId)) {
|
|
488
|
+
throw new LastDurableClientForgetError();
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// Which rung is current, recovered from the log itself. Fails closed with
|
|
492
|
+
// `LadderAttributionError` for a revoked (or never-bound) credential and
|
|
493
|
+
// for any ambiguous history.
|
|
494
|
+
const { rung } = await attributeLadderRung({ ladderSeed, published });
|
|
495
|
+
const rungHash = await deriveNextKeyHash(rung.keyMultibase);
|
|
496
|
+
await assertCarryOverCommitments({ published });
|
|
497
|
+
// The ladder vouches for its own commitments: a self-enrolled client's
|
|
498
|
+
// staged hash was committed in the same reveal entry as the next rung's
|
|
499
|
+
// hash, so without these the staged-hash attribution cannot tell the two
|
|
500
|
+
// apart. Every hash a reveal entry can have committed is for a rung at or
|
|
501
|
+
// one past the current index.
|
|
502
|
+
const ladderHashes = [];
|
|
503
|
+
for (let index = 0; index <= rung.index + 1; index++) {
|
|
504
|
+
const laddered = await ladderRung({ ladderSeed, index });
|
|
505
|
+
ladderHashes.push(await deriveNextKeyHash(laddered.keyMultibase));
|
|
506
|
+
}
|
|
507
|
+
const fields = await clientRemovalFields({
|
|
508
|
+
published,
|
|
509
|
+
target,
|
|
510
|
+
knownLatentHashes: [...knownLatentHashes, ...ladderHashes]
|
|
511
|
+
});
|
|
512
|
+
const signer = await updateKeySigner({ seed: rung.seed });
|
|
513
|
+
const updated = await updateDID({
|
|
514
|
+
log: published.log,
|
|
515
|
+
signer,
|
|
516
|
+
alsoKnownAsWeb: true,
|
|
517
|
+
...fields,
|
|
518
|
+
// The acting rung reveals itself in the entry it signs (its hash stands
|
|
519
|
+
// committed, or the rung is already revealed), and its own hash is kept
|
|
520
|
+
// committed so the carry-over convention holds for the next entry.
|
|
521
|
+
updateKeys: [...new Set([...fields.updateKeys, rung.keyMultibase])],
|
|
522
|
+
nextKeyHashes: [...new Set([...fields.nextKeyHashes, rungHash])]
|
|
523
|
+
});
|
|
524
|
+
await publishLogOnly({ store, log: updated.log, ifMatch: published.etag });
|
|
525
|
+
return { did: updated.did, doc: updated.doc, log: updated.log };
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* THE LADDER-VM INSTALL ENTRY (the two-entry transition ceremony's first
|
|
529
|
+
* entry): publishes the credential's ladder VM -- the stable sibling, under
|
|
530
|
+
* `assertionMethod` and `capabilityDelegation` only -- while the last durable
|
|
531
|
+
* client's whole footprint stays untouched: the both-present transitional
|
|
532
|
+
* state the no-neither invariant permits. The entry is ladder-signed by the
|
|
533
|
+
* attributed rung, which reveals itself into `updateKeys` with its own hash
|
|
534
|
+
* kept committed (the carry-over convention), exactly the removal entry's
|
|
535
|
+
* rung math -- so a torn ceremony's re-run re-attributes the now-revealed
|
|
536
|
+
* rung and carries on.
|
|
537
|
+
*
|
|
538
|
+
* This entry is what makes the transition's document version POSTURE-CHANGING
|
|
539
|
+
* under the ceremony-tail license (the ladder-VM set gains a member), so the
|
|
540
|
+
* ceremony's ONE ladder-signed roster append anchors here -- and it is what
|
|
541
|
+
* lets the delegation revocations that follow verify their ladder-signed
|
|
542
|
+
* chains against the currently resolved document while the still-standing
|
|
543
|
+
* client signs the invocations.
|
|
544
|
+
*
|
|
545
|
+
* Idempotent: a document already carrying this credential's ladder VM (by
|
|
546
|
+
* the relation-asymmetry recognition) returns unchanged with
|
|
547
|
+
* `installed: false`. The entry publishes conditionally on the log this call
|
|
548
|
+
* read; a lost race re-runs, re-attributes, and rebases on the winner's
|
|
549
|
+
* head.
|
|
550
|
+
*
|
|
551
|
+
* @param options {object}
|
|
552
|
+
* @param options.store {UnlockLogStore} the credential's delegated
|
|
553
|
+
* `did.jsonl` bridge store
|
|
554
|
+
* @param options.ladderSeed {Uint8Array} the credential's ladder seed
|
|
555
|
+
* @param [options.expectedDid] {string} the account DID the log must resolve
|
|
556
|
+
* to, from the caller's stored account pointer
|
|
557
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog, installed: boolean }>}
|
|
558
|
+
* the account DID and the document and log as the install entry leaves them
|
|
559
|
+
* (unchanged on the idempotent no-op path); `installed` says whether the
|
|
560
|
+
* entry ran on this call
|
|
561
|
+
*/
|
|
562
|
+
export async function installLadderVmWebvh(options) {
|
|
563
|
+
return withLogConflictRetry(() => installLadderVmWebvhOnce(options));
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* One attempt of {@link installLadderVmWebvh}, re-invoked by the conflict
|
|
567
|
+
* retry.
|
|
568
|
+
*
|
|
569
|
+
* @param options {object} see {@link installLadderVmWebvh}
|
|
570
|
+
* @returns {Promise<{ did: string, doc: DIDDoc, log: DIDLog, installed: boolean }>}
|
|
571
|
+
*/
|
|
572
|
+
async function installLadderVmWebvhOnce({ store, ladderSeed, expectedDid }) {
|
|
573
|
+
const published = await readLogOrThrow({
|
|
574
|
+
store,
|
|
575
|
+
...(expectedDid !== undefined ? { expectedDid } : {})
|
|
576
|
+
});
|
|
577
|
+
const { did, doc } = published;
|
|
578
|
+
const ladderVmKey = await ladderVmKeyMultibase({ ladderSeed });
|
|
579
|
+
const ladderVmId = `${did}#${ladderVmKey}`;
|
|
580
|
+
if (ladderVmIds({ doc }).includes(ladderVmId)) {
|
|
581
|
+
// Already installed (a torn earlier run published the entry, or the
|
|
582
|
+
// account is mid-transition).
|
|
583
|
+
return { did, doc, log: published.log, installed: false };
|
|
584
|
+
}
|
|
585
|
+
// Which rung is current, recovered from the log itself. Fails closed with
|
|
586
|
+
// `LadderAttributionError` for a revoked (or never-bound) credential and
|
|
587
|
+
// for any ambiguous history.
|
|
588
|
+
const { rung } = await attributeLadderRung({ ladderSeed, published });
|
|
589
|
+
const rungHash = await deriveNextKeyHash(rung.keyMultibase);
|
|
590
|
+
await assertCarryOverCommitments({ published });
|
|
591
|
+
const existingMethods = (doc.verificationMethod ?? []);
|
|
592
|
+
const verificationMethods = [
|
|
593
|
+
...existingMethods.filter(method => method.id !== ladderVmId),
|
|
594
|
+
ladderVerificationMethod({
|
|
595
|
+
controller: did,
|
|
596
|
+
publicKeyMultibase: ladderVmKey
|
|
597
|
+
})
|
|
598
|
+
];
|
|
599
|
+
// The ladder VM's relation asymmetry: `assertionMethod` and
|
|
600
|
+
// `capabilityDelegation` only -- no `authentication`, no
|
|
601
|
+
// `capabilityInvocation` -- which is also what keeps it out of every client
|
|
602
|
+
// listing.
|
|
603
|
+
const withVm = (relation) => [
|
|
604
|
+
...new Set([...relationIds(relation), ladderVmId])
|
|
605
|
+
];
|
|
606
|
+
const signer = await updateKeySigner({ seed: rung.seed });
|
|
607
|
+
const updated = await updateDID({
|
|
608
|
+
log: published.log,
|
|
609
|
+
signer,
|
|
610
|
+
alsoKnownAsWeb: true,
|
|
611
|
+
// The acting rung reveals itself in the entry it signs (its hash stands
|
|
612
|
+
// committed, or the rung is already revealed), and its own hash is kept
|
|
613
|
+
// committed so the carry-over convention holds for the next entry.
|
|
614
|
+
updateKeys: [...new Set([...published.updateKeys, rung.keyMultibase])],
|
|
615
|
+
nextKeyHashes: [...new Set([...published.nextKeyHashes, rungHash])],
|
|
616
|
+
verificationMethods,
|
|
617
|
+
authentication: relationIds(doc.authentication),
|
|
618
|
+
assertionMethod: withVm(doc.assertionMethod),
|
|
619
|
+
keyAgreement: relationIds(doc.keyAgreement),
|
|
620
|
+
capabilityInvocation: relationIds(doc.capabilityInvocation),
|
|
621
|
+
capabilityDelegation: withVm(doc.capabilityDelegation)
|
|
622
|
+
});
|
|
623
|
+
await publishLogOnly({ store, log: updated.log, ifMatch: published.etag });
|
|
624
|
+
return {
|
|
625
|
+
did: updated.did,
|
|
626
|
+
doc: updated.doc,
|
|
627
|
+
log: updated.log,
|
|
628
|
+
installed: true
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
//# sourceMappingURL=ladderAnchored.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ladderAnchored.js","sourceRoot":"","sources":["../../src/clientAnnex/ladderAnchored.ts"],"names":[],"mappings":"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"}
|