@forgesworn/fold-kit 0.5.0 → 0.5.1
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/dist/epoch.d.ts +4 -0
- package/dist/member-epoch.d.ts +5 -0
- package/dist/member-epoch.js +4 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
package/dist/epoch.d.ts
CHANGED
|
@@ -257,6 +257,10 @@ export type EpochGrant = {
|
|
|
257
257
|
epoch: 0;
|
|
258
258
|
};
|
|
259
259
|
removed: string[];
|
|
260
|
+
/** Present on a member's answer through `requestRoomEpoch({ members })`:
|
|
261
|
+
* the epochs it carried between the requester's and `epoch`. See
|
|
262
|
+
* `MemberEpochGrant.passed`. The authority's own answer has none. */
|
|
263
|
+
passed?: RoomEpoch[];
|
|
260
264
|
refused?: undefined;
|
|
261
265
|
} | {
|
|
262
266
|
refused: EpochRefusal;
|
package/dist/member-epoch.d.ts
CHANGED
|
@@ -156,6 +156,11 @@ export interface MemberEpochGrant {
|
|
|
156
156
|
epoch: RoomEpoch;
|
|
157
157
|
/** Cumulative: `opts.removed` plus every removal in the chain. */
|
|
158
158
|
removed: string[];
|
|
159
|
+
/** The epochs between the requester's and `epoch`, oldest first, each
|
|
160
|
+
* proven by the next rekey in the chain decrypting under it. Empty for a
|
|
161
|
+
* grant one epoch ahead. Kept, they let the requester read what was said
|
|
162
|
+
* in the epochs it skipped, and hand them on from its own member desk. */
|
|
163
|
+
passed: RoomEpoch[];
|
|
159
164
|
}
|
|
160
165
|
/**
|
|
161
166
|
* Verify a member's answer to one of this device's member requests. Null
|
package/dist/member-epoch.js
CHANGED
|
@@ -278,6 +278,7 @@ export function decodeMemberEpochGrant(event, opts) {
|
|
|
278
278
|
const removed = new Set([...(opts.removed ?? [])].map(normaliseHex));
|
|
279
279
|
let previous = opts.current;
|
|
280
280
|
let secret;
|
|
281
|
+
const passed = [];
|
|
281
282
|
for (let i = 0; i < length; i += 1) {
|
|
282
283
|
const evidence = readRekeyEvidence(body.rekeys[i], { roomId, authority: opts.authority, previous });
|
|
283
284
|
if (!evidence)
|
|
@@ -304,8 +305,10 @@ export function decodeMemberEpochGrant(event, opts) {
|
|
|
304
305
|
return null;
|
|
305
306
|
}
|
|
306
307
|
previous = deriveEpoch({ epoch: evidence.epoch, secret });
|
|
308
|
+
if (i < length - 1)
|
|
309
|
+
passed.push({ epoch: evidence.epoch, secret });
|
|
307
310
|
}
|
|
308
|
-
return { epoch: { epoch: top, secret: secret }, removed: [...removed].sort() };
|
|
311
|
+
return { epoch: { epoch: top, secret: secret }, removed: [...removed].sort(), passed };
|
|
309
312
|
}
|
|
310
313
|
catch {
|
|
311
314
|
return null;
|
package/llms.txt
CHANGED
|
@@ -79,7 +79,7 @@ Not yet published to npm under this API. Until it is, pin an immutable Git commi
|
|
|
79
79
|
- `encodeEpochGrant(opts)` / `decodeEpochGrant(event, opts)` - the authority's answer (secret, epoch-0, or a refusal `'removed' | 'closed'`)
|
|
80
80
|
- `epochRequestAdmission(opts)`, `deriveEpochRequestKey(roomKey)`
|
|
81
81
|
- `hostRoomEpoch(opts)` / `requestRoomEpoch(opts)` / `EpochRefusedError` - the live request/grant desk, both sides
|
|
82
|
-
- Member epoch catch-up (see `docs/member-epoch-catch-up.md`): `encodeRekeyEvent({ ..., commit: true })` writes `epochCommitment(roomId, epoch, secret)` into the rekey body; `hostMemberEpochDesk(opts)` lets any current member answer; `requestRoomEpoch({ ..., members: memberEpochSource(opts) })` asks the authority and members, first verifiable answer wins; `requestMemberEpoch(opts)` asks members alone. Kinds `MEMBER_EPOCH_KINDS` = `{ REQUEST: 20471, GRANT: 20472 }`. A member grant carries the authority-signed rekeys from the asker's epoch to the current one; the asker verifies the chain itself (`decodeMemberEpochGrant`) and refuses a last epoch with no commitment (legacy: authority only), a chain that removes it or closes the room, and one that stops short of `expected`. Codecs: `encodeMemberEpochRequest`, `decodeMemberEpochRequest`, `encodeMemberEpochGrant`, `readRekeyEvidence`, `deriveMemberEpochRequestKey`, `MAX_MEMBER_EPOCH_CHAIN` (32)
|
|
82
|
+
- Member epoch catch-up (see `docs/member-epoch-catch-up.md`): `encodeRekeyEvent({ ..., commit: true })` writes `epochCommitment(roomId, epoch, secret)` into the rekey body; `hostMemberEpochDesk(opts)` lets any current member answer; `requestRoomEpoch({ ..., members: memberEpochSource(opts) })` asks the authority and members, first verifiable answer wins; `requestMemberEpoch(opts)` asks members alone. Kinds `MEMBER_EPOCH_KINDS` = `{ REQUEST: 20471, GRANT: 20472 }`. A member grant carries the authority-signed rekeys from the asker's epoch to the current one; the asker verifies the chain itself (`decodeMemberEpochGrant`) and refuses a last epoch with no commitment (legacy: authority only), a chain that removes it or closes the room, and one that stops short of `expected`. A verified grant is `{ epoch, removed, passed }`: `passed` holds the epochs between the asker's and `epoch`, oldest first, and `requestRoomEpoch` carries it as an optional `passed` when a member answered. Codecs: `encodeMemberEpochRequest`, `decodeMemberEpochRequest`, `encodeMemberEpochGrant`, `readRekeyEvidence`, `deriveMemberEpochRequestKey`, `MAX_MEMBER_EPOCH_CHAIN` (32)
|
|
83
83
|
- `canonicalAdmins(admins)` / `signAdmins(opts)` / `verifyAdmins(opts)` - the authority's signed admin list
|
|
84
84
|
- `canonicalChannels(channels)` / `signChannels(opts)` / `verifyChannels(opts)` - the authority's signed channel list; `CHANNEL_NAME`, `RESERVED_CHANNELS`
|
|
85
85
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgesworn/fold-kit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Circle primitives for private Nostr groups nobody operates: epoch keys, link invites, removal by rekey, device credentials.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|