@interop/wallet-core 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/index.d.ts +7 -4
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +7 -4
  4. package/dist/index.js.map +1 -1
  5. package/dist/markers/acquire.d.ts +107 -0
  6. package/dist/markers/acquire.d.ts.map +1 -0
  7. package/dist/markers/acquire.js +83 -0
  8. package/dist/markers/acquire.js.map +1 -0
  9. package/dist/markers/cipher.d.ts +56 -0
  10. package/dist/markers/cipher.d.ts.map +1 -0
  11. package/dist/markers/cipher.js +73 -0
  12. package/dist/markers/cipher.js.map +1 -0
  13. package/dist/markers/index.d.ts +30 -0
  14. package/dist/markers/index.d.ts.map +1 -0
  15. package/dist/markers/index.js +29 -0
  16. package/dist/markers/index.js.map +1 -0
  17. package/dist/markers/refresh.d.ts +60 -0
  18. package/dist/markers/refresh.d.ts.map +1 -0
  19. package/dist/markers/refresh.js +67 -0
  20. package/dist/markers/refresh.js.map +1 -0
  21. package/dist/recovery/index.d.ts +31 -0
  22. package/dist/recovery/index.d.ts.map +1 -0
  23. package/dist/recovery/index.js +28 -0
  24. package/dist/recovery/index.js.map +1 -0
  25. package/dist/recovery/recoveryCode.d.ts +105 -0
  26. package/dist/recovery/recoveryCode.d.ts.map +1 -0
  27. package/dist/recovery/recoveryCode.js +155 -0
  28. package/dist/recovery/recoveryCode.js.map +1 -0
  29. package/dist/recovery/recoveryRecord.d.ts +75 -0
  30. package/dist/recovery/recoveryRecord.d.ts.map +1 -0
  31. package/dist/recovery/recoveryRecord.js +89 -0
  32. package/dist/recovery/recoveryRecord.js.map +1 -0
  33. package/dist/recovery/recoveryWebvh.d.ts +126 -0
  34. package/dist/recovery/recoveryWebvh.d.ts.map +1 -0
  35. package/dist/recovery/recoveryWebvh.js +379 -0
  36. package/dist/recovery/recoveryWebvh.js.map +1 -0
  37. package/dist/webvh/didWebvh.d.ts +79 -0
  38. package/dist/webvh/didWebvh.d.ts.map +1 -1
  39. package/dist/webvh/didWebvh.js +5 -5
  40. package/dist/webvh/didWebvh.js.map +1 -1
  41. package/package.json +13 -1
