@interop/wallet-core 0.41.0 → 0.43.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 (121) hide show
  1. package/README.md +17 -4
  2. package/dist/clients/rosterPolicy.d.ts +28 -16
  3. package/dist/clients/rosterPolicy.d.ts.map +1 -1
  4. package/dist/clients/rosterPolicy.js +51 -26
  5. package/dist/clients/rosterPolicy.js.map +1 -1
  6. package/dist/descriptors/index.d.ts +1 -1
  7. package/dist/descriptors/index.d.ts.map +1 -1
  8. package/dist/descriptors/index.js +1 -1
  9. package/dist/descriptors/index.js.map +1 -1
  10. package/dist/descriptors/logSource.d.ts +58 -6
  11. package/dist/descriptors/logSource.d.ts.map +1 -1
  12. package/dist/descriptors/logSource.js +57 -15
  13. package/dist/descriptors/logSource.js.map +1 -1
  14. package/dist/enrollment/enrollment.d.ts.map +1 -1
  15. package/dist/enrollment/enrollment.js +14 -26
  16. package/dist/enrollment/enrollment.js.map +1 -1
  17. package/dist/keyring/fetch.d.ts +12 -0
  18. package/dist/keyring/fetch.d.ts.map +1 -1
  19. package/dist/keyring/fetch.js +0 -2
  20. package/dist/keyring/fetch.js.map +1 -1
  21. package/dist/keyring/index.d.ts +1 -1
  22. package/dist/keyring/index.d.ts.map +1 -1
  23. package/dist/keyring/index.js +1 -1
  24. package/dist/keyring/index.js.map +1 -1
  25. package/dist/keyring/kdf.d.ts +22 -6
  26. package/dist/keyring/kdf.d.ts.map +1 -1
  27. package/dist/keyring/kdf.js +9 -14
  28. package/dist/keyring/kdf.js.map +1 -1
  29. package/dist/keys/index.d.ts +1 -1
  30. package/dist/keys/index.d.ts.map +1 -1
  31. package/dist/keys/index.js +1 -1
  32. package/dist/keys/index.js.map +1 -1
  33. package/dist/keys/rosterLogStore.d.ts +4 -1
  34. package/dist/keys/rosterLogStore.d.ts.map +1 -1
  35. package/dist/keys/rosterLogStore.js +13 -16
  36. package/dist/keys/rosterLogStore.js.map +1 -1
  37. package/dist/keys/rosterStore.d.ts +13 -1
  38. package/dist/keys/rosterStore.d.ts.map +1 -1
  39. package/dist/keys/rosterStore.js +18 -0
  40. package/dist/keys/rosterStore.js.map +1 -1
  41. package/dist/keys/userKeyRoster.d.ts +17 -5
  42. package/dist/keys/userKeyRoster.d.ts.map +1 -1
  43. package/dist/keys/userKeyRoster.js +38 -13
  44. package/dist/keys/userKeyRoster.js.map +1 -1
  45. package/dist/recovery/index.d.ts +14 -12
  46. package/dist/recovery/index.d.ts.map +1 -1
  47. package/dist/recovery/index.js +13 -11
  48. package/dist/recovery/index.js.map +1 -1
  49. package/dist/recovery/recoveryCode.d.ts +5 -17
  50. package/dist/recovery/recoveryCode.d.ts.map +1 -1
  51. package/dist/recovery/recoveryCode.js +4 -14
  52. package/dist/recovery/recoveryCode.js.map +1 -1
  53. package/dist/recovery/recoveryDelegation.d.ts +50 -19
  54. package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
  55. package/dist/recovery/recoveryDelegation.js +86 -41
  56. package/dist/recovery/recoveryDelegation.js.map +1 -1
  57. package/dist/recovery/recoveryWebvh.d.ts +13 -22
  58. package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
  59. package/dist/recovery/recoveryWebvh.js +37 -129
  60. package/dist/recovery/recoveryWebvh.js.map +1 -1
  61. package/dist/resourceLog/append.d.ts +12 -3
  62. package/dist/resourceLog/append.d.ts.map +1 -1
  63. package/dist/resourceLog/append.js +17 -10
  64. package/dist/resourceLog/append.js.map +1 -1
  65. package/dist/resourceLog/index.d.ts +1 -1
  66. package/dist/resourceLog/index.d.ts.map +1 -1
  67. package/dist/resourceLog/index.js +1 -1
  68. package/dist/resourceLog/index.js.map +1 -1
  69. package/dist/resourceLog/pin.d.ts +46 -8
  70. package/dist/resourceLog/pin.d.ts.map +1 -1
  71. package/dist/resourceLog/pin.js +32 -7
  72. package/dist/resourceLog/pin.js.map +1 -1
  73. package/dist/resourceLog/seal.d.ts +4 -1
  74. package/dist/resourceLog/seal.d.ts.map +1 -1
  75. package/dist/resourceLog/seal.js +6 -2
  76. package/dist/resourceLog/seal.js.map +1 -1
  77. package/dist/unlock/index.d.ts +40 -0
  78. package/dist/unlock/index.d.ts.map +1 -0
  79. package/dist/unlock/index.js +36 -0
  80. package/dist/unlock/index.js.map +1 -0
  81. package/dist/unlock/ladder.d.ts +100 -0
  82. package/dist/unlock/ladder.d.ts.map +1 -0
  83. package/dist/unlock/ladder.js +144 -0
  84. package/dist/unlock/ladder.js.map +1 -0
  85. package/dist/unlock/selfEnroll.d.ts +83 -0
  86. package/dist/unlock/selfEnroll.d.ts.map +1 -0
  87. package/dist/unlock/selfEnroll.js +126 -0
  88. package/dist/unlock/selfEnroll.js.map +1 -0
  89. package/dist/unlock/standingClient.d.ts +68 -0
  90. package/dist/unlock/standingClient.d.ts.map +1 -0
  91. package/dist/unlock/standingClient.js +81 -0
  92. package/dist/unlock/standingClient.js.map +1 -0
  93. package/dist/unlock/standingWebvh.d.ts +153 -0
  94. package/dist/unlock/standingWebvh.d.ts.map +1 -0
  95. package/dist/unlock/standingWebvh.js +370 -0
  96. package/dist/unlock/standingWebvh.js.map +1 -0
  97. package/dist/unlock/unlockRecord.d.ts +207 -0
  98. package/dist/unlock/unlockRecord.d.ts.map +1 -0
  99. package/dist/unlock/unlockRecord.js +435 -0
  100. package/dist/unlock/unlockRecord.js.map +1 -0
  101. package/dist/webvh/didWebvh.d.ts +94 -6
  102. package/dist/webvh/didWebvh.d.ts.map +1 -1
  103. package/dist/webvh/didWebvh.js +175 -19
  104. package/dist/webvh/didWebvh.js.map +1 -1
  105. package/dist/webvh/index.d.ts +7 -2
  106. package/dist/webvh/index.d.ts.map +1 -1
  107. package/dist/webvh/index.js +7 -2
  108. package/dist/webvh/index.js.map +1 -1
  109. package/dist/webvh/keyAgreement.d.ts +22 -6
  110. package/dist/webvh/keyAgreement.d.ts.map +1 -1
  111. package/dist/webvh/keyAgreement.js +1 -1
  112. package/dist/webvh/keyAgreement.js.map +1 -1
  113. package/dist/webvh/verifyLog.d.ts +15 -2
  114. package/dist/webvh/verifyLog.d.ts.map +1 -1
  115. package/dist/webvh/verifyLog.js +22 -3
  116. package/dist/webvh/verifyLog.js.map +1 -1
  117. package/package.json +11 -5
  118. package/dist/recovery/recoveryRecord.d.ts +0 -172
  119. package/dist/recovery/recoveryRecord.d.ts.map +0 -1
  120. package/dist/recovery/recoveryRecord.js +0 -288
  121. package/dist/recovery/recoveryRecord.js.map +0 -1
