canary-kit 0.9.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 (69) hide show
  1. package/CANARY.md +1065 -0
  2. package/INTEGRATION.md +351 -0
  3. package/LICENSE +21 -0
  4. package/NIP-CANARY.md +624 -0
  5. package/README.md +187 -0
  6. package/SECURITY.md +92 -0
  7. package/dist/beacon.d.ts +104 -0
  8. package/dist/beacon.d.ts.map +1 -0
  9. package/dist/beacon.js +197 -0
  10. package/dist/beacon.js.map +1 -0
  11. package/dist/counter.d.ts +37 -0
  12. package/dist/counter.d.ts.map +1 -0
  13. package/dist/counter.js +62 -0
  14. package/dist/counter.js.map +1 -0
  15. package/dist/crypto.d.ts +111 -0
  16. package/dist/crypto.d.ts.map +1 -0
  17. package/dist/crypto.js +309 -0
  18. package/dist/crypto.js.map +1 -0
  19. package/dist/derive.d.ts +68 -0
  20. package/dist/derive.d.ts.map +1 -0
  21. package/dist/derive.js +85 -0
  22. package/dist/derive.js.map +1 -0
  23. package/dist/encoding.d.ts +56 -0
  24. package/dist/encoding.d.ts.map +1 -0
  25. package/dist/encoding.js +98 -0
  26. package/dist/encoding.js.map +1 -0
  27. package/dist/group.d.ts +185 -0
  28. package/dist/group.d.ts.map +1 -0
  29. package/dist/group.js +263 -0
  30. package/dist/group.js.map +1 -0
  31. package/dist/index.d.ts +10 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +12 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/nostr.d.ts +134 -0
  36. package/dist/nostr.d.ts.map +1 -0
  37. package/dist/nostr.js +175 -0
  38. package/dist/nostr.js.map +1 -0
  39. package/dist/presets.d.ts +26 -0
  40. package/dist/presets.d.ts.map +1 -0
  41. package/dist/presets.js +39 -0
  42. package/dist/presets.js.map +1 -0
  43. package/dist/session.d.ts +114 -0
  44. package/dist/session.d.ts.map +1 -0
  45. package/dist/session.js +173 -0
  46. package/dist/session.js.map +1 -0
  47. package/dist/sync-crypto.d.ts +66 -0
  48. package/dist/sync-crypto.d.ts.map +1 -0
  49. package/dist/sync-crypto.js +125 -0
  50. package/dist/sync-crypto.js.map +1 -0
  51. package/dist/sync.d.ts +191 -0
  52. package/dist/sync.d.ts.map +1 -0
  53. package/dist/sync.js +568 -0
  54. package/dist/sync.js.map +1 -0
  55. package/dist/token.d.ts +186 -0
  56. package/dist/token.d.ts.map +1 -0
  57. package/dist/token.js +344 -0
  58. package/dist/token.js.map +1 -0
  59. package/dist/verify.d.ts +45 -0
  60. package/dist/verify.d.ts.map +1 -0
  61. package/dist/verify.js +59 -0
  62. package/dist/verify.js.map +1 -0
  63. package/dist/wordlist.d.ts +28 -0
  64. package/dist/wordlist.d.ts.map +1 -0
  65. package/dist/wordlist.js +297 -0
  66. package/dist/wordlist.js.map +1 -0
  67. package/llms-full.txt +1461 -0
  68. package/llms.txt +180 -0
  69. package/package.json +144 -0
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ // src/index.ts
2
+ export { WORDLIST, WORDLIST_SIZE, getWord, indexOf, } from './wordlist.js';
3
+ export { getCounter, counterToBytes, counterFromEventId, DEFAULT_ROTATION_INTERVAL, MAX_COUNTER_OFFSET, } from './counter.js';
4
+ export { GROUP_CONTEXT, deriveVerificationWord, deriveVerificationPhrase, deriveDuressWord, deriveDuressPhrase, deriveCurrentWord, } from './derive.js';
5
+ export { verifyWord, } from './verify.js';
6
+ export { createGroup, getCurrentWord, getCurrentDuressWord, advanceCounter, reseed, addMember, removeMember, removeMemberAndReseed, syncCounter, dissolveGroup, } from './group.js';
7
+ export { PRESETS, } from './presets.js';
8
+ export { deriveBeaconKey, deriveDuressKey, encryptBeacon, decryptBeacon, buildDuressAlert, encryptDuressAlert, decryptDuressAlert, } from './beacon.js';
9
+ // --- CANARY Protocol (universal API) ---
10
+ export { MAX_TOLERANCE, deriveTokenBytes, deriveToken, deriveDuressTokenBytes, deriveDuressToken, verifyToken, deriveLivenessToken, } from './token.js';
11
+ export { encodeAsWords, encodeAsPin, encodeAsHex, encodeToken, DEFAULT_ENCODING, } from './encoding.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EACL,QAAQ,EACR,aAAa,EACb,OAAO,EACP,OAAO,GACR,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,UAAU,GAGX,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,MAAM,EACN,SAAS,EACT,YAAY,EACZ,qBAAqB,EACrB,WAAW,EACX,aAAa,GAGd,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,OAAO,GAGR,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,GAInB,MAAM,aAAa,CAAA;AAEpB,0CAA0C;AAC1C,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,mBAAmB,GAGpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EAEX,gBAAgB,GACjB,MAAM,eAAe,CAAA"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Canary Nostr event kinds (NIP-CANARY).
3
+ *
4
+ * - group + memberUpdate: parameterised replaceable (30000–39999)
5
+ * - seedDistribution, reseed, wordUsed: ephemeral (20000–29999)
6
+ * - beacon: ephemeral (20000–29999)
7
+ */
8
+ export declare const KINDS: {
9
+ readonly group: 38800;
10
+ readonly seedDistribution: 28800;
11
+ readonly memberUpdate: 38801;
12
+ readonly reseed: 28801;
13
+ readonly wordUsed: 28802;
14
+ readonly beacon: 20800;
15
+ };
16
+ /** Unsigned Nostr event (consumer signs with their own library). */
17
+ export interface UnsignedEvent {
18
+ kind: number;
19
+ content: string;
20
+ tags: string[][];
21
+ created_at: number;
22
+ }
23
+ export interface GroupEventParams {
24
+ groupId: string;
25
+ name: string;
26
+ members: string[];
27
+ rotationInterval: number;
28
+ wordCount: 1 | 2 | 3;
29
+ wordlist: string;
30
+ encryptedContent: string;
31
+ expiration?: number;
32
+ }
33
+ /**
34
+ * Build an unsigned kind 38800 group definition event.
35
+ *
36
+ * @param params - Group event parameters including groupId, name, members, and encrypted content.
37
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
38
+ * @throws {Error} If groupId/name are invalid, member pubkeys are malformed, rotationInterval is non-positive, or wordCount is not 1/2/3.
39
+ */
40
+ export declare function buildGroupEvent(params: GroupEventParams): UnsignedEvent;
41
+ export interface SeedDistributionParams {
42
+ recipientPubkey: string;
43
+ groupEventId: string;
44
+ encryptedContent: string;
45
+ }
46
+ /**
47
+ * Build an unsigned kind 28800 seed distribution event.
48
+ *
49
+ * @param params - Seed distribution parameters including recipient pubkey, group event ID, and encrypted seed.
50
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
51
+ * @throws {Error} If recipientPubkey or groupEventId are not valid 64-character hex strings.
52
+ */
53
+ export declare function buildSeedDistributionEvent(params: SeedDistributionParams): UnsignedEvent;
54
+ export interface MemberUpdateParams {
55
+ groupId: string;
56
+ action: 'add' | 'remove';
57
+ memberPubkey: string;
58
+ reseed: boolean;
59
+ encryptedContent: string;
60
+ }
61
+ /**
62
+ * Build an unsigned kind 38801 member update event (add or remove).
63
+ *
64
+ * @param params - Member update parameters including groupId, action ('add' | 'remove'), member pubkey, and reseed flag.
65
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
66
+ * @throws {Error} If action is not 'add' or 'remove', or pubkey/groupId are invalid.
67
+ */
68
+ export declare function buildMemberUpdateEvent(params: MemberUpdateParams): UnsignedEvent;
69
+ export interface ReseedParams {
70
+ groupEventId: string;
71
+ reason: 'member_removed' | 'compromise' | 'scheduled' | 'duress';
72
+ encryptedContent: string;
73
+ }
74
+ /**
75
+ * Build an unsigned kind 28801 reseed notification event.
76
+ *
77
+ * @param params - Reseed parameters including group event ID, reason, and encrypted new seed.
78
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
79
+ * @throws {Error} If groupEventId is not a valid 64-character hex string or reason is invalid.
80
+ */
81
+ export declare function buildReseedEvent(params: ReseedParams): UnsignedEvent;
82
+ export interface WordUsedParams {
83
+ groupEventId: string;
84
+ encryptedContent: string;
85
+ }
86
+ /**
87
+ * Build an unsigned kind 28802 word-used (burn-after-use) event.
88
+ *
89
+ * @param params - Word-used parameters including group event ID and encrypted content.
90
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
91
+ * @throws {Error} If groupEventId is not a valid 64-character hex string.
92
+ */
93
+ export declare function buildWordUsedEvent(params: WordUsedParams): UnsignedEvent;
94
+ export interface BeaconEventParams {
95
+ groupId: string;
96
+ encryptedContent: string;
97
+ expiration?: number;
98
+ }
99
+ /** Plaintext payload for kind 28800 (seed distribution). */
100
+ export interface SeedDistributionPayload {
101
+ seed: string;
102
+ /** Allows re-seeding mid-window without waiting for the next natural time rotation. */
103
+ counter_offset: number;
104
+ /** The group's d-tag value (group identifier). */
105
+ group_d: string;
106
+ }
107
+ /** Plaintext payload for kind 38800 encrypted content (group configuration). */
108
+ export interface GroupEventPayload {
109
+ description: string;
110
+ policies: {
111
+ invite_by: 'creator' | 'any_member';
112
+ reseed_by: 'creator' | 'any_admin';
113
+ };
114
+ }
115
+ /** Plaintext payload for kind 28801 (reseed notification). */
116
+ export interface ReseedPayload {
117
+ seed: string;
118
+ reason: 'member_removed' | 'compromise' | 'scheduled' | 'duress';
119
+ }
120
+ /** Plaintext payload for kind 28802 (word used / burn-after-use). */
121
+ export interface WordUsedPayload {
122
+ new_counter: number;
123
+ used_by: string;
124
+ duress: boolean;
125
+ }
126
+ /**
127
+ * Build an unsigned kind 20800 beacon event.
128
+ *
129
+ * @param params - Beacon event parameters including groupId, encrypted content, and optional expiration.
130
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
131
+ * @throws {Error} If groupId is invalid or expiration is not a non-negative integer.
132
+ */
133
+ export declare function buildBeaconEvent(params: BeaconEventParams): UnsignedEvent;
134
+ //# sourceMappingURL=nostr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nostr.d.ts","sourceRoot":"","sources":["../src/nostr.ts"],"names":[],"mappings":"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"}
package/dist/nostr.js ADDED
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Canary Nostr event kinds (NIP-CANARY).
3
+ *
4
+ * - group + memberUpdate: parameterised replaceable (30000–39999)
5
+ * - seedDistribution, reseed, wordUsed: ephemeral (20000–29999)
6
+ * - beacon: ephemeral (20000–29999)
7
+ */
8
+ export const KINDS = {
9
+ group: 38_800,
10
+ seedDistribution: 28_800,
11
+ memberUpdate: 38_801,
12
+ reseed: 28_801,
13
+ wordUsed: 28_802,
14
+ beacon: 20_800,
15
+ };
16
+ function now() {
17
+ return Math.floor(Date.now() / 1000);
18
+ }
19
+ const HEX_64_RE = /^[0-9a-f]{64}$/;
20
+ const MAX_TAG_LENGTH = 256;
21
+ function validatePubkey(pubkey, label) {
22
+ if (!HEX_64_RE.test(pubkey)) {
23
+ throw new Error(`Invalid ${label}: expected 64 lowercase hex characters, got ${pubkey.length} chars`);
24
+ }
25
+ }
26
+ function validateEventId(eventId, label) {
27
+ if (!HEX_64_RE.test(eventId)) {
28
+ throw new Error(`Invalid ${label}: expected 64 lowercase hex characters, got ${eventId.length} chars`);
29
+ }
30
+ }
31
+ function validateTagString(value, label) {
32
+ if (typeof value !== 'string' || value.length === 0) {
33
+ throw new Error(`Invalid ${label}: must be a non-empty string`);
34
+ }
35
+ if (value.length > MAX_TAG_LENGTH) {
36
+ throw new Error(`Invalid ${label}: exceeds maximum length of ${MAX_TAG_LENGTH} characters`);
37
+ }
38
+ }
39
+ /**
40
+ * Build an unsigned kind 38800 group definition event.
41
+ *
42
+ * @param params - Group event parameters including groupId, name, members, and encrypted content.
43
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
44
+ * @throws {Error} If groupId/name are invalid, member pubkeys are malformed, rotationInterval is non-positive, or wordCount is not 1/2/3.
45
+ */
46
+ export function buildGroupEvent(params) {
47
+ validateTagString(params.groupId, 'groupId');
48
+ validateTagString(params.name, 'name');
49
+ for (const m of params.members)
50
+ validatePubkey(m, 'member pubkey');
51
+ if (!Number.isInteger(params.rotationInterval) || params.rotationInterval <= 0) {
52
+ throw new Error(`Invalid rotationInterval: must be a positive integer, got ${params.rotationInterval}`);
53
+ }
54
+ if (params.wordCount !== 1 && params.wordCount !== 2 && params.wordCount !== 3) {
55
+ throw new Error(`Invalid wordCount: must be 1, 2, or 3, got ${params.wordCount}`);
56
+ }
57
+ const tags = [
58
+ ['d', params.groupId],
59
+ ['name', params.name],
60
+ ...params.members.map((m) => ['p', m]),
61
+ ['rotation', String(params.rotationInterval)],
62
+ ['words', String(params.wordCount)],
63
+ ['wordlist', params.wordlist],
64
+ ];
65
+ if (params.expiration !== undefined) {
66
+ if (!Number.isInteger(params.expiration) || params.expiration < 0) {
67
+ throw new Error('expiration must be a non-negative integer');
68
+ }
69
+ tags.push(['expiration', String(params.expiration)]);
70
+ }
71
+ return { kind: KINDS.group, content: params.encryptedContent, tags, created_at: now() };
72
+ }
73
+ /**
74
+ * Build an unsigned kind 28800 seed distribution event.
75
+ *
76
+ * @param params - Seed distribution parameters including recipient pubkey, group event ID, and encrypted seed.
77
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
78
+ * @throws {Error} If recipientPubkey or groupEventId are not valid 64-character hex strings.
79
+ */
80
+ export function buildSeedDistributionEvent(params) {
81
+ validatePubkey(params.recipientPubkey, 'recipientPubkey');
82
+ validateEventId(params.groupEventId, 'groupEventId');
83
+ return {
84
+ kind: KINDS.seedDistribution,
85
+ content: params.encryptedContent,
86
+ tags: [
87
+ ['p', params.recipientPubkey],
88
+ ['e', params.groupEventId],
89
+ ],
90
+ created_at: now(),
91
+ };
92
+ }
93
+ /**
94
+ * Build an unsigned kind 38801 member update event (add or remove).
95
+ *
96
+ * @param params - Member update parameters including groupId, action ('add' | 'remove'), member pubkey, and reseed flag.
97
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
98
+ * @throws {Error} If action is not 'add' or 'remove', or pubkey/groupId are invalid.
99
+ */
100
+ export function buildMemberUpdateEvent(params) {
101
+ if (params.action !== 'add' && params.action !== 'remove') {
102
+ throw new Error(`Invalid action: must be 'add' or 'remove', got '${params.action}'`);
103
+ }
104
+ validatePubkey(params.memberPubkey, 'memberPubkey');
105
+ validateTagString(params.groupId, 'groupId');
106
+ return {
107
+ kind: KINDS.memberUpdate,
108
+ content: params.encryptedContent,
109
+ tags: [
110
+ ['d', params.groupId],
111
+ ['action', params.action],
112
+ ['p', params.memberPubkey],
113
+ ['reseed', String(params.reseed)],
114
+ ],
115
+ created_at: now(),
116
+ };
117
+ }
118
+ const VALID_RESEED_REASONS = new Set(['member_removed', 'compromise', 'scheduled', 'duress']);
119
+ /**
120
+ * Build an unsigned kind 28801 reseed notification event.
121
+ *
122
+ * @param params - Reseed parameters including group event ID, reason, and encrypted new seed.
123
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
124
+ * @throws {Error} If groupEventId is not a valid 64-character hex string or reason is invalid.
125
+ */
126
+ export function buildReseedEvent(params) {
127
+ validateEventId(params.groupEventId, 'groupEventId');
128
+ if (!VALID_RESEED_REASONS.has(params.reason)) {
129
+ throw new Error(`Invalid reason: must be one of ${[...VALID_RESEED_REASONS].join(', ')}, got '${params.reason}'`);
130
+ }
131
+ return {
132
+ kind: KINDS.reseed,
133
+ content: params.encryptedContent,
134
+ tags: [
135
+ ['e', params.groupEventId],
136
+ ['reason', params.reason],
137
+ ],
138
+ created_at: now(),
139
+ };
140
+ }
141
+ /**
142
+ * Build an unsigned kind 28802 word-used (burn-after-use) event.
143
+ *
144
+ * @param params - Word-used parameters including group event ID and encrypted content.
145
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
146
+ * @throws {Error} If groupEventId is not a valid 64-character hex string.
147
+ */
148
+ export function buildWordUsedEvent(params) {
149
+ validateEventId(params.groupEventId, 'groupEventId');
150
+ return {
151
+ kind: KINDS.wordUsed,
152
+ content: params.encryptedContent,
153
+ tags: [['e', params.groupEventId]],
154
+ created_at: now(),
155
+ };
156
+ }
157
+ /**
158
+ * Build an unsigned kind 20800 beacon event.
159
+ *
160
+ * @param params - Beacon event parameters including groupId, encrypted content, and optional expiration.
161
+ * @returns An {@link UnsignedEvent} ready to be signed and published.
162
+ * @throws {Error} If groupId is invalid or expiration is not a non-negative integer.
163
+ */
164
+ export function buildBeaconEvent(params) {
165
+ validateTagString(params.groupId, 'groupId');
166
+ const tags = [['h', params.groupId]];
167
+ if (params.expiration !== undefined) {
168
+ if (!Number.isInteger(params.expiration) || params.expiration < 0) {
169
+ throw new Error('expiration must be a non-negative integer');
170
+ }
171
+ tags.push(['expiration', String(params.expiration)]);
172
+ }
173
+ return { kind: KINDS.beacon, content: params.encryptedContent, tags, created_at: now() };
174
+ }
175
+ //# sourceMappingURL=nostr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nostr.js","sourceRoot":"","sources":["../src/nostr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /** Named threat-profile preset identifier. */
2
+ export type PresetName = 'family' | 'field-ops' | 'enterprise' | 'event';
3
+ /**
4
+ * A threat-profile preset — pre-configured group settings optimised for
5
+ * a specific risk level and use case.
6
+ */
7
+ export interface GroupPreset {
8
+ /** Words per verification challenge. */
9
+ wordCount: 1 | 2 | 3;
10
+ /** Rotation interval in seconds. Must be a positive integer. */
11
+ rotationInterval: number;
12
+ /** Human-readable description of the preset's trade-offs. */
13
+ description: string;
14
+ }
15
+ /**
16
+ * Built-in threat-profile presets.
17
+ *
18
+ * | Preset | Words | Rotation | Use case |
19
+ * |--------------|-------|----------|------------------------------------|
20
+ * | `family` | 1 | 7 days | Casual family/friend verification |
21
+ * | `field-ops` | 2 | 24 hours | Journalism, activism, field work |
22
+ * | `enterprise` | 2 | 48 hours | Corporate incident response |
23
+ * | `event` | 1 | 4 hours | Conferences, festivals, meetups |
24
+ */
25
+ export declare const PRESETS: Readonly<Record<PresetName, Readonly<GroupPreset>>>;
26
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAEA,8CAA8C;AAC9C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAA;AAExE;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACpB,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CA8BtE,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { DEFAULT_ROTATION_INTERVAL } from './counter.js';
2
+ /**
3
+ * Built-in threat-profile presets.
4
+ *
5
+ * | Preset | Words | Rotation | Use case |
6
+ * |--------------|-------|----------|------------------------------------|
7
+ * | `family` | 1 | 7 days | Casual family/friend verification |
8
+ * | `field-ops` | 2 | 24 hours | Journalism, activism, field work |
9
+ * | `enterprise` | 2 | 48 hours | Corporate incident response |
10
+ * | `event` | 1 | 4 hours | Conferences, festivals, meetups |
11
+ */
12
+ export const PRESETS = Object.freeze({
13
+ family: Object.freeze({
14
+ wordCount: 1,
15
+ rotationInterval: DEFAULT_ROTATION_INTERVAL,
16
+ description: 'Casual verification for family and friends. Single word, weekly rotation. ' +
17
+ 'Adequate for live voice/video calls where the attacker gets one attempt. ' +
18
+ 'NOT suitable for text-based verification — 11 bits of entropy is trivially brute-forceable without rate limiting.',
19
+ }),
20
+ 'field-ops': Object.freeze({
21
+ wordCount: 2,
22
+ rotationInterval: 86_400,
23
+ description: 'High-security preset for journalism, activism, and field operations. ' +
24
+ 'Two-word phrases (~22 bits) with daily rotation. Use burn-after-use for maximum protection.',
25
+ }),
26
+ enterprise: Object.freeze({
27
+ wordCount: 2,
28
+ rotationInterval: 172_800,
29
+ description: 'Enterprise incident response. Two-word phrases with 48-hour rotation. ' +
30
+ 'Balances security with operational convenience for larger teams.',
31
+ }),
32
+ event: Object.freeze({
33
+ wordCount: 1,
34
+ rotationInterval: 14_400,
35
+ description: 'Temporary groups for conferences, festivals, and meetups. ' +
36
+ 'Single word with 4-hour rotation. Fast setup, easy to share at the door.',
37
+ }),
38
+ });
39
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAkBxD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,OAAO,GAAwD,MAAM,CAAC,MAAM,CAAC;IACxF,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;QACpB,SAAS,EAAE,CAAC;QACZ,gBAAgB,EAAE,yBAAyB;QAC3C,WAAW,EACT,4EAA4E;YAC5E,2EAA2E;YAC3E,mHAAmH;KACtH,CAAC;IACF,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC;QACzB,SAAS,EAAE,CAAC;QACZ,gBAAgB,EAAE,MAAM;QACxB,WAAW,EACT,uEAAuE;YACvE,6FAA6F;KAChG,CAAC;IACF,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;QACxB,SAAS,EAAE,CAAC;QACZ,gBAAgB,EAAE,OAAO;QACzB,WAAW,EACT,wEAAwE;YACxE,kEAAkE;KACrE,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC;QACZ,gBAAgB,EAAE,MAAM;QACxB,WAAW,EACT,4DAA4D;YAC5D,0EAA0E;KAC7E,CAAC;CACH,CAAC,CAAA"}
@@ -0,0 +1,114 @@
1
+ import { type TokenVerifyResult, type DirectionalPair } from './token.js';
2
+ import type { TokenEncoding } from './encoding.js';
3
+ /**
4
+ * Generate a cryptographically secure 256-bit seed.
5
+ * Uses the global `crypto.getRandomValues` (Web Crypto API).
6
+ *
7
+ * @returns A 32-byte Uint8Array containing cryptographically secure random bytes.
8
+ */
9
+ export declare function generateSeed(): Uint8Array;
10
+ /**
11
+ * Derive a seed deterministically from a master key and string components.
12
+ *
13
+ * Algorithm: HMAC-SHA256(masterKey, utf8(components[0]) || 0x00 || utf8(components[1]) || ...)
14
+ *
15
+ * Null-byte separators prevent concatenation ambiguity.
16
+ *
17
+ * @param masterKey - Master key (hex string or Uint8Array, minimum 16 bytes).
18
+ * @param components - One or more string components for domain separation.
19
+ * @returns A deterministic 32-byte seed derived via HMAC-SHA256.
20
+ * @throws {RangeError} If master key is shorter than 16 bytes.
21
+ */
22
+ export declare function deriveSeed(masterKey: Uint8Array | string, ...components: string[]): Uint8Array;
23
+ /** Named session preset identifier. */
24
+ export type SessionPresetName = 'call' | 'handoff';
25
+ /** A session preset — pre-configured settings for a specific use case. */
26
+ export interface SessionPreset {
27
+ /** Words per token. */
28
+ wordCount: number;
29
+ /** Rotation interval in seconds (0 = fixed counter, single-use). */
30
+ rotationSeconds: number;
31
+ /** Counter tolerance window. */
32
+ tolerance: number;
33
+ /** Whether this is a directional (two-party) preset. */
34
+ directional: boolean;
35
+ /** Human-readable description. */
36
+ description: string;
37
+ }
38
+ /**
39
+ * Built-in session presets for directional verification.
40
+ *
41
+ * | Preset | Words | Rotation | Tolerance | Use case |
42
+ * |-----------|-------|------------|-----------|------------------------------|
43
+ * | `call` | 1 | 30 seconds | 1 | Phone verification |
44
+ * | `handoff` | 1 | single-use | 0 | Physical handoff (rideshare) |
45
+ */
46
+ export declare const SESSION_PRESETS: Readonly<Record<SessionPresetName, Readonly<SessionPreset>>>;
47
+ /** Configuration for creating a directional verification session. */
48
+ export interface SessionConfig {
49
+ /** Shared secret (hex string or Uint8Array). */
50
+ secret: Uint8Array | string;
51
+ /** Namespace prefix for context strings (e.g. 'aviva', 'dispatch'). */
52
+ namespace: string;
53
+ /** The two roles in the session (e.g. ['caller', 'agent']). */
54
+ roles: [string, string];
55
+ /** Which role I am. */
56
+ myRole: string;
57
+ /** Rotation interval in seconds (default: 30). */
58
+ rotationSeconds?: number;
59
+ /** Token encoding (default: words, count from preset or 1). */
60
+ encoding?: TokenEncoding;
61
+ /** Counter tolerance window (default: from preset or 0). */
62
+ tolerance?: number;
63
+ /**
64
+ * Their identity string for duress detection (e.g. customer ID).
65
+ *
66
+ * **WARNING:** When omitted, duress detection is completely disabled —
67
+ * a duress token from the other party will return `'invalid'` instead of
68
+ * `'duress'`. If duress detection is safety-critical for your use case,
69
+ * always provide this field.
70
+ */
71
+ theirIdentity?: string;
72
+ /** Session preset (overrides rotationSeconds, tolerance, encoding). */
73
+ preset?: SessionPresetName;
74
+ /** Fixed counter for single-use / handoff mode (ignores time-based rotation). */
75
+ counter?: number;
76
+ }
77
+ /** A role-aware, time-managed session for two-party verification. */
78
+ export interface Session {
79
+ /** Get the current counter (time-based or fixed). */
80
+ counter(nowSec?: number): number;
81
+ /** Get the token I speak to prove my identity. */
82
+ myToken(nowSec?: number): string;
83
+ /** Get the token I expect to hear from the other party. */
84
+ theirToken(nowSec?: number): string;
85
+ /** Verify a word spoken to me against the other party's context. */
86
+ verify(spoken: string, nowSec?: number): TokenVerifyResult;
87
+ /** Get both tokens at once, keyed by role name. */
88
+ pair(nowSec?: number): DirectionalPair;
89
+ }
90
+ /**
91
+ * Create a directional verification session.
92
+ *
93
+ * Wraps the low-level token API with role awareness, time management,
94
+ * and optional duress detection.
95
+ *
96
+ * @param config - Session configuration including secret, namespace, roles, and optional preset.
97
+ * @returns A {@link Session} object with `myToken()`, `theirToken()`, `verify()`, `counter()`, and `pair()` methods.
98
+ * @throws {Error} If namespace is empty or contains null bytes, roles are invalid, or myRole is not in roles.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const session = createSession({
103
+ * secret: sharedSeed,
104
+ * namespace: 'aviva',
105
+ * roles: ['caller', 'agent'],
106
+ * myRole: 'agent',
107
+ * preset: 'call',
108
+ * })
109
+ * session.myToken() // word I speak
110
+ * session.theirToken() // word I expect to hear
111
+ * ```
112
+ */
113
+ export declare function createSession(config: SessionConfig): Session;
114
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAIlD;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,UAAU,CAIzC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,UAAU,GAAG,MAAM,EAC9B,GAAG,UAAU,EAAE,MAAM,EAAE,GACtB,UAAU,CAWZ;AAED,uCAAuC;AACvC,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAAA;AAElD,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAA;IACvB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,WAAW,EAAE,OAAO,CAAA;IACpB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAoBvF,CAAA;AAEF,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,MAAM,EAAE,UAAU,GAAG,MAAM,CAAA;IAC3B,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB,+DAA+D;IAC/D,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uEAAuE;IACvE,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACtB,qDAAqD;IACrD,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAChC,kDAAkD;IAClD,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAChC,2DAA2D;IAC3D,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACnC,oEAAoE;IACpE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAA;IAC1D,mDAAmD;IACnD,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,eAAe,CAAA;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CA0F5D"}