@@ -0,0 +1,28 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/wallet-core/recovery` subpath: recovery codes on the roster
6
+ * identity model -- a code as a minimal always-enrolled wallet client.
7
+ *
8
+ * - `generateRecoveryCode` / `formatRecoveryCode` / `normalizeRecoveryCode` /
9
+ * `decodeRecoveryCode` / `RECOVERY_KDF` -- the format layer and the code's
10
+ * own unlock-derivation parameter set (its salt distinct from every other
11
+ * unlock method's).
12
+ * - `recoveryClientFromCode` -- the deterministic client key set:
13
+ * unlock identity, client seed (signing + key-agreement pair), and the
14
+ * single did:webvh update key whose hash stands pre-committed.
15
+ * - `wrapRecoveryRecord` / `unwrapRecoveryRecord` -- the keyring-record
16
+ * sibling carrying the account pointer plus the pre-minted
17
+ * PUT-on-`did.jsonl` delegation (never a seed, never a PUK wrap).
18
+ * - `publishRecoveryKey` / `removeRecoveryKey` / `recoverWebvhClient` -- the
19
+ * document half: issuance's split posture, revocation's removal, and the
20
+ * self-enrolling recovery continuation.
21
+ *
22
+ * Kept out of the root export: this subpath pulls the webkms-client / ezcap /
23
+ * was-client dependency graph (the same isolation pattern as `./keyring`).
24
+ */
25
+ export { decodeRecoveryCode, formatRecoveryCode, generateRecoveryCode, normalizeRecoveryCode, RECOVERY_CODE_BYTES, RECOVERY_KDF, RecoveryCodeInvalidError, recoveryClientFromCode } from './recoveryCode.js';
26
+ export { unwrapRecoveryRecord, wrapRecoveryRecord } from './recoveryRecord.js';
27
+ export { publishRecoveryKey, recoverWebvhClient, RecoveryKeyNotCommittedError, recoveryVmId, removeRecoveryKey } from './recoveryWebvh.js';
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recovery/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAG9E,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,4BAA4B,EAC5B,YAAY,EACZ,iBAAiB,EAClB,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,105 @@
1
+ import type { ProfileAgents } from '../identity/agents.js';
2
+ import type { UnlockKdf } from '../keyring/kdf.js';
3
+ /**
4
+ * The byte length of a recovery code: 16 random bytes is ~128 bits, enough
5
+ * that the unlock derivation is a single expansion rather than a stretched
6
+ * KDF (there is nothing to stretch -- the code is already uniform).
7
+ */
8
+ export declare const RECOVERY_CODE_BYTES = 16;
9
+ /**
10
+ * HKDF parameters for the recovery-code unlock derivation
11
+ * (`unlockSeed = HKDF(codeBytes)`). The salt differs from every other unlock
12
+ * method's salt, so a code and a passphrase that stringify alike can never
13
+ * derive the same unlock Space; as with the other unlock KDFs, `version` pins
14
+ * the parameter set and the salt is permanent.
15
+ */
16
+ export declare const RECOVERY_KDF: UnlockKdf;
17
+ /**
18
+ * Thrown for text that is not a well-formed recovery code (characters outside
19
+ * the base58 alphabet, or the wrong decoded length). Deliberately distinct
20
+ * from "no account found for this code" -- a malformed code was mistyped; a
21
+ * well-formed code that resolves to nothing was never issued or has been
22
+ * revoked.
23
+ */
24
+ export declare class RecoveryCodeInvalidError extends Error {
25
+ constructor(message?: string);
26
+ }
27
+ /**
28
+ * Generates a fresh recovery code: 16 random bytes, base58-encoded.
29
+ *
30
+ * @returns {string}
31
+ */
32
+ export declare function generateRecoveryCode(): string;
33
+ /**
34
+ * Renders a recovery code in dash-separated groups of four for display
35
+ * ("6yCL-Ho5s-..."). Purely cosmetic; `normalizeRecoveryCode` strips the
36
+ * grouping back out on entry.
37
+ *
38
+ * @param options {object}
39
+ * @param options.code {string}
40
+ * @returns {string}
41
+ */
42
+ export declare function formatRecoveryCode({ code }: {
43
+ code: string;
44
+ }): string;
45
+ /**
46
+ * Normalizes user-entered recovery code text: strips whitespace and the
47
+ * display dashes. Base58 is case-sensitive, so casing is preserved.
48
+ *
49
+ * @param options {object}
50
+ * @param options.input {string}
51
+ * @returns {string}
52
+ */
53
+ export declare function normalizeRecoveryCode({ input }: {
54
+ input: string;
55
+ }): string;
56
+ /**
57
+ * Decodes a (possibly formatted) recovery code back to its 16 bytes,
58
+ * throwing `RecoveryCodeInvalidError` on anything malformed.
59
+ *
60
+ * @param options {object}
61
+ * @param options.code {string} the user-entered code (grouping tolerated)
62
+ * @returns {Uint8Array}
63
+ */
64
+ export declare function decodeRecoveryCode({ code }: {
65
+ code: string;
66
+ }): Uint8Array;
67
+ /**
68
+ * The code's full client identity, derived deterministically from
69
+ * its bytes: the 32-byte client seed (behind the code's Ed25519 signing pair
70
+ * and X25519 key-agreement twin), the single did:webvh update-key seed (one
71
+ * key, no staged pair -- a code is spent on use, so it never self-rotates;
72
+ * its recovery continuation commits whatever it needs next), the derived
73
+ * agents, and the public multibases / ids the issuance and recovery flows
74
+ * publish and look up.
75
+ */
76
+ export interface RecoveryClient {
77
+ codeBytes: Uint8Array;
78
+ clientSeed: Uint8Array;
79
+ updateSeed: Uint8Array;
80
+ agents: ProfileAgents;
81
+ clientDid: string;
82
+ signingKeyMultibase: string;
83
+ keyAgreementKeyMultibase: string;
84
+ updateKeyMultibase: string;
85
+ /**
86
+ * The kid of the code's PUK-roster entry -- its key-agreement key's id
87
+ * exactly as `agentsFromSeed` derives it (`did:key:<ed>#<x>`), so the wrap
88
+ * minted at issuance is the one the recovery flow's roster read looks for.
89
+ */
90
+ recipientKid: string;
91
+ }
92
+ /**
93
+ * Derives the code's whole client identity from a (possibly formatted) code.
94
+ * Deterministic: the same code always yields the same key set. Throws
95
+ * `RecoveryCodeInvalidError` on malformed text; whether the derived identity
96
+ * actually unlocks anything is the caller's question.
97
+ *
98
+ * @param options {object}
99
+ * @param options.code {string} the recovery code (grouping tolerated)
100
+ * @returns {Promise<RecoveryClient>}
101
+ */
102
+ export declare function recoveryClientFromCode({ code }: {
103
+ code: string;
104
+ }): Promise<RecoveryClient>;
105
+ //# sourceMappingURL=recoveryCode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recoveryCode.d.ts","sourceRoot":"","sources":["../../src/recovery/recoveryCode.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAGlD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,SAM1B,CAAA;AAWD;;;;;;GAMG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,SAAuC;CAI3D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAErE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE1E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAazE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,UAAU,CAAA;IACrB,UAAU,EAAE,UAAU,CAAA;IACtB,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,aAAa,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,wBAAwB,EAAE,MAAM,CAAA;IAChC,kBAAkB,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,IAAI,EACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,cAAc,CAAC,CAmC1B"}
@@ -0,0 +1,155 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The recovery-code format layer and its deterministic derivations. A recovery
6
+ * code is 16 random bytes rendered as base58 (Bitcoin alphabet), shown to the
7
+ * user exactly once at issuance. Under the roster identity model the code is a
8
+ * **minimal always-enrolled wallet client**: everything the code needs to
9
+ * act -- the unlock identity that locates its keyring record, the client
10
+ * key set behind its `keyAgreement` verification method and PUK-roster wrap,
11
+ * and the did:webvh update key whose hash stands pre-committed in
12
+ * `nextKeyHashes` -- derives deterministically from the code's bytes, so the
13
+ * key material exists nowhere until the code is typed.
14
+ *
15
+ * The derivations are wire-level: two wallet apps must produce byte-identical
16
+ * output for the same code, or a code issued in one could not recover in the
17
+ * other. Every salt below is therefore permanent -- changing one orphans every
18
+ * issued code.
19
+ */
20
+ import { base58 } from '@scure/base';
21
+ import { hkdf } from '@noble/hashes/hkdf.js';
22
+ import { sha256 } from '@noble/hashes/sha2.js';
23
+ import { agentsFromSeed } from '../identity/agents.js';
24
+ import { updateKeyMultibase } from '../webvh/didWebvh.js';
25
+ /**
26
+ * The byte length of a recovery code: 16 random bytes is ~128 bits, enough
27
+ * that the unlock derivation is a single expansion rather than a stretched
28
+ * KDF (there is nothing to stretch -- the code is already uniform).
29
+ */
30
+ export const RECOVERY_CODE_BYTES = 16;
31
+ /**
32
+ * HKDF parameters for the recovery-code unlock derivation
33
+ * (`unlockSeed = HKDF(codeBytes)`). The salt differs from every other unlock
34
+ * method's salt, so a code and a passphrase that stringify alike can never
35
+ * derive the same unlock Space; as with the other unlock KDFs, `version` pins
36
+ * the parameter set and the salt is permanent.
37
+ */
38
+ export const RECOVERY_KDF = {
39
+ version: 1,
40
+ algorithm: 'HKDF',
41
+ hash: 'SHA-256',
42
+ salt: 'freewallet/keyring/recovery-code/v1',
43
+ info: 'freewallet/unlock-seed'
44
+ };
45
+ /**
46
+ * The HKDF salt for the code's client-side key set (distinct from the unlock
47
+ * salt above, so the unlock identity and the client identity can never
48
+ * collide), and the per-key expansion labels. All permanent.
49
+ */
50
+ const RECOVERY_CLIENT_SALT = 'freewallet/recovery/client-keys/v1';
51
+ const RECOVERY_CLIENT_SEED_INFO = 'client-seed';
52
+ const RECOVERY_UPDATE_SEED_INFO = 'update-key';
53
+ /**
54
+ * Thrown for text that is not a well-formed recovery code (characters outside
55
+ * the base58 alphabet, or the wrong decoded length). Deliberately distinct
56
+ * from "no account found for this code" -- a malformed code was mistyped; a
57
+ * well-formed code that resolves to nothing was never issued or has been
58
+ * revoked.
59
+ */
60
+ export class RecoveryCodeInvalidError extends Error {
61
+ constructor(message = 'This is not a valid recovery code.') {
62
+ super(message);
63
+ this.name = 'RecoveryCodeInvalidError';
64
+ }
65
+ }
66
+ /**
67
+ * Generates a fresh recovery code: 16 random bytes, base58-encoded.
68
+ *
69
+ * @returns {string}
70
+ */
71
+ export function generateRecoveryCode() {
72
+ const bytes = new Uint8Array(RECOVERY_CODE_BYTES);
73
+ crypto.getRandomValues(bytes);
74
+ return base58.encode(bytes);
75
+ }
76
+ /**
77
+ * Renders a recovery code in dash-separated groups of four for display
78
+ * ("6yCL-Ho5s-..."). Purely cosmetic; `normalizeRecoveryCode` strips the
79
+ * grouping back out on entry.
80
+ *
81
+ * @param options {object}
82
+ * @param options.code {string}
83
+ * @returns {string}
84
+ */
85
+ export function formatRecoveryCode({ code }) {
86
+ return code.replace(/(.{4})(?=.)/g, '$1-');
87
+ }
88
+ /**
89
+ * Normalizes user-entered recovery code text: strips whitespace and the
90
+ * display dashes. Base58 is case-sensitive, so casing is preserved.
91
+ *
92
+ * @param options {object}
93
+ * @param options.input {string}
94
+ * @returns {string}
95
+ */
96
+ export function normalizeRecoveryCode({ input }) {
97
+ return input.replace(/[\s-]+/g, '');
98
+ }
99
+ /**
100
+ * Decodes a (possibly formatted) recovery code back to its 16 bytes,
101
+ * throwing `RecoveryCodeInvalidError` on anything malformed.
102
+ *
103
+ * @param options {object}
104
+ * @param options.code {string} the user-entered code (grouping tolerated)
105
+ * @returns {Uint8Array}
106
+ */
107
+ export function decodeRecoveryCode({ code }) {
108
+ const normalized = normalizeRecoveryCode({ input: code });
109
+ let bytes;
110
+ try {
111
+ // Throws on characters outside the base58 alphabet.
112
+ bytes = base58.decode(normalized);
113
+ }
114
+ catch {
115
+ throw new RecoveryCodeInvalidError();
116
+ }
117
+ if (bytes.length !== RECOVERY_CODE_BYTES) {
118
+ throw new RecoveryCodeInvalidError();
119
+ }
120
+ return bytes;
121
+ }
122
+ /**
123
+ * Derives the code's whole client identity from a (possibly formatted) code.
124
+ * Deterministic: the same code always yields the same key set. Throws
125
+ * `RecoveryCodeInvalidError` on malformed text; whether the derived identity
126
+ * actually unlocks anything is the caller's question.
127
+ *
128
+ * @param options {object}
129
+ * @param options.code {string} the recovery code (grouping tolerated)
130
+ * @returns {Promise<RecoveryClient>}
131
+ */
132
+ export async function recoveryClientFromCode({ code }) {
133
+ const codeBytes = decodeRecoveryCode({ code });
134
+ const salt = new TextEncoder().encode(RECOVERY_CLIENT_SALT);
135
+ const clientSeed = hkdf(sha256, codeBytes, salt, new TextEncoder().encode(RECOVERY_CLIENT_SEED_INFO), 32);
136
+ const updateSeed = hkdf(sha256, codeBytes, salt, new TextEncoder().encode(RECOVERY_UPDATE_SEED_INFO), 32);
137
+ const agents = await agentsFromSeed({ seed: clientSeed });
138
+ const { publicKeyMultibase: keyAgreementKeyMultibase } = agents.keyAgreementKey;
139
+ if (!keyAgreementKeyMultibase) {
140
+ throw new Error('The derived key-agreement key has no public multibase.');
141
+ }
142
+ const [, , signingKeyMultibase] = agents.keyAgent.id.split(':');
143
+ return {
144
+ codeBytes,
145
+ clientSeed,
146
+ updateSeed,
147
+ agents,
148
+ clientDid: agents.keyAgent.id,
149
+ signingKeyMultibase: signingKeyMultibase,
150
+ keyAgreementKeyMultibase,
151
+ updateKeyMultibase: await updateKeyMultibase({ seed: updateSeed }),
152
+ recipientKid: `${agents.keyAgent.id}#${keyAgreementKeyMultibase}`
153
+ };
154
+ }
155
+ //# sourceMappingURL=recoveryCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recoveryCode.js","sourceRoot":"","sources":["../../src/recovery/recoveryCode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The recovery keyring record codec: the `{ version, wrapped }` envelope
6
+ * stored as the one resource of a recovery code's unlock Space. Its plaintext
7
+ * is the ordinary keyring record's (controller, email, account pointer) PLUS
8
+ * the pre-minted PUT-on-`did.jsonl` delegation -- the narrow zcap bridge that
9
+ * lets the code-derived client write its self-enrolling log continuation. It
10
+ * carries **no key material of any kind**: never a seed, never a PUK wrap
11
+ * (wraps live doc-and-roster only), so the record stays a pure pointer.
12
+ *
13
+ * The wrap reuses the keyring cipher context verbatim, so a recovery record
14
+ * IS a keyring record to every generic consumer (an ordinary
15
+ * `unwrapKeyringRecord` recovers its pointer and ignores the extra member) --
16
+ * only the recovery flow demands the delegation.
17
+ */
18
+ import type { IKeyAgreementKey, IKeyResolver, IZcap } from '@interop/data-integrity-core';
19
+ import type { AccountPointer } from '../keyring/record.js';
20
+ /**
21
+ * The unwrapped contents of a recovery keyring record: the ordinary record
22
+ * members plus the required delegation. `pointer` is required -- a recovery
23
+ * record exists only on WAS deployments (there is nothing to recover toward
24
+ * without a Space).
25
+ */
26
+ export interface RecoveryRecordContents {
27
+ controller: string;
28
+ email?: string;
29
+ pointer: AccountPointer;
30
+ delegation: IZcap;
31
+ }
32
+ /**
33
+ * Wraps the recovery record: controller, email, pointer, and the pre-minted
34
+ * `did.jsonl` PUT delegation, encrypted under the code's unlock KAK via the
35
+ * keyring EDV cipher context.
36
+ *
37
+ * @param options {object}
38
+ * @param options.controller {string} the account did:key
39
+ * @param [options.email] {string} the account email, when known
40
+ * @param options.pointer {AccountPointer} the account pointer
41
+ * @param options.delegation {IZcap} the PUT-on-`did.jsonl` delegation to the
42
+ * code-derived signing DID
43
+ * @param options.keyAgreementKey {IKeyAgreementKey} the code's unlock KAK
44
+ * @param options.keyResolver {IKeyResolver}
45
+ * @returns {Promise<{ version: number, wrapped: unknown }>}
46
+ */
47
+ export declare function wrapRecoveryRecord({ controller, email, pointer, delegation, keyAgreementKey, keyResolver }: {
48
+ controller: string;
49
+ email?: string;
50
+ pointer: AccountPointer;
51
+ delegation: IZcap;
52
+ keyAgreementKey: IKeyAgreementKey;
53
+ keyResolver: IKeyResolver;
54
+ }): Promise<{
55
+ version: number;
56
+ wrapped: unknown;
57
+ }>;
58
+ /**
59
+ * Unwraps and validates a recovery record: the ordinary keyring-record checks
60
+ * plus the required pointer and delegation. A record without a delegation is
61
+ * not a recovery record (an ordinary keyring record found under a code's
62
+ * unlock Space would mean a corrupted issuance) and is refused.
63
+ *
64
+ * @param options {object}
65
+ * @param options.record {unknown} the stored `{ version, wrapped }` envelope
66
+ * @param options.keyAgreementKey {IKeyAgreementKey} the code's unlock KAK
67
+ * @param options.keyResolver {IKeyResolver}
68
+ * @returns {Promise<RecoveryRecordContents>}
69
+ */
70
+ export declare function unwrapRecoveryRecord({ record, keyAgreementKey, keyResolver }: {
71
+ record: unknown;
72
+ keyAgreementKey: IKeyAgreementKey;
73
+ keyResolver: IKeyResolver;
74
+ }): Promise<RecoveryRecordContents>;
75
+ //# sourceMappingURL=recoveryRecord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recoveryRecord.d.ts","sourceRoot":"","sources":["../../src/recovery/recoveryRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACN,MAAM,8BAA8B,CAAA;AAOrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,cAAc,CAAA;IACvB,UAAU,EAAE,KAAK,CAAA;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,UAAU,EACV,KAAK,EACL,OAAO,EACP,UAAU,EACV,eAAe,EACf,WAAW,EACZ,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,cAAc,CAAA;IACvB,UAAU,EAAE,KAAK,CAAA;IACjB,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;CAC1B,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAqBjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,EACzC,MAAM,EACN,eAAe,EACf,WAAW,EACZ,EAAE;IACD,MAAM,EAAE,OAAO,CAAA;IACf,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;CAC1B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA+ClC"}
@@ -0,0 +1,89 @@
1
+ import { createEdvDocCipher } from '@interop/was-client/edv';
2
+ import { KEYRING_COLLECTION } from '../space/collections.js';
3
+ import { KEYRING_RECORD_VERSION, parseRecordPointer } from '../keyring/record.js';
4
+ /**
5
+ * Wraps the recovery record: controller, email, pointer, and the pre-minted
6
+ * `did.jsonl` PUT delegation, encrypted under the code's unlock KAK via the
7
+ * keyring EDV cipher context.
8
+ *
9
+ * @param options {object}
10
+ * @param options.controller {string} the account did:key
11
+ * @param [options.email] {string} the account email, when known
12
+ * @param options.pointer {AccountPointer} the account pointer
13
+ * @param options.delegation {IZcap} the PUT-on-`did.jsonl` delegation to the
14
+ * code-derived signing DID
15
+ * @param options.keyAgreementKey {IKeyAgreementKey} the code's unlock KAK
16
+ * @param options.keyResolver {IKeyResolver}
17
+ * @returns {Promise<{ version: number, wrapped: unknown }>}
18
+ */
19
+ export async function wrapRecoveryRecord({ controller, email, pointer, delegation, keyAgreementKey, keyResolver }) {
20
+ const cipher = await createEdvDocCipher({
21
+ keyAgreementKey,
22
+ keyResolver,
23
+ collectionId: KEYRING_COLLECTION.id
24
+ });
25
+ const data = {
26
+ controller,
27
+ ...(email ? { email } : {}),
28
+ pointer: {
29
+ ...(pointer.did ? { did: pointer.did } : {}),
30
+ spaceId: pointer.spaceId,
31
+ host: pointer.host
32
+ },
33
+ delegation,
34
+ createdAt: new Date().toISOString()
35
+ };
36
+ const { envelope } = await cipher.encrypt({
37
+ data: data
38
+ });
39
+ return { version: KEYRING_RECORD_VERSION, wrapped: envelope };
40
+ }
41
+ /**
42
+ * Unwraps and validates a recovery record: the ordinary keyring-record checks
43
+ * plus the required pointer and delegation. A record without a delegation is
44
+ * not a recovery record (an ordinary keyring record found under a code's
45
+ * unlock Space would mean a corrupted issuance) and is refused.
46
+ *
47
+ * @param options {object}
48
+ * @param options.record {unknown} the stored `{ version, wrapped }` envelope
49
+ * @param options.keyAgreementKey {IKeyAgreementKey} the code's unlock KAK
50
+ * @param options.keyResolver {IKeyResolver}
51
+ * @returns {Promise<RecoveryRecordContents>}
52
+ */
53
+ export async function unwrapRecoveryRecord({ record, keyAgreementKey, keyResolver }) {
54
+ if (record === null || typeof record !== 'object') {
55
+ throw new Error('Malformed recovery record.');
56
+ }
57
+ const { version, wrapped } = record;
58
+ if (version !== KEYRING_RECORD_VERSION) {
59
+ throw new Error(`Unsupported recovery record version "${String(version)}".`);
60
+ }
61
+ const cipher = await createEdvDocCipher({
62
+ keyAgreementKey,
63
+ keyResolver,
64
+ collectionId: KEYRING_COLLECTION.id
65
+ });
66
+ const plaintext = (await cipher.decrypt({
67
+ envelope: wrapped
68
+ }));
69
+ if (typeof plaintext.controller !== 'string' || !plaintext.controller) {
70
+ throw new Error('Recovery record is missing a controller.');
71
+ }
72
+ const pointer = parseRecordPointer(plaintext.pointer);
73
+ if (!pointer) {
74
+ throw new Error('Recovery record is missing its account pointer.');
75
+ }
76
+ if (plaintext.delegation === null ||
77
+ typeof plaintext.delegation !== 'object') {
78
+ throw new Error('Recovery record is missing its did.jsonl delegation.');
79
+ }
80
+ return {
81
+ controller: plaintext.controller,
82
+ ...(typeof plaintext.email === 'string' && plaintext.email
83
+ ? { email: plaintext.email }
84
+ : {}),
85
+ pointer,
86
+ delegation: plaintext.delegation
87
+ };
88
+ }
89
+ //# sourceMappingURL=recoveryRecord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recoveryRecord.js","sourceRoot":"","sources":["../../src/recovery/recoveryRecord.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ import type { ClientWebvhUpdateKeys, WebvhEnrollmentKeys, WebvhIdStore } from '../webvh/didWebvh.js';
2
+ /**
3
+ * The verification-method id a code's key-agreement key publishes under --
4
+ * the ordinary `<did>#<multibase>` form, indistinguishable by id from any
5
+ * other keyAgreement entry. Consumers that must exclude recovery entries do
6
+ * it structurally (an enrolled client is a `capabilityInvocation` entry; a
7
+ * recovery key never has one) or by the registry's recorded multibase.
8
+ *
9
+ * @param options {object}
10
+ * @param options.did {string} the account's did:webvh
11
+ * @param options.keyAgreementKeyMultibase {string}
12
+ * @returns {string}
13
+ */
14
+ export declare function recoveryVmId({ did, keyAgreementKeyMultibase }: {
15
+ did: string;
16
+ keyAgreementKeyMultibase: string;
17
+ }): string;
18
+ /**
19
+ * The public halves of a recovery code as the document and log carry them:
20
+ * the X25519 key-agreement key published as the recovery VM, and the update
21
+ * key whose hash stands in `nextKeyHashes`.
22
+ */
23
+ export interface RecoveryPublicKeys {
24
+ keyAgreementKeyMultibase: string;
25
+ updateKeyMultibase: string;
26
+ }
27
+ /**
28
+ * Thrown by the recovery continuation when the log carries neither the code's
29
+ * update key nor its committed hash -- the code was revoked (or never
30
+ * issued), so no continuation can verify.
31
+ */
32
+ export declare class RecoveryKeyNotCommittedError extends Error {
33
+ constructor(message?: string);
34
+ }
35
+ /**
36
+ * The narrow store seam the recovery continuation writes through: a public
37
+ * read of the log and the delegated `did.jsonl` PUT. A subset of
38
+ * {@link WebvhIdStore}, so an app's remote-store class satisfies it too.
39
+ */
40
+ export type RecoveryLogStore = Pick<WebvhIdStore, 'getIdResourceRaw' | 'putIdResource'>;
41
+ /**
42
+ * ISSUANCE (run by an enrolled client, root authority): publishes a recovery
43
+ * code's split posture into the document -- one entry adding the code's
44
+ * `keyAgreement` verification method (an ordinary, unmarked Multikey entry)
45
+ * and committing its update-key hash in `nextKeyHashes`. The code's update
46
+ * key joins `updateKeys` nowhere. Idempotent: a posture already published is
47
+ * a no-op, so re-running a torn issuance converges.
48
+ *
49
+ * @param options {object}
50
+ * @param options.idStore {WebvhIdStore}
51
+ * @param options.updateKeys {ClientWebvhUpdateKeys} the ISSUING client's
52
+ * own did:webvh update-key seeds
53
+ * @param options.recovery {RecoveryPublicKeys} the code's public halves
54
+ * @returns {Promise<{ did: string }>}
55
+ */
56
+ export declare function publishRecoveryKey({ idStore, updateKeys, recovery }: {
57
+ idStore: WebvhIdStore;
58
+ updateKeys: ClientWebvhUpdateKeys;
59
+ recovery: RecoveryPublicKeys;
60
+ }): Promise<{
61
+ did: string;
62
+ }>;
63
+ /**
64
+ * REVOCATION (run by an enrolled client, root authority): removes a recovery
65
+ * code's posture from the document -- its `keyAgreement` verification method
66
+ * and its committed update-key hash -- in one entry. Idempotent. The
67
+ * roster-side half (rotating the PUK epoch off the code's wrap) is the
68
+ * caller's, and runs after this so the resolver's document no longer backs
69
+ * the removed entry.
70
+ *
71
+ * @param options {object}
72
+ * @param options.idStore {WebvhIdStore}
73
+ * @param options.updateKeys {ClientWebvhUpdateKeys} the REVOKING client's
74
+ * own did:webvh update-key seeds
75
+ * @param options.recovery {RecoveryPublicKeys} the code's public halves
76
+ * @returns {Promise<{ did: string }>}
77
+ */
78
+ export declare function removeRecoveryKey({ idStore, updateKeys, recovery }: {
79
+ idStore: WebvhIdStore;
80
+ updateKeys: ClientWebvhUpdateKeys;
81
+ recovery: RecoveryPublicKeys;
82
+ }): Promise<{
83
+ did: string;
84
+ }>;
85
+ /**
86
+ * RECOVERY (run by the code-derived client through the delegated `did.jsonl`
87
+ * PUT): writes the self-enrolling continuation described in the module doc --
88
+ * the reveal-and-commit entry signed by the code's pre-committed update key,
89
+ * then the add-and-retire entry signed by the new ordinary client's update
90
+ * key. Resumable from durable state alone: a completed continuation is
91
+ * detected by the new client's update key already being authorized (no-op),
92
+ * a torn one by the standing commitments (the commit step re-runs
93
+ * convergently -- the spent code's hash is deliberately carried through the
94
+ * commit entry, so a resumed commit can re-state the revealed key).
95
+ *
96
+ * @param options {object}
97
+ * @param options.store {RecoveryLogStore} public log read + delegated PUT
98
+ * @param options.recovery {object} the spent code's update seed and public
99
+ * halves
100
+ * @param options.recovery.updateSeed {Uint8Array}
101
+ * @param options.recovery.keyAgreementKeyMultibase {string}
102
+ * @param options.recovery.updateKeyMultibase {string}
103
+ * @param options.newClientKeys {WebvhEnrollmentKeys} the new ordinary
104
+ * client's public halves
105
+ * @param options.newClientUpdateSeeds {ClientWebvhUpdateKeys} the new
106
+ * client's update-key seeds (minted by the recovery flow, which therefore
107
+ * holds them and can sign the add entry)
108
+ * @param options.replacement {RecoveryPublicKeys} the replacement code's
109
+ * public halves, committed and published in the same continuation
110
+ * @returns {Promise<{ did: string, webDoc?: object }>} the account DID and,
111
+ * when the add entry ran here, the final `did.json` projection for the
112
+ * recovered session to republish
113
+ */
114
+ export declare function recoverWebvhClient({ store, recovery, newClientKeys, newClientUpdateSeeds, replacement }: {
115
+ store: RecoveryLogStore;
116
+ recovery: RecoveryPublicKeys & {
117
+ updateSeed: Uint8Array;
118
+ };
119
+ newClientKeys: WebvhEnrollmentKeys;
120
+ newClientUpdateSeeds: ClientWebvhUpdateKeys;
121
+ replacement: RecoveryPublicKeys;
122
+ }): Promise<{
123
+ did: string;
124
+ webDoc?: object;
125
+ }>;
126
+ //# sourceMappingURL=recoveryWebvh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recoveryWebvh.d.ts","sourceRoot":"","sources":["../../src/recovery/recoveryWebvh.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EACV,qBAAqB,EAErB,mBAAmB,EACnB,YAAY,EACb,MAAM,sBAAsB,CAAA;AAE7B;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,EAC3B,GAAG,EACH,wBAAwB,EACzB,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,wBAAwB,EAAE,MAAM,CAAA;CACjC,GAAG,MAAM,CAET;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB,EAAE,MAAM,CAAA;IAChC,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;gBAEnD,OAAO,SACuC;CAKjD;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,YAAY,EACZ,kBAAkB,GAAG,eAAe,CACrC,CAAA;AA0ED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,OAAO,EACP,UAAU,EACV,QAAQ,EACT,EAAE;IACD,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,QAAQ,EAAE,kBAAkB,CAAA;CAC7B,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAyD3B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,OAAO,EACP,UAAU,EACV,QAAQ,EACT,EAAE;IACD,OAAO,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,qBAAqB,CAAA;IACjC,QAAQ,EAAE,kBAAkB,CAAA;CAC7B,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAkD3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,KAAK,EACL,QAAQ,EACR,aAAa,EACb,oBAAoB,EACpB,WAAW,EACZ,EAAE;IACD,KAAK,EAAE,gBAAgB,CAAA;IACvB,QAAQ,EAAE,kBAAkB,GAAG;QAAE,UAAU,EAAE,UAAU,CAAA;KAAE,CAAA;IACzD,aAAa,EAAE,mBAAmB,CAAA;IAClC,oBAAoB,EAAE,qBAAqB,CAAA;IAC3C,WAAW,EAAE,kBAAkB,CAAA;CAChC,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsI5C"}