@@ -0,0 +1,207 @@
1
+ import type { IKeyAgreementKey, IKeyResolver, IZcap } from '@interop/data-integrity-core';
2
+ import type { CollectionEncryption } from '@interop/was-client';
3
+ import type { AccountPointer, RecordSigner, SignedRecord } from '../keyring/record.js';
4
+ /**
5
+ * An unlock record's account binding is absent, malformed, or does not verify
6
+ * under the credential's binding MAC key. Its own class, distinct from a
7
+ * proof or decrypt failure: this is the refusal that says the record's
8
+ * account core (and ladder seed, where one rides) was not written by a holder
9
+ * of this credential -- a forged record redirecting login at another account,
10
+ * or a record from before the account moved hosts (either way the credential
11
+ * must be rebound).
12
+ */
13
+ export declare class UnlockBindingError extends Error {
14
+ constructor(message: string);
15
+ }
16
+ /**
17
+ * A self-contained sealed record member: its own one-epoch descriptor plus
18
+ * the envelope sealed under it. Self-containment is what lets a member travel
19
+ * VERBATIM through a re-mint that re-seals its siblings -- each member
20
+ * decrypts against its own descriptor, not the frame's.
21
+ */
22
+ export interface SealedRecordMember {
23
+ encryption: CollectionEncryption;
24
+ wrapped: unknown;
25
+ }
26
+ /**
27
+ * The unwrapped contents of an unlock record: the credential-authenticated
28
+ * account core (controller + pointer, plus the ladder seed where the
29
+ * credential is a standing method), the bridge delegation, the optional bind
30
+ * email, and the bind timestamp. `pointer` is required -- the record exists
31
+ * only on WAS deployments.
32
+ */
33
+ export interface UnlockRecordContents {
34
+ controller: string;
35
+ email?: string;
36
+ pointer: AccountPointer;
37
+ delegation: IZcap;
38
+ ladderSeed?: Uint8Array;
39
+ createdAt: string;
40
+ }
41
+ /**
42
+ * A stored unlock record: the shared signed frame plus the record-kind
43
+ * members the frame proof also covers.
44
+ */
45
+ export interface SignedUnlockRecord extends SignedRecord {
46
+ binding: string;
47
+ bridge: SealedRecordMember;
48
+ ladder?: SealedRecordMember;
49
+ }
50
+ /**
51
+ * Where an unlock record's proof stands after the unwrap: `'verified'` when
52
+ * the credential-derived unlock key signed it (checked before decryption), or
53
+ * a pending marker naming the signer the caller must still check against the
54
+ * account's verified did:webvh document -- the re-mint case, where an
55
+ * enrolled client signed on the credential's behalf. The pending case defers
56
+ * the shell's authenticity only, never the account identity: the binding is
57
+ * verified either way.
58
+ */
59
+ export type UnlockRecordProofState = 'verified' | {
60
+ pending: {
61
+ verificationMethod: string;
62
+ keyMultibase: string;
63
+ };
64
+ };
65
+ /**
66
+ * Computes the account-binding tag: HMAC-SHA-256 over the core values under
67
+ * the credential-derived binding MAC key, base64url (no pad). Bind time calls
68
+ * it to stamp the record; login recomputes it to verify.
69
+ *
70
+ * @param options {object}
71
+ * @param options.bindingMacKey {Uint8Array} the credential-derived MAC key
72
+ * @param options.controller {string} the account controller
73
+ * @param options.pointer {AccountPointer} the account pointer
74
+ * @param [options.ladderSeed] {Uint8Array} the ladder seed, for a standing
75
+ * credential
76
+ * @returns {string}
77
+ */
78
+ export declare function computeUnlockBinding({ bindingMacKey, controller, pointer, ladderSeed }: {
79
+ bindingMacKey: Uint8Array;
80
+ controller: string;
81
+ pointer: AccountPointer;
82
+ ladderSeed?: Uint8Array;
83
+ }): string;
84
+ /**
85
+ * Reads the `binding` frame member off a stored unlock record without
86
+ * decrypting anything. The re-mint path uses it to confirm the record is
87
+ * re-mintable before touching it. Refuses a record with no binding: such a
88
+ * record predates the credential-authenticated core and cannot be re-minted
89
+ * -- its credential must be rebound.
90
+ *
91
+ * @param options {object}
92
+ * @param options.record {unknown} the stored record envelope
93
+ * @returns {string}
94
+ */
95
+ export declare function unlockRecordBinding({ record }: {
96
+ record: unknown;
97
+ }): string;
98
+ /**
99
+ * Wraps an unlock record at bind time: the shell (controller, optional
100
+ * email, pointer, timestamp) sealed to the credential's unlock KAK, the
101
+ * bridge delegation and the optional ladder seed sealed as their own
102
+ * members, the credential-authenticated binding computed over the core, and
103
+ * the whole frame signed -- by the credential-derived unlock key at bind
104
+ * time, or by an acting client's account key where a ceremony rebuilds a
105
+ * record whole (the reader settles the mixed-signer policy either way).
106
+ *
107
+ * @param options {object}
108
+ * @param options.controller {string} the account controller
109
+ * @param [options.email] {string} the account email, when known
110
+ * @param options.pointer {AccountPointer} the account pointer
111
+ * @param options.delegation {IZcap} the PUT-on-`did.jsonl` delegation to
112
+ * the credential-derived signing DID
113
+ * @param [options.ladderSeed] {Uint8Array} the update-key ladder seed, for
114
+ * a standing credential (a recovery code carries none)
115
+ * @param options.keyAgreementKey {IKeyAgreementKey} the credential's unlock
116
+ * KAK -- its public half is all the wrap uses
117
+ * @param options.signer {RecordSigner} the signing key
118
+ * @param options.bindingMacKey {Uint8Array} the credential-derived binding
119
+ * MAC key
120
+ * @param [options.createdAt] {string} the bind timestamp to stamp, as an
121
+ * ISO string; defaults to now. Supplied by a caller that pins record
122
+ * freshness.
123
+ * @returns {Promise<SignedUnlockRecord>}
124
+ */
125
+ export declare function wrapUnlockRecord({ controller, email, pointer, delegation, ladderSeed, keyAgreementKey, signer, bindingMacKey, createdAt }: {
126
+ controller: string;
127
+ email?: string;
128
+ pointer: AccountPointer;
129
+ delegation: IZcap;
130
+ ladderSeed?: Uint8Array;
131
+ keyAgreementKey: IKeyAgreementKey;
132
+ signer: RecordSigner;
133
+ bindingMacKey: Uint8Array;
134
+ createdAt?: string;
135
+ }): Promise<SignedUnlockRecord>;
136
+ /**
137
+ * Unwraps and validates an unlock record: the ordinary keyring-record frame
138
+ * checks plus the required pointer, bridge delegation, and
139
+ * credential-authenticated binding. A record without a bridge member is not
140
+ * an unlock record in the standing layout (an ordinary keyring record found
141
+ * under a credential's unlock Space would mean a torn bind) and is refused.
142
+ *
143
+ * The binding is verified before the contents are returned: the decrypted
144
+ * core must carry the tag the credential-derived MAC key computes over it, or
145
+ * the record is refused as forged ({@link UnlockBindingError}) -- the check
146
+ * that closes the host-forgery redirect, since the host never holds the MAC
147
+ * key. Nothing downstream may trust the pointer (or the ladder seed) before
148
+ * this returns.
149
+ *
150
+ * Proof verification is mixed-signer and ordered deliberately, exactly as the
151
+ * recovery record's was: a proof by the credential's own unlock key is
152
+ * verified BEFORE decryption; a proof by any other key comes back as a
153
+ * pending state naming the signer, for the caller to settle with
154
+ * `verifyRecordProof` against the verified document of the account the
155
+ * credential-authenticated pointer names.
156
+ *
157
+ * @param options {object}
158
+ * @param options.record {unknown} the stored record envelope
159
+ * @param options.keyAgreementKey {IKeyAgreementKey} the credential's unlock
160
+ * KAK
161
+ * @param options.keyResolver {IKeyResolver}
162
+ * @param options.expectedKeyMultibase {string} the credential-derived
163
+ * unlock signing key's multibase
164
+ * @param options.bindingMacKey {Uint8Array} the credential-derived binding
165
+ * MAC key the record's account binding must verify under
166
+ * @returns {Promise<{ contents: UnlockRecordContents,
167
+ * proofState: UnlockRecordProofState }>}
168
+ */
169
+ export declare function unwrapUnlockRecord({ record, keyAgreementKey, keyResolver, expectedKeyMultibase, bindingMacKey }: {
170
+ record: unknown;
171
+ keyAgreementKey: IKeyAgreementKey;
172
+ keyResolver: IKeyResolver;
173
+ expectedKeyMultibase: string;
174
+ bindingMacKey: Uint8Array;
175
+ }): Promise<{
176
+ contents: UnlockRecordContents;
177
+ proofState: UnlockRecordProofState;
178
+ }>;
179
+ /**
180
+ * Re-mints an unlock record's bridge: the revocation-cascade path that
181
+ * replaces a rotted or expiring delegation while touching nothing else. The
182
+ * shell, the ladder member, and the binding are carried VERBATIM (the re-mint
183
+ * cannot decrypt any of them and does not need to -- each is self-contained
184
+ * and the binding covers the core), a fresh bridge is sealed to the
185
+ * credential's unlock KAK public half, and the frame is re-signed by the
186
+ * acting client's account key -- the mixed-signer case the reader settles
187
+ * against the verified document.
188
+ *
189
+ * A record with no binding cannot be re-minted ({@link UnlockBindingError});
190
+ * its credential must be rebound.
191
+ *
192
+ * @param options {object}
193
+ * @param options.record {unknown} the standing stored record
194
+ * @param options.delegation {IZcap} the freshly minted `did.jsonl`
195
+ * delegation
196
+ * @param options.keyAgreementKey {IKeyAgreementKey} the credential's unlock
197
+ * KAK, public half only
198
+ * @param options.signer {RecordSigner} the acting client's account key
199
+ * @returns {Promise<SignedUnlockRecord>}
200
+ */
201
+ export declare function remintUnlockRecordBridge({ record, delegation, keyAgreementKey, signer }: {
202
+ record: unknown;
203
+ delegation: IZcap;
204
+ keyAgreementKey: IKeyAgreementKey;
205
+ signer: RecordSigner;
206
+ }): Promise<SignedUnlockRecord>;
207
+ //# sourceMappingURL=unlockRecord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unlockRecord.d.ts","sourceRoot":"","sources":["../../src/unlock/unlockRecord.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,435 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The unlock record codec for credentials with standing authority: the
6
+ * envelope stored as the one resource of a credential's unlock Space, for
7
+ * every unlock method in the standing posture -- a passphrase, a passkey PRF
8
+ * output, or a recovery code. Its frame is the ordinary keyring record's
9
+ * (`{ version, encryption, wrapped, proof }`), extended with three
10
+ * record-kind members the proof also covers:
11
+ *
12
+ * - `wrapped` (the SHELL): the account core -- controller, optional email,
13
+ * pointer, bind timestamp -- sealed to the credential's unlock KAK. Carried
14
+ * VERBATIM through every re-mint, so the bind timestamp (which apps pin
15
+ * freshness on) and the email survive a re-mint that cannot decrypt them.
16
+ * - `bridge`: the pre-minted PUT-on-`did.jsonl` delegation, sealed in its own
17
+ * self-contained `{ encryption, wrapped }` member. The one member a re-mint
18
+ * replaces: revoking the client that signed the delegation rots it, and the
19
+ * revocation cascade re-seals a fresh one to the credential's unlock KAK
20
+ * public half ({@link remintUnlockRecordBridge}).
21
+ * - `ladder` (standing credentials only): the random 32-byte update-key
22
+ * ladder seed (`./ladder`), sealed in its own `{ encryption, wrapped }`
23
+ * member and carried VERBATIM through re-mints -- a re-mint can never read
24
+ * or replace a credential's update authority. A recovery code carries none
25
+ * (its single update key derives from the code bytes).
26
+ *
27
+ * The record splits into a credential-authenticated core and a re-mintable
28
+ * shell exactly as the recovery record did. The core is the account binding
29
+ * plus the ladder seed, authenticated by the `binding` frame member: an HMAC
30
+ * tag under a key derived from the credential itself, computed at bind time
31
+ * and verified BEFORE the pointer is trusted. Only the binder and the
32
+ * credential holder ever hold that key -- the storage host never does -- so a
33
+ * host-forged record redirecting login (or a host-substituted ladder seed)
34
+ * fails the tag however it is encrypted or signed. The tag rides the frame in
35
+ * the clear (it reveals nothing), so the re-mint path, which cannot decrypt
36
+ * the record or recompute the tag, preserves it verbatim. The consequence: a
37
+ * re-mint can never move the record to another account, and an account that
38
+ * moves hosts must rebind its credentials.
39
+ *
40
+ * The shell's signer is mixed, as before: at bind time the record is signed
41
+ * by the credential-derived unlock key (verified before decryption); a
42
+ * re-mint signs with the acting client's account verification method, which
43
+ * comes back as a pending proof state the caller settles against the account
44
+ * document the credential-authenticated pointer names.
45
+ */
46
+ import { base64urlnopad } from '@scure/base';
47
+ import { equalBytes } from '@noble/ciphers/utils.js';
48
+ import { hmac } from '@noble/hashes/hmac.js';
49
+ import { sha256 } from '@noble/hashes/sha2.js';
50
+ import { KEYRING_RECORD_VERSION, mintRecordEncryption, parseRecordCreatedAt, parseRecordFrame, parseRecordPointer, recordCipher, recordCreatedAtStamp, recordProofKeyMultibase, recordSealCipher, signRecordFrame, verifyRecordProof } from '../keyring/record.js';
51
+ import { LADDER_SEED_BYTES } from './ladder.js';
52
+ /**
53
+ * The context label mixed into the binding MAC input, versioning the tag
54
+ * construction. Permanent -- changing it orphans every bound credential.
55
+ * Supersedes the recovery record's `freewallet/recovery/binding/v1` (the
56
+ * standing layout is a re-provision boundary; issued codes are re-issued).
57
+ */
58
+ const UNLOCK_BINDING_CONTEXT = 'freewallet/unlock/binding/v2';
59
+ /**
60
+ * An unlock record's account binding is absent, malformed, or does not verify
61
+ * under the credential's binding MAC key. Its own class, distinct from a
62
+ * proof or decrypt failure: this is the refusal that says the record's
63
+ * account core (and ladder seed, where one rides) was not written by a holder
64
+ * of this credential -- a forged record redirecting login at another account,
65
+ * or a record from before the account moved hosts (either way the credential
66
+ * must be rebound).
67
+ */
68
+ export class UnlockBindingError extends Error {
69
+ constructor(message) {
70
+ super(message);
71
+ this.name = 'UnlockBindingError';
72
+ }
73
+ }
74
+ /**
75
+ * The deterministic MAC input over a record's credential-authenticated core:
76
+ * a JSON array of the context label, the binding values, and the ladder seed
77
+ * (base64url, empty for a credential that carries none), so no delimiter
78
+ * ambiguity can make two cores collide.
79
+ */
80
+ function bindingMacInput({ controller, pointer, ladderSeed }) {
81
+ return new TextEncoder().encode(JSON.stringify([
82
+ UNLOCK_BINDING_CONTEXT,
83
+ controller,
84
+ pointer.did ?? '',
85
+ pointer.spaceId,
86
+ pointer.host,
87
+ ladderSeed ? base64urlnopad.encode(ladderSeed) : ''
88
+ ]));
89
+ }
90
+ /**
91
+ * Computes the account-binding tag: HMAC-SHA-256 over the core values under
92
+ * the credential-derived binding MAC key, base64url (no pad). Bind time calls
93
+ * it to stamp the record; login recomputes it to verify.
94
+ *
95
+ * @param options {object}
96
+ * @param options.bindingMacKey {Uint8Array} the credential-derived MAC key
97
+ * @param options.controller {string} the account controller
98
+ * @param options.pointer {AccountPointer} the account pointer
99
+ * @param [options.ladderSeed] {Uint8Array} the ladder seed, for a standing
100
+ * credential
101
+ * @returns {string}
102
+ */
103
+ export function computeUnlockBinding({ bindingMacKey, controller, pointer, ladderSeed }) {
104
+ return base64urlnopad.encode(hmac(sha256, bindingMacKey, bindingMacInput({
105
+ controller,
106
+ pointer,
107
+ ...(ladderSeed ? { ladderSeed } : {})
108
+ })));
109
+ }
110
+ /**
111
+ * Reads the `binding` frame member off a stored unlock record without
112
+ * decrypting anything. The re-mint path uses it to confirm the record is
113
+ * re-mintable before touching it. Refuses a record with no binding: such a
114
+ * record predates the credential-authenticated core and cannot be re-minted
115
+ * -- its credential must be rebound.
116
+ *
117
+ * @param options {object}
118
+ * @param options.record {unknown} the stored record envelope
119
+ * @returns {string}
120
+ */
121
+ export function unlockRecordBinding({ record }) {
122
+ const { binding } = (record ?? {});
123
+ if (typeof binding !== 'string' || !binding) {
124
+ throw new UnlockBindingError('The unlock record carries no credential-authenticated account ' +
125
+ 'binding; the credential must be rebound.');
126
+ }
127
+ return binding;
128
+ }
129
+ /**
130
+ * Shape-checks a sealed record member (`{ encryption, wrapped }`).
131
+ *
132
+ * @param options {object}
133
+ * @param options.value {unknown} the frame member
134
+ * @param options.name {string} names the member in the refusal
135
+ * @returns {SealedRecordMember}
136
+ */
137
+ function parseSealedMember({ value, name }) {
138
+ const member = value;
139
+ if (member === null ||
140
+ typeof member !== 'object' ||
141
+ member.encryption === null ||
142
+ typeof member.encryption !== 'object' ||
143
+ member.wrapped === undefined ||
144
+ member.wrapped === null) {
145
+ throw new Error(`The unlock record's ${name} member is malformed.`);
146
+ }
147
+ return member;
148
+ }
149
+ /**
150
+ * Seals one self-contained record member to a KAK: a fresh one-epoch
151
+ * descriptor plus the envelope. Sealing needs no key-agreement secret, which
152
+ * is what lets the re-mint path (holding only the credential's unlock KAK
153
+ * public half) build a fresh bridge member.
154
+ *
155
+ * @param options {object}
156
+ * @param options.data {object} the member plaintext
157
+ * @param options.keyAgreementKey {IKeyAgreementKey} the credential's unlock
158
+ * KAK (public half suffices)
159
+ * @returns {Promise<SealedRecordMember>}
160
+ */
161
+ async function sealMember({ data, keyAgreementKey }) {
162
+ const encryption = await mintRecordEncryption({ keyAgreementKey });
163
+ const cipher = await recordSealCipher({ encryption });
164
+ const { envelope } = await cipher.encrypt({
165
+ data: data
166
+ });
167
+ return { encryption, wrapped: envelope };
168
+ }
169
+ /**
170
+ * Opens one self-contained record member with the credential's unlock KAK.
171
+ *
172
+ * @param options {object}
173
+ * @param options.member {SealedRecordMember}
174
+ * @param options.keyAgreementKey {IKeyAgreementKey}
175
+ * @param options.keyResolver {IKeyResolver}
176
+ * @returns {Promise<unknown>} the member plaintext
177
+ */
178
+ async function openMember({ member, keyAgreementKey, keyResolver }) {
179
+ const cipher = await recordCipher({
180
+ keyAgreementKey,
181
+ keyResolver,
182
+ encryption: member.encryption
183
+ });
184
+ return cipher.decrypt({ envelope: member.wrapped });
185
+ }
186
+ /**
187
+ * Wraps an unlock record at bind time: the shell (controller, optional
188
+ * email, pointer, timestamp) sealed to the credential's unlock KAK, the
189
+ * bridge delegation and the optional ladder seed sealed as their own
190
+ * members, the credential-authenticated binding computed over the core, and
191
+ * the whole frame signed -- by the credential-derived unlock key at bind
192
+ * time, or by an acting client's account key where a ceremony rebuilds a
193
+ * record whole (the reader settles the mixed-signer policy either way).
194
+ *
195
+ * @param options {object}
196
+ * @param options.controller {string} the account controller
197
+ * @param [options.email] {string} the account email, when known
198
+ * @param options.pointer {AccountPointer} the account pointer
199
+ * @param options.delegation {IZcap} the PUT-on-`did.jsonl` delegation to
200
+ * the credential-derived signing DID
201
+ * @param [options.ladderSeed] {Uint8Array} the update-key ladder seed, for
202
+ * a standing credential (a recovery code carries none)
203
+ * @param options.keyAgreementKey {IKeyAgreementKey} the credential's unlock
204
+ * KAK -- its public half is all the wrap uses
205
+ * @param options.signer {RecordSigner} the signing key
206
+ * @param options.bindingMacKey {Uint8Array} the credential-derived binding
207
+ * MAC key
208
+ * @param [options.createdAt] {string} the bind timestamp to stamp, as an
209
+ * ISO string; defaults to now. Supplied by a caller that pins record
210
+ * freshness.
211
+ * @returns {Promise<SignedUnlockRecord>}
212
+ */
213
+ export async function wrapUnlockRecord({ controller, email, pointer, delegation, ladderSeed, keyAgreementKey, signer, bindingMacKey, createdAt }) {
214
+ if (ladderSeed && ladderSeed.length !== LADDER_SEED_BYTES) {
215
+ throw new Error('The ladder seed must be 32 bytes.');
216
+ }
217
+ const binding = computeUnlockBinding({
218
+ bindingMacKey,
219
+ controller,
220
+ pointer,
221
+ ...(ladderSeed ? { ladderSeed } : {})
222
+ });
223
+ const shell = await sealMember({
224
+ data: {
225
+ controller,
226
+ ...(email ? { email } : {}),
227
+ pointer: {
228
+ ...(pointer.did ? { did: pointer.did } : {}),
229
+ spaceId: pointer.spaceId,
230
+ host: pointer.host
231
+ },
232
+ createdAt: recordCreatedAtStamp({ createdAt })
233
+ },
234
+ keyAgreementKey
235
+ });
236
+ const bridge = await sealMember({ data: { delegation }, keyAgreementKey });
237
+ const ladder = ladderSeed
238
+ ? await sealMember({
239
+ data: { ladderSeed: base64urlnopad.encode(ladderSeed) },
240
+ keyAgreementKey
241
+ })
242
+ : undefined;
243
+ return (await signRecordFrame({
244
+ version: KEYRING_RECORD_VERSION,
245
+ encryption: shell.encryption,
246
+ wrapped: shell.wrapped,
247
+ signer,
248
+ members: { binding, bridge, ...(ladder ? { ladder } : {}) }
249
+ }));
250
+ }
251
+ /**
252
+ * Unwraps and validates an unlock record: the ordinary keyring-record frame
253
+ * checks plus the required pointer, bridge delegation, and
254
+ * credential-authenticated binding. A record without a bridge member is not
255
+ * an unlock record in the standing layout (an ordinary keyring record found
256
+ * under a credential's unlock Space would mean a torn bind) and is refused.
257
+ *
258
+ * The binding is verified before the contents are returned: the decrypted
259
+ * core must carry the tag the credential-derived MAC key computes over it, or
260
+ * the record is refused as forged ({@link UnlockBindingError}) -- the check
261
+ * that closes the host-forgery redirect, since the host never holds the MAC
262
+ * key. Nothing downstream may trust the pointer (or the ladder seed) before
263
+ * this returns.
264
+ *
265
+ * Proof verification is mixed-signer and ordered deliberately, exactly as the
266
+ * recovery record's was: a proof by the credential's own unlock key is
267
+ * verified BEFORE decryption; a proof by any other key comes back as a
268
+ * pending state naming the signer, for the caller to settle with
269
+ * `verifyRecordProof` against the verified document of the account the
270
+ * credential-authenticated pointer names.
271
+ *
272
+ * @param options {object}
273
+ * @param options.record {unknown} the stored record envelope
274
+ * @param options.keyAgreementKey {IKeyAgreementKey} the credential's unlock
275
+ * KAK
276
+ * @param options.keyResolver {IKeyResolver}
277
+ * @param options.expectedKeyMultibase {string} the credential-derived
278
+ * unlock signing key's multibase
279
+ * @param options.bindingMacKey {Uint8Array} the credential-derived binding
280
+ * MAC key the record's account binding must verify under
281
+ * @returns {Promise<{ contents: UnlockRecordContents,
282
+ * proofState: UnlockRecordProofState }>}
283
+ */
284
+ export async function unwrapUnlockRecord({ record, keyAgreementKey, keyResolver, expectedKeyMultibase, bindingMacKey }) {
285
+ const { encryption, wrapped, proof } = parseRecordFrame({
286
+ record,
287
+ label: 'unlock'
288
+ });
289
+ const binding = unlockRecordBinding({ record });
290
+ const { bridge: rawBridge, ladder: rawLadder } = record;
291
+ if (rawBridge === undefined) {
292
+ throw new Error('The unlock record carries no bridge member; it predates the standing ' +
293
+ 'layout and the credential must be rebound.');
294
+ }
295
+ const bridge = parseSealedMember({ value: rawBridge, name: 'bridge' });
296
+ const ladder = rawLadder === undefined
297
+ ? undefined
298
+ : parseSealedMember({ value: rawLadder, name: 'ladder' });
299
+ // `parseRecordFrame` shape-checks the proof of a current-version frame, so
300
+ // it is present here.
301
+ const verificationMethod = proof.verificationMethod;
302
+ const keyMultibase = recordProofKeyMultibase({
303
+ verificationMethod,
304
+ label: 'unlock'
305
+ });
306
+ let proofState = {
307
+ pending: { verificationMethod, keyMultibase }
308
+ };
309
+ if (keyMultibase === expectedKeyMultibase) {
310
+ await verifyRecordProof({
311
+ record,
312
+ allowedKeyMultibases: expectedKeyMultibase,
313
+ label: 'unlock'
314
+ });
315
+ proofState = 'verified';
316
+ }
317
+ const shell = (await openMember({
318
+ member: { encryption, wrapped },
319
+ keyAgreementKey,
320
+ keyResolver
321
+ }));
322
+ if (typeof shell.controller !== 'string' || !shell.controller) {
323
+ throw new Error('Unlock record is missing a controller.');
324
+ }
325
+ const pointer = parseRecordPointer(shell.pointer);
326
+ if (!pointer) {
327
+ throw new Error('Unlock record is missing its account pointer.');
328
+ }
329
+ const createdAt = parseRecordCreatedAt({
330
+ value: shell.createdAt,
331
+ label: 'Unlock'
332
+ });
333
+ const bridgePlaintext = (await openMember({
334
+ member: bridge,
335
+ keyAgreementKey,
336
+ keyResolver
337
+ }));
338
+ if (bridgePlaintext.delegation === null ||
339
+ typeof bridgePlaintext.delegation !== 'object') {
340
+ throw new Error('Unlock record is missing its did.jsonl delegation.');
341
+ }
342
+ let ladderSeed;
343
+ if (ladder) {
344
+ const ladderPlaintext = (await openMember({
345
+ member: ladder,
346
+ keyAgreementKey,
347
+ keyResolver
348
+ }));
349
+ if (typeof ladderPlaintext.ladderSeed !== 'string') {
350
+ throw new Error('Unlock record has a malformed ladder member.');
351
+ }
352
+ try {
353
+ ladderSeed = base64urlnopad.decode(ladderPlaintext.ladderSeed);
354
+ }
355
+ catch {
356
+ throw new Error('Unlock record has a malformed ladder member.');
357
+ }
358
+ if (ladderSeed.length !== LADDER_SEED_BYTES) {
359
+ throw new Error('Unlock record has a malformed ladder member.');
360
+ }
361
+ }
362
+ const expectedTag = hmac(sha256, bindingMacKey, bindingMacInput({
363
+ controller: shell.controller,
364
+ pointer,
365
+ ...(ladderSeed ? { ladderSeed } : {})
366
+ }));
367
+ let servedTag;
368
+ try {
369
+ servedTag = base64urlnopad.decode(binding);
370
+ }
371
+ catch {
372
+ servedTag = null;
373
+ }
374
+ // `equalBytes` is @noble/ciphers' authentication-tag comparison (no early
375
+ // exit), so the check leaks nothing through timing.
376
+ if (servedTag === null || !equalBytes(servedTag, expectedTag)) {
377
+ throw new UnlockBindingError("The unlock record's account binding does not verify under this " +
378
+ 'credential; the record is refused as forged.');
379
+ }
380
+ return {
381
+ contents: {
382
+ controller: shell.controller,
383
+ ...(typeof shell.email === 'string' && shell.email
384
+ ? { email: shell.email }
385
+ : {}),
386
+ pointer,
387
+ delegation: bridgePlaintext.delegation,
388
+ ...(ladderSeed ? { ladderSeed } : {}),
389
+ createdAt
390
+ },
391
+ proofState
392
+ };
393
+ }
394
+ /**
395
+ * Re-mints an unlock record's bridge: the revocation-cascade path that
396
+ * replaces a rotted or expiring delegation while touching nothing else. The
397
+ * shell, the ladder member, and the binding are carried VERBATIM (the re-mint
398
+ * cannot decrypt any of them and does not need to -- each is self-contained
399
+ * and the binding covers the core), a fresh bridge is sealed to the
400
+ * credential's unlock KAK public half, and the frame is re-signed by the
401
+ * acting client's account key -- the mixed-signer case the reader settles
402
+ * against the verified document.
403
+ *
404
+ * A record with no binding cannot be re-minted ({@link UnlockBindingError});
405
+ * its credential must be rebound.
406
+ *
407
+ * @param options {object}
408
+ * @param options.record {unknown} the standing stored record
409
+ * @param options.delegation {IZcap} the freshly minted `did.jsonl`
410
+ * delegation
411
+ * @param options.keyAgreementKey {IKeyAgreementKey} the credential's unlock
412
+ * KAK, public half only
413
+ * @param options.signer {RecordSigner} the acting client's account key
414
+ * @returns {Promise<SignedUnlockRecord>}
415
+ */
416
+ export async function remintUnlockRecordBridge({ record, delegation, keyAgreementKey, signer }) {
417
+ const { encryption, wrapped } = parseRecordFrame({
418
+ record,
419
+ label: 'unlock'
420
+ });
421
+ const binding = unlockRecordBinding({ record });
422
+ const { ladder: rawLadder } = record;
423
+ const ladder = rawLadder === undefined
424
+ ? undefined
425
+ : parseSealedMember({ value: rawLadder, name: 'ladder' });
426
+ const bridge = await sealMember({ data: { delegation }, keyAgreementKey });
427
+ return (await signRecordFrame({
428
+ version: KEYRING_RECORD_VERSION,
429
+ encryption,
430
+ wrapped,
431
+ signer,
432
+ members: { binding, bridge, ...(ladder ? { ladder } : {}) }
433
+ }));
434
+ }
435
+ //# sourceMappingURL=unlockRecord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unlockRecord.js","sourceRoot":"","sources":["../../src/unlock/unlockRecord.ts"],"names":[],"mappings":"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"}