@hwip/cli 0.0.1 → 0.1.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.
Files changed (245) hide show
  1. package/LICENSE +190 -0
  2. package/NOTICE +11 -0
  3. package/README.md +1983 -0
  4. package/dist/agent-list.d.ts +76 -0
  5. package/dist/agent-list.js +102 -0
  6. package/dist/agent-read.d.ts +105 -0
  7. package/dist/agent-read.js +309 -0
  8. package/dist/agent-rules-fetch.d.ts +51 -0
  9. package/dist/agent-rules-fetch.js +275 -0
  10. package/dist/agent-rules.default.d.ts +30 -0
  11. package/dist/agent-rules.default.js +305 -0
  12. package/dist/agent-session.d.ts +23 -0
  13. package/dist/agent-session.js +44 -0
  14. package/dist/agent-state.d.ts +84 -0
  15. package/dist/agent-state.js +188 -0
  16. package/dist/agent-target.d.ts +60 -0
  17. package/dist/agent-target.js +81 -0
  18. package/dist/agents.d.ts +31 -0
  19. package/dist/agents.js +75 -0
  20. package/dist/api.d.ts +28 -0
  21. package/dist/api.js +76 -0
  22. package/dist/args.d.ts +74 -0
  23. package/dist/args.js +254 -0
  24. package/dist/ask-context-attach.d.ts +73 -0
  25. package/dist/ask-context-attach.js +151 -0
  26. package/dist/ask-context-screen.d.ts +21 -0
  27. package/dist/ask-context-screen.js +49 -0
  28. package/dist/ask-context-switch.d.ts +31 -0
  29. package/dist/ask-context-switch.js +74 -0
  30. package/dist/ask-context.d.ts +84 -0
  31. package/dist/ask-context.js +172 -0
  32. package/dist/ask-pending.d.ts +47 -0
  33. package/dist/ask-pending.js +221 -0
  34. package/dist/ask-seal.d.ts +120 -0
  35. package/dist/ask-seal.js +179 -0
  36. package/dist/ask.d.ts +107 -0
  37. package/dist/ask.js +551 -0
  38. package/dist/blocked-prompt-seal.d.ts +39 -0
  39. package/dist/blocked-prompt-seal.js +92 -0
  40. package/dist/blocked-prompt.d.ts +62 -0
  41. package/dist/blocked-prompt.js +518 -0
  42. package/dist/channel.d.ts +67 -0
  43. package/dist/channel.js +136 -0
  44. package/dist/check-update.d.ts +28 -0
  45. package/dist/check-update.js +153 -0
  46. package/dist/cli.d.ts +3 -0
  47. package/dist/cli.js +813 -0
  48. package/dist/codex-config.d.ts +24 -0
  49. package/dist/codex-config.js +169 -0
  50. package/dist/codex-transcript.d.ts +59 -0
  51. package/dist/codex-transcript.js +373 -0
  52. package/dist/command-refusal.d.ts +56 -0
  53. package/dist/command-refusal.js +127 -0
  54. package/dist/command-scan.d.ts +46 -0
  55. package/dist/command-scan.js +154 -0
  56. package/dist/command-seal.d.ts +57 -0
  57. package/dist/command-seal.js +88 -0
  58. package/dist/command-seq.d.ts +30 -0
  59. package/dist/command-seq.js +150 -0
  60. package/dist/config.d.ts +156 -0
  61. package/dist/config.js +392 -0
  62. package/dist/core-sections.d.ts +18 -0
  63. package/dist/core-sections.js +28 -0
  64. package/dist/crypto.d.ts +278 -0
  65. package/dist/crypto.js +698 -0
  66. package/dist/desktop-notify.d.ts +33 -0
  67. package/dist/desktop-notify.js +49 -0
  68. package/dist/device-directory.d.ts +36 -0
  69. package/dist/device-directory.js +97 -0
  70. package/dist/device-presence.d.ts +17 -0
  71. package/dist/device-presence.js +62 -0
  72. package/dist/downloads.d.ts +29 -0
  73. package/dist/downloads.js +106 -0
  74. package/dist/errors.d.ts +12 -0
  75. package/dist/errors.js +28 -0
  76. package/dist/file-crypto.d.ts +94 -0
  77. package/dist/file-crypto.js +278 -0
  78. package/dist/file-view-budget.d.ts +15 -0
  79. package/dist/file-view-budget.js +34 -0
  80. package/dist/file-view-switch.d.ts +28 -0
  81. package/dist/file-view-switch.js +122 -0
  82. package/dist/file-view.d.ts +108 -0
  83. package/dist/file-view.js +327 -0
  84. package/dist/gate.d.ts +141 -0
  85. package/dist/gate.js +336 -0
  86. package/dist/gemini-transcript.d.ts +32 -0
  87. package/dist/gemini-transcript.js +189 -0
  88. package/dist/http-failure.d.ts +98 -0
  89. package/dist/http-failure.js +349 -0
  90. package/dist/hwip-core.generated.d.ts +7 -0
  91. package/dist/hwip-core.generated.js +14 -0
  92. package/dist/hwip-hook.d.ts +77 -0
  93. package/dist/hwip-hook.js +340 -0
  94. package/dist/index.d.ts +7 -0
  95. package/dist/index.js +14 -0
  96. package/dist/input-sequencer.d.ts +65 -0
  97. package/dist/input-sequencer.js +142 -0
  98. package/dist/insecure-url.d.ts +16 -0
  99. package/dist/insecure-url.js +76 -0
  100. package/dist/installer.d.ts +96 -0
  101. package/dist/installer.js +850 -0
  102. package/dist/inventory-offload.d.ts +49 -0
  103. package/dist/inventory-offload.js +209 -0
  104. package/dist/inventory-worker.d.ts +2 -0
  105. package/dist/inventory-worker.js +27 -0
  106. package/dist/jsonc-doc.d.ts +106 -0
  107. package/dist/jsonc-doc.js +354 -0
  108. package/dist/keep-awake.d.ts +32 -0
  109. package/dist/keep-awake.js +46 -0
  110. package/dist/key-changes.d.ts +48 -0
  111. package/dist/key-changes.js +140 -0
  112. package/dist/lan-auth.d.ts +140 -0
  113. package/dist/lan-auth.js +217 -0
  114. package/dist/lan-endpoint.d.ts +41 -0
  115. package/dist/lan-endpoint.js +115 -0
  116. package/dist/lan-receiver.d.ts +122 -0
  117. package/dist/lan-receiver.js +510 -0
  118. package/dist/lan-sender.d.ts +76 -0
  119. package/dist/lan-sender.js +184 -0
  120. package/dist/lan-transfer.d.ts +36 -0
  121. package/dist/lan-transfer.js +54 -0
  122. package/dist/listener-device-id.d.ts +20 -0
  123. package/dist/listener-device-id.js +133 -0
  124. package/dist/listener-log.d.ts +4 -0
  125. package/dist/listener-log.js +23 -0
  126. package/dist/listener-process.d.ts +200 -0
  127. package/dist/listener-process.js +470 -0
  128. package/dist/listener-service.d.ts +225 -0
  129. package/dist/listener-service.js +682 -0
  130. package/dist/listener-worktree-cleanup.d.ts +27 -0
  131. package/dist/listener-worktree-cleanup.js +62 -0
  132. package/dist/listener.d.ts +1325 -0
  133. package/dist/listener.js +5681 -0
  134. package/dist/login-address.d.ts +25 -0
  135. package/dist/login-address.js +97 -0
  136. package/dist/login-page.d.ts +29 -0
  137. package/dist/login-page.js +93 -0
  138. package/dist/login.d.ts +98 -0
  139. package/dist/login.js +388 -0
  140. package/dist/mcp-command.d.ts +45 -0
  141. package/dist/mcp-command.js +50 -0
  142. package/dist/mcp.d.ts +19 -0
  143. package/dist/mcp.js +29 -0
  144. package/dist/node-support.d.ts +19 -0
  145. package/dist/node-support.js +38 -0
  146. package/dist/notify-failure.d.ts +57 -0
  147. package/dist/notify-failure.js +150 -0
  148. package/dist/opencode-transcript.d.ts +139 -0
  149. package/dist/opencode-transcript.js +390 -0
  150. package/dist/optional-features.d.ts +6 -0
  151. package/dist/optional-features.js +19 -0
  152. package/dist/pane-fit.d.ts +40 -0
  153. package/dist/pane-fit.js +119 -0
  154. package/dist/peer-key.d.ts +33 -0
  155. package/dist/peer-key.js +34 -0
  156. package/dist/pi-transcript.d.ts +26 -0
  157. package/dist/pi-transcript.js +255 -0
  158. package/dist/presence.d.ts +14 -0
  159. package/dist/presence.js +124 -0
  160. package/dist/private-files.d.ts +51 -0
  161. package/dist/private-files.js +218 -0
  162. package/dist/project-switch.d.ts +19 -0
  163. package/dist/project-switch.js +60 -0
  164. package/dist/redact.d.ts +10 -0
  165. package/dist/redact.js +21 -0
  166. package/dist/remote-agents.d.ts +410 -0
  167. package/dist/remote-agents.js +1218 -0
  168. package/dist/remote-hook.d.ts +12 -0
  169. package/dist/remote-hook.js +196 -0
  170. package/dist/replace-file.d.ts +50 -0
  171. package/dist/replace-file.js +328 -0
  172. package/dist/schedule-command.d.ts +35 -0
  173. package/dist/schedule-command.js +260 -0
  174. package/dist/schedule-launch.d.ts +15 -0
  175. package/dist/schedule-launch.js +24 -0
  176. package/dist/schedule-ready.d.ts +44 -0
  177. package/dist/schedule-ready.js +71 -0
  178. package/dist/schedule-remote.d.ts +77 -0
  179. package/dist/schedule-remote.js +167 -0
  180. package/dist/schedule-runner.d.ts +89 -0
  181. package/dist/schedule-runner.js +452 -0
  182. package/dist/schedule.d.ts +149 -0
  183. package/dist/schedule.js +428 -0
  184. package/dist/secret-mask.d.ts +29 -0
  185. package/dist/secret-mask.js +245 -0
  186. package/dist/self-register.d.ts +45 -0
  187. package/dist/self-register.js +67 -0
  188. package/dist/send.d.ts +56 -0
  189. package/dist/send.js +104 -0
  190. package/dist/session-diff.d.ts +161 -0
  191. package/dist/session-diff.js +445 -0
  192. package/dist/session-registry.d.ts +143 -0
  193. package/dist/session-registry.js +216 -0
  194. package/dist/sessions-report.d.ts +59 -0
  195. package/dist/sessions-report.js +99 -0
  196. package/dist/shell-audit.d.ts +34 -0
  197. package/dist/shell-audit.js +47 -0
  198. package/dist/subagent-transcripts.d.ts +167 -0
  199. package/dist/subagent-transcripts.js +437 -0
  200. package/dist/subscriber-trust.d.ts +128 -0
  201. package/dist/subscriber-trust.js +397 -0
  202. package/dist/templates.d.ts +105 -0
  203. package/dist/templates.js +871 -0
  204. package/dist/tmux-install.d.ts +44 -0
  205. package/dist/tmux-install.js +65 -0
  206. package/dist/tmux-liveness.d.ts +45 -0
  207. package/dist/tmux-liveness.js +71 -0
  208. package/dist/tmux-pane.d.ts +55 -0
  209. package/dist/tmux-pane.js +126 -0
  210. package/dist/tmux-socket.d.ts +20 -0
  211. package/dist/tmux-socket.js +292 -0
  212. package/dist/todo-fold.d.ts +31 -0
  213. package/dist/todo-fold.js +102 -0
  214. package/dist/transcript-tail.d.ts +312 -0
  215. package/dist/transcript-tail.js +718 -0
  216. package/dist/trust-command.d.ts +49 -0
  217. package/dist/trust-command.js +200 -0
  218. package/dist/trust-lock.d.ts +26 -0
  219. package/dist/trust-lock.js +94 -0
  220. package/dist/trust-pins.d.ts +37 -0
  221. package/dist/trust-pins.js +82 -0
  222. package/dist/turn-recorder-wire.d.ts +70 -0
  223. package/dist/turn-recorder-wire.js +165 -0
  224. package/dist/turn-recorder.d.ts +190 -0
  225. package/dist/turn-recorder.js +695 -0
  226. package/dist/turn-ring.d.ts +93 -0
  227. package/dist/turn-ring.js +418 -0
  228. package/dist/turn-watch.d.ts +177 -0
  229. package/dist/turn-watch.js +630 -0
  230. package/dist/types.d.ts +63 -0
  231. package/dist/types.js +2 -0
  232. package/dist/uninstall.d.ts +55 -0
  233. package/dist/uninstall.js +507 -0
  234. package/dist/usage.d.ts +17 -0
  235. package/dist/usage.js +421 -0
  236. package/dist/verify.d.ts +47 -0
  237. package/dist/verify.js +396 -0
  238. package/dist/worktree.d.ts +144 -0
  239. package/dist/worktree.js +310 -0
  240. package/dist/wrapper.d.ts +254 -0
  241. package/dist/wrapper.js +704 -0
  242. package/dist/ws-url.d.ts +109 -0
  243. package/dist/ws-url.js +202 -0
  244. package/package.json +78 -10
  245. package/bin/hwip.js +0 -3
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Per-device encryption for the Hook SDK — self-contained ECDH P-256 +
3
+ * AES-256-GCM. Mirrors @hwip/crypto API but bundled inline (no external
4
+ * dependency). Uses Web Crypto API via node:crypto webcrypto, imported rather
5
+ * than read off the `crypto` global.
6
+ *
7
+ * How it works (ADR-0007):
8
+ *
9
+ * This host holds its own ECDH keypair in ~/.hwip/device-keys.json. The
10
+ * private half is generated here and never leaves — the server only ever
11
+ * sees public keys. A push is encrypted once with a random AES key, and
12
+ * that key is wrapped separately for each of the user's registered devices
13
+ * using ECDH(this host, that device). Same keypair the stream frames below
14
+ * already used; push and file bodies now share it.
15
+ *
16
+ * What it does not give you:
17
+ * • Forward secrecy — the ECDH secret for a given (sender, device) pair is
18
+ * static, so a compromise of either private key retroactively opens every
19
+ * push wrapped for that pair.
20
+ * • Authenticity beyond the key pairing — nothing signs `senderPublicKey`.
21
+ *
22
+ * Superseded scheme: a single account-wide keypair whose private half the
23
+ * backend escrowed so it could sync to new devices. Key escrow was removed
24
+ * server-side and `GET /users/me/keys` has returned a public
25
+ * key only ever since. This client used to react by generating a fresh
26
+ * account keypair and PUTting it back — which overwrote the account public
27
+ * key and encrypted to a key no device held. Both that upload path and the
28
+ * account keypair are gone.
29
+ */
30
+ /** One target device, as returned by `GET /devices`. */
31
+ export interface DeviceRecipient {
32
+ deviceId: string;
33
+ /** Base64 SPKI of that device's per-device public key. */
34
+ publicKey: string;
35
+ }
36
+ /** deviceId → JSON `{ encryptedKey, keyIv }`, the wire shape the clients parse. */
37
+ export type DeviceKeyMap = Record<string, string>;
38
+ /**
39
+ * Keep only devices this host can encrypt for: a device without a public key
40
+ * has never run a build that registers one, and wrapping for it produces a push
41
+ * it cannot open.
42
+ */
43
+ export declare const selectRecipients: (devices: {
44
+ deviceId: string;
45
+ publicKey?: string;
46
+ }[]) => DeviceRecipient[];
47
+ /** A device a person reads pushes on: the iOS or Android app. A push or question nobody can read on a phone is not sent. */
48
+ export declare const isAppDevice: (d: {
49
+ type?: string;
50
+ }) => boolean;
51
+ /**
52
+ * Encrypt a push body for the given recipient devices.
53
+ *
54
+ * Returns the wire fields the API expects: `body` carries the ciphertext and
55
+ * IV, `deviceKeyMap` the per-device wrapped keys, `senderPublicKey` the half
56
+ * recipients need to derive the same secret back.
57
+ */
58
+ export declare const encryptPushBodyForDevices: (input: PushBodyInput, recipients: DeviceRecipient[]) => Promise<{
59
+ body: string;
60
+ deviceKeyMap: DeviceKeyMap;
61
+ senderPublicKey: string;
62
+ isEncrypted: true;
63
+ }>;
64
+ /**
65
+ * Encrypt file content for the given recipient devices.
66
+ */
67
+ export declare const encryptFileForDevices: (content: string | Buffer, recipients: DeviceRecipient[]) => Promise<{
68
+ ciphertext: Buffer;
69
+ iv: string;
70
+ deviceKeyMap: DeviceKeyMap;
71
+ }>;
72
+ /**
73
+ * Load-or-create the per-device keypair. Local-only — no server round-trip,
74
+ * no upload. Safe to call concurrently (dedupes to one init). Returns the
75
+ * exported public key (Base64 SPKI).
76
+ */
77
+ export declare const initDeviceCrypto: () => Promise<string>;
78
+ export declare const getDevicePublicKey: () => string | null;
79
+ /**
80
+ * Raw ECDH secret between this device and `peerPublicKeyRaw` (Base64
81
+ * SPKI) — the 32-byte x-coordinate WebCrypto's `deriveBits` yields for
82
+ * P-256. Input to the local-transfer MAC key (lan-auth.ts `deriveLanKey`);
83
+ * never used as a key by itself. Requires initDeviceCrypto().
84
+ */
85
+ export declare const deriveLanSharedSecret: (peerPublicKeyRaw: string) => Promise<Buffer>;
86
+ export declare const unwrapDeviceKey: (entryJson: string, senderPublicKeyRaw: string) => Promise<Buffer>;
87
+ /**
88
+ * The label a sealed REST command carries inside its body (M5 D8): which
89
+ * session on which machine it is for, and a number that only grows per
90
+ * sender. A sealed body without one is not a command. `from` is the id of the
91
+ * computer that sent it, when it names itself.
92
+ */
93
+ export interface SealedCommandLabel {
94
+ n: number;
95
+ session: string;
96
+ device: string;
97
+ from?: string;
98
+ }
99
+ /** One button of a sealed question: `id` and `style` also reach the server in the clear, `label` never does. */
100
+ export interface SealedAskAction {
101
+ id: string;
102
+ label: string;
103
+ style?: string;
104
+ }
105
+ /**
106
+ * The label a sealed question carries inside its body: the asker's own random
107
+ * `id` (the answer must echo it, so a relay cannot pass an old question's answer
108
+ * off as a new one's), the Machine Device that asks, and the wording the server
109
+ * must not read.
110
+ */
111
+ export interface SealedAskLabel {
112
+ id: string;
113
+ device: string;
114
+ actions?: SealedAskAction[];
115
+ placeholder?: string;
116
+ }
117
+ /**
118
+ * The summary a sealed question may carry in its body under `context` (F3): what the asking session has changed
119
+ * and how much of its screen the original holds. It is a new key of the same plaintext JSON — the envelope and
120
+ * the schema are unchanged, and a reader that does not know the key drops it with the rest of the keys it does
121
+ * not read. The original (the masked diff and screen) is never in the body: it is the question's sealed attachment.
122
+ */
123
+ export interface SealedAskContext {
124
+ diff: 'ok' | 'no_repo' | 'failed';
125
+ files: number;
126
+ added: number;
127
+ removed: number;
128
+ listed: {
129
+ path: string;
130
+ status: 'M' | 'A' | 'D' | '?';
131
+ added: number;
132
+ removed: number;
133
+ binary?: true;
134
+ }[];
135
+ moreFiles: number;
136
+ screenLines: number;
137
+ masked: number;
138
+ cut: {
139
+ diff: boolean;
140
+ screen: boolean;
141
+ };
142
+ }
143
+ /** The label a sealed answer carries: which question it answers and what was chosen. */
144
+ export interface SealedAnswerLabel {
145
+ ask: string;
146
+ actionId?: string;
147
+ exit?: true;
148
+ }
149
+ /** What `encryptPushBodyForDevices` seals. Keys left out are left out of the plaintext JSON. */
150
+ export interface PushBodyInput {
151
+ title?: string;
152
+ body?: string;
153
+ url?: string;
154
+ cmd?: SealedCommandLabel;
155
+ ask?: SealedAskLabel;
156
+ answer?: SealedAnswerLabel;
157
+ files?: SealedFileMeta[];
158
+ /**
159
+ * Named keys (the blocked prompt's answer) inside a sealed command. Read
160
+ * back only when every entry is a string; the listener allowlists the names.
161
+ */
162
+ keys?: string[];
163
+ /** The blocked prompt id the keys answer, inside a sealed command. */
164
+ ifPrompt?: string;
165
+ context?: SealedAskContext;
166
+ }
167
+ /**
168
+ * One sealed attachment as the sealed body names it (M5): its IV — fresh per
169
+ * file, so an attachment from another message does not match — and what it
170
+ * really is. The list binds the attachments to the message, in order.
171
+ * `chunk` is there for a file sealed in chunks (`file-chunk-v1`): the plain
172
+ * bytes in each piece, and `iv` is then the 7-byte prefix of the piece nonces.
173
+ */
174
+ export interface SealedFileMeta {
175
+ iv: string;
176
+ name: string;
177
+ type: string;
178
+ size: number;
179
+ chunk?: number;
180
+ }
181
+ /** The `code` of the errors above that a shorter choice list fixes. */
182
+ export declare const ASK_CHOICES_CODE = "ask-choices-over-limits";
183
+ /**
184
+ * Decrypt a push body sealed by `encryptPushBodyForDevices` (any client's
185
+ * twin of it) for this device: `body` is the JSON `{ ciphertext, iv }`
186
+ * envelope, the message key comes out of this device's `deviceKeyMap` slot.
187
+ * Returns the `{ title, body, url }` the sender put in, the `cmd` label of a
188
+ * sealed command, the `ask` / `answer` label of a sealed question / answer and
189
+ * the `files` list, the sealed `keys` / `ifPrompt` of a blocked-prompt answer,
190
+ * and the `context` summary — each only when well formed. `context` is read from any body;
191
+ * whether it belongs there (a question) is the caller's to decide.
192
+ */
193
+ export declare const decryptPushBodyForDevice: (body: string, entryJson: string, senderPublicKeyRaw: string) => Promise<{
194
+ title?: string;
195
+ body?: string;
196
+ url?: string;
197
+ cmd?: SealedCommandLabel;
198
+ ask?: SealedAskLabel;
199
+ answer?: SealedAnswerLabel;
200
+ files?: SealedFileMeta[];
201
+ keys?: string[];
202
+ ifPrompt?: string;
203
+ /** A schedule request inside a sealed command (F8); its fields are the listener's to check. */
204
+ schedule?: Record<string, unknown>;
205
+ context?: SealedAskContext;
206
+ }>;
207
+ export type SealPurpose = 'stream.frame' | 'stream.input' | 'stream.alive' | 'stream.started' | 'screen.snapshot' | 'screen.history' | 'session.diff' | 'schedule.list' | 'turn.batch';
208
+ export interface SealedV2 {
209
+ v: 2;
210
+ /** Base64, 32 bytes — the HKDF salt, fresh per message. */
211
+ salt: string;
212
+ /** Base64, 12 bytes. */
213
+ iv: string;
214
+ /** Base64 ciphertext ‖ 16-byte tag. */
215
+ ciphertext: string;
216
+ /** Base64 SPKI of the sealing device. Covered by the seal (AAD). */
217
+ senderPublicKey: string;
218
+ }
219
+ /** Every field of a v2 envelope is relay JSON: check the shape before any of
220
+ * it reaches WebCrypto, so a malformed one is a refusal and not a throw from
221
+ * inside a Base64 decode. */
222
+ export declare const isSealedV2: (value: unknown) => value is SealedV2;
223
+ /**
224
+ * The X9.63 point of a device public key, or null when the string is not
225
+ * spelled as one. Only the spelling is checked: whether the 65 bytes are a
226
+ * point on the curve is left to the key import that follows, which is where
227
+ * `sealV2` and `openV2` reject one that is not.
228
+ *
229
+ * A device key has exactly one spelling here: standard padded Base64 of the
230
+ * 91-byte SPKI with an uncompressed point — what WebCrypto's
231
+ * `exportKey('spki')` and the app's CryptoKit `derRepresentation` both write.
232
+ * The same key spelled another way (a compressed point, unpadded Base64) is
233
+ * refused rather than normalised. With one spelling, two keys are the same
234
+ * exactly when their strings are, here and in the app, which cannot read the
235
+ * compressed form at all.
236
+ */
237
+ export declare const publicKeyPoint: (spkiBase64: string) => Buffer | null;
238
+ /**
239
+ * Who a sealed message is from, as far as a replay check can tell: the x
240
+ * coordinate of the sender's point, in hex (null for a string that is not a
241
+ * device key). A sealed push opens from the ECDH x coordinate alone — the
242
+ * secret is the same for a point and its mirror (x, p − y) — so a relay can
243
+ * hand the same box to the listener under the mirrored key without the
244
+ * phone's secret. The string of that key is another one, the sender is not.
245
+ * Pins and fingerprints still compare the whole key; only the question "have
246
+ * I taken this number from this sender" asks for x.
247
+ */
248
+ export declare const publicKeySender: (spkiBase64: string) => string | null;
249
+ /** Whether two strings are the same device public key. A string that is not
250
+ * in the one spelling `publicKeyPoint` takes equals nothing, itself included. */
251
+ export declare const samePublicKey: (a: string, b: string) => boolean;
252
+ /**
253
+ * A device public key as something two people can compare: the first 16 bytes
254
+ * of SHA-256 over its X9.63 point, as eight groups of four hex digits. The app
255
+ * prints the same string for the same key (`Envelope.fingerprint`), which is
256
+ * the point — `hwip trust` on this side, the device screen on that one. null
257
+ * for a string that is not a device key.
258
+ */
259
+ export declare const keyFingerprint: (spkiBase64: string) => string | null;
260
+ /**
261
+ * Seal `plaintext` for one recipient device, for one purpose. Requires
262
+ * initDeviceCrypto().
263
+ */
264
+ export declare const sealV2: (purpose: SealPurpose, plaintext: string, recipientPublicKey: string, context?: string) => Promise<SealedV2>;
265
+ /**
266
+ * Open a v2 envelope addressed to this device.
267
+ *
268
+ * Rejects rather than returning null, like every open here: a throw means the
269
+ * envelope was sealed by another key than `expectedSender`, for another
270
+ * device, purpose or context, was tampered with, or is not a v2 envelope.
271
+ *
272
+ * `expectedSender` is not optional: opening alone proves only that the sender
273
+ * holds the private half of `senderPublicKey`, and anyone can mint a keypair.
274
+ * Every caller knows who it is talking to; naming that key here is what turns
275
+ * "it opened" into "the peer sent it". Requires initDeviceCrypto().
276
+ */
277
+ export declare const openV2: (purpose: SealPurpose, envelope: SealedV2, expectedSender: string, context?: string) => Promise<string>;
278
+ //# sourceMappingURL=crypto.d.ts.map