morok-bot-sdk 1.0.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 (96) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +602 -0
  3. package/README.ru.md +602 -0
  4. package/dist/bot.d.ts +232 -0
  5. package/dist/bot.d.ts.map +1 -0
  6. package/dist/bot.js +558 -0
  7. package/dist/bot.js.map +1 -0
  8. package/dist/crypto/channel-cipher.d.ts +32 -0
  9. package/dist/crypto/channel-cipher.d.ts.map +1 -0
  10. package/dist/crypto/channel-cipher.js +77 -0
  11. package/dist/crypto/channel-cipher.js.map +1 -0
  12. package/dist/crypto/channel-key-store.d.ts +37 -0
  13. package/dist/crypto/channel-key-store.d.ts.map +1 -0
  14. package/dist/crypto/channel-key-store.js +149 -0
  15. package/dist/crypto/channel-key-store.js.map +1 -0
  16. package/dist/crypto/cross-signing.d.ts +57 -0
  17. package/dist/crypto/cross-signing.d.ts.map +1 -0
  18. package/dist/crypto/cross-signing.js +111 -0
  19. package/dist/crypto/cross-signing.js.map +1 -0
  20. package/dist/crypto/file-cipher.d.ts +36 -0
  21. package/dist/crypto/file-cipher.d.ts.map +1 -0
  22. package/dist/crypto/file-cipher.js +61 -0
  23. package/dist/crypto/file-cipher.js.map +1 -0
  24. package/dist/crypto/group-secret-cipher.d.ts +49 -0
  25. package/dist/crypto/group-secret-cipher.d.ts.map +1 -0
  26. package/dist/crypto/group-secret-cipher.js +69 -0
  27. package/dist/crypto/group-secret-cipher.js.map +1 -0
  28. package/dist/crypto/group-secret-store.d.ts +35 -0
  29. package/dist/crypto/group-secret-store.d.ts.map +1 -0
  30. package/dist/crypto/group-secret-store.js +149 -0
  31. package/dist/crypto/group-secret-store.js.map +1 -0
  32. package/dist/crypto/signal.d.ts +81 -0
  33. package/dist/crypto/signal.d.ts.map +1 -0
  34. package/dist/crypto/signal.js +125 -0
  35. package/dist/crypto/signal.js.map +1 -0
  36. package/dist/crypto/stores.d.ts +130 -0
  37. package/dist/crypto/stores.d.ts.map +1 -0
  38. package/dist/crypto/stores.js +314 -0
  39. package/dist/crypto/stores.js.map +1 -0
  40. package/dist/flow/attachments.d.ts +110 -0
  41. package/dist/flow/attachments.d.ts.map +1 -0
  42. package/dist/flow/attachments.js +409 -0
  43. package/dist/flow/attachments.js.map +1 -0
  44. package/dist/flow/conv-cache.d.ts +36 -0
  45. package/dist/flow/conv-cache.d.ts.map +1 -0
  46. package/dist/flow/conv-cache.js +84 -0
  47. package/dist/flow/conv-cache.js.map +1 -0
  48. package/dist/flow/direct.d.ts +109 -0
  49. package/dist/flow/direct.d.ts.map +1 -0
  50. package/dist/flow/direct.js +346 -0
  51. package/dist/flow/direct.js.map +1 -0
  52. package/dist/flow/groups.d.ts +146 -0
  53. package/dist/flow/groups.d.ts.map +1 -0
  54. package/dist/flow/groups.js +768 -0
  55. package/dist/flow/groups.js.map +1 -0
  56. package/dist/flow/prekeys.d.ts +45 -0
  57. package/dist/flow/prekeys.d.ts.map +1 -0
  58. package/dist/flow/prekeys.js +111 -0
  59. package/dist/flow/prekeys.js.map +1 -0
  60. package/dist/flow/receive.d.ts +125 -0
  61. package/dist/flow/receive.d.ts.map +1 -0
  62. package/dist/flow/receive.js +773 -0
  63. package/dist/flow/receive.js.map +1 -0
  64. package/dist/index.d.ts +15 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +6 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/morokbot-file.d.ts +14 -0
  69. package/dist/morokbot-file.d.ts.map +1 -0
  70. package/dist/morokbot-file.js +88 -0
  71. package/dist/morokbot-file.js.map +1 -0
  72. package/dist/ratelimit.d.ts +40 -0
  73. package/dist/ratelimit.d.ts.map +1 -0
  74. package/dist/ratelimit.js +76 -0
  75. package/dist/ratelimit.js.map +1 -0
  76. package/dist/sessions.d.ts +34 -0
  77. package/dist/sessions.d.ts.map +1 -0
  78. package/dist/sessions.js +69 -0
  79. package/dist/sessions.js.map +1 -0
  80. package/dist/state-lock.d.ts +17 -0
  81. package/dist/state-lock.d.ts.map +1 -0
  82. package/dist/state-lock.js +66 -0
  83. package/dist/state-lock.js.map +1 -0
  84. package/dist/transport/http.d.ts +48 -0
  85. package/dist/transport/http.d.ts.map +1 -0
  86. package/dist/transport/http.js +112 -0
  87. package/dist/transport/http.js.map +1 -0
  88. package/dist/transport/ws.d.ts +65 -0
  89. package/dist/transport/ws.d.ts.map +1 -0
  90. package/dist/transport/ws.js +219 -0
  91. package/dist/transport/ws.js.map +1 -0
  92. package/dist/types.d.ts +254 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +2 -0
  95. package/dist/types.js.map +1 -0
  96. package/package.json +59 -0
package/dist/bot.d.ts ADDED
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Public orchestrator. Use MorokBot.fromFile(...) to construct
3
+ * The ctor is private because .morokbot parsing and state-dir setup need IO
4
+ *
5
+ * Lifecycle:
6
+ * fromFile: parse .morokbot, build modules (no network IO)
7
+ * start(): import keys, fsck state, /auth/bot-session, WS handshake, prekey replenish + background loop
8
+ * stop(): prekey loop -> ws -> pending sends -> done
9
+ *
10
+ * `error` fires on recoverable failures (decrypt errors, exceptions thrown by developer handlers)
11
+ * start() itself throws on fatal init errors (bad .morokbot, 401, etc.)
12
+ */
13
+ import { EventEmitter } from 'node:events';
14
+ import type { BotConfig, IncomingMessage, CommandInvocation, BotStartEvent, BotStopEvent, ReactionEvent, ControlEvent, BotControl, ConversationAddedEvent, ConversationKickedEvent, DisconnectInfo, AttachmentInput } from './types.js';
15
+ import { type SendResult } from './flow/direct.js';
16
+ export interface SendArgs {
17
+ /**
18
+ * DM target, numeric userId or username (the SDK resolves a username via `GET /users/:username`)
19
+ * Mutually exclusive with `conversation`
20
+ */
21
+ peer?: number | string;
22
+ /**
23
+ * Group-chat / channel target, numeric conversationId. Mutually exclusive with `peer`
24
+ * The bot must already be a member, obtain `conversationId` from a `conversation_added` event,
25
+ * or from an incoming `IncomingMessage.conversationId` when responding to one
26
+ */
27
+ conversation?: number;
28
+ /**
29
+ * Message text. Required when `attachment` is absent
30
+ * Sent alongside a `'file'` attachment, it becomes the caption
31
+ * Ignored (with a debug log) for `'voice'` and `'video_note'` attachments,
32
+ * the FE renderer has no caption slot for those
33
+ */
34
+ text?: string;
35
+ /**
36
+ * Single attachment (file / voice / video_note). Mutually exclusive with `attachments`
37
+ */
38
+ attachment?: AttachmentInput;
39
+ /**
40
+ * Gallery of 2-10 file attachments shipped in one message, the bubble renders as a grid on the FE
41
+ * voice and video_note are not allowed in a gallery
42
+ * (server caps and FE renderer both expect `kind: 'file'` per item). Mutually exclusive with `attachment`
43
+ */
44
+ attachments?: AttachmentInput[];
45
+ replyToId?: number;
46
+ replyToClientMsgId?: string;
47
+ threadRootId?: number;
48
+ /** Disappearing-message TTL in seconds. Server-validated */
49
+ expiresInSeconds?: number;
50
+ }
51
+ export interface ReplyArgs {
52
+ text?: string;
53
+ attachment?: AttachmentInput;
54
+ attachments?: AttachmentInput[];
55
+ expiresInSeconds?: number;
56
+ }
57
+ interface MorokBotEvents {
58
+ message: (msg: IncomingMessage) => void | Promise<void>;
59
+ command: (cmd: CommandInvocation) => void | Promise<void>;
60
+ start: (e: BotStartEvent) => void | Promise<void>;
61
+ stop: (e: BotStopEvent) => void | Promise<void>;
62
+ reaction: (e: ReactionEvent) => void | Promise<void>;
63
+ control: (e: ControlEvent) => void | Promise<void>;
64
+ conversation_added: (e: ConversationAddedEvent) => void | Promise<void>;
65
+ conversation_kicked: (e: ConversationKickedEvent) => void | Promise<void>;
66
+ disconnect: (info: DisconnectInfo) => void | Promise<void>;
67
+ error: (err: Error) => void | Promise<void>;
68
+ }
69
+ export declare class MorokBot extends EventEmitter {
70
+ private readonly file;
71
+ private readonly stateDir;
72
+ private readonly apiBaseUrl;
73
+ private readonly wsUrlVal;
74
+ private readonly logger?;
75
+ private readonly bgIntervalMs;
76
+ private readonly replenishThreshold;
77
+ private readonly replenishTarget;
78
+ private readonly autoBackfillOnJoin;
79
+ private readonly serveBackfillRequests;
80
+ private signal?;
81
+ private http?;
82
+ private ws?;
83
+ private direct?;
84
+ private receive?;
85
+ private groups?;
86
+ private chanStore?;
87
+ private gsStore?;
88
+ private convCache?;
89
+ private stateLock?;
90
+ private prekey?;
91
+ private botUserId?;
92
+ private running;
93
+ /** Set true synchronously when start() enters, before any await, so a second concurrent start() returns
94
+ * without opening a second WS. Separate from `running` so isConnected stays accurate during boot */
95
+ private starting;
96
+ /** Flipped by stop() while start() is mid-flight. start() checks it at every checkpoint,
97
+ * and throws into its own catch so teardown runs and nothing is left open */
98
+ private stopRequested;
99
+ private constructor();
100
+ /** Read + validate the .morokbot file and build the bot. No network IO, call start() to connect */
101
+ static fromFile(config: BotConfig & {
102
+ tokenFile: string;
103
+ }): Promise<MorokBot>;
104
+ /** Connect. Resolves after WS auth + boot prekey replenish. Throws on fatal init errors. Idempotent */
105
+ start(): Promise<void>;
106
+ private assertResolvedUserId;
107
+ /**
108
+ * One-shot device-certificate publish (D cross-signing). Signs a certificate over this device's identity key
109
+ * under the .morokbot account signing key (XSK) and commits it via POST /crypto/cross-signing,
110
+ * so peers verify the bot's device against its account key and render a cross-signed safety number
111
+ * (routes/developer.ts:556 documents this obligation)
112
+ *
113
+ * Best-effort and idempotent: re-submitting the same (XSK, cert) on every start succeeds server-side
114
+ * Any failure (network, 409 XSK_ALREADY_SET / IDENTITY_ROTATED, missing XSK) is logged and non-fatal,
115
+ * the bot keeps running uncertified while peers fall back to TOFU
116
+ * One device per bot, so the FE's multi-device XSK propagation races don't apply here
117
+ *
118
+ * Skipped silently when the .morokbot predates cross-signing (no accountSigningKey), matching the FE
119
+ */
120
+ private ensureCrossSigning;
121
+ /** Clean shutdown. Stops background loops, closes the socket, rejects pending sends,
122
+ * releases the state lock. Idempotent. If start() is mid-flight, stopRequested makes it abort
123
+ * at the next checkpoint into its catch path */
124
+ stop(): Promise<void>;
125
+ get isConnected(): boolean;
126
+ /** Bot's own userId. Available after start() resolves */
127
+ get userId(): number;
128
+ send(args: SendArgs): Promise<SendResult>;
129
+ private sendDirect;
130
+ private sendGroup;
131
+ /** Rotate the channel-key. Mints a fresh 32-byte secret, wraps it to every other member device,
132
+ * POSTs to /channel-key/rotate. The server allows any member,
133
+ * so the bot's call is functionally identical to a human admin's */
134
+ rotateChannelKey(conversationId: number): Promise<{
135
+ epoch: number;
136
+ }>;
137
+ /** Share locally-known channel-key epochs with another member's devices
138
+ * Useful when the bot is the only online member at the moment a new joiner needs history
139
+ *
140
+ * target.deviceIds optional, absent = fetch via /prekeys/:userId/devices
141
+ * opts.epochs optional, absent = all local epochs. Server filters pre-join epochs by joined_secret_version */
142
+ backfillChannelKeys(conversationId: number, target: {
143
+ userId: number;
144
+ deviceIds?: number[];
145
+ }, opts?: {
146
+ epochs?: number[];
147
+ }): Promise<{
148
+ accepted: number;
149
+ }>;
150
+ /**
151
+ * Rotate group_secret and channel-key in one server transaction
152
+ * Run after kicking a leaker so a stale ex-member can't unseal future bundles with the old group_secret
153
+ *
154
+ * Server constraints (POST /groups/:id/group-secret/rotate):
155
+ * - conv type must be GROUP
156
+ * - conv must be private or the caller must be owner
157
+ * - bot must hold the current group_secret (auto-fetched)
158
+ *
159
+ * Error codes (axios error.response.data.code):
160
+ * SECRET_VERSION_STALE : someone else rotated, retry
161
+ * NOT_PRIVATE : bot lacks permission
162
+ * DIST_MISMATCH : membership shifted mid-rotate
163
+ * NO_READY_DEVICES : no recipient had an SPK
164
+ *
165
+ * Also re-seals every locally-known historical epoch under the new group_secret (server's resealHistorical field)
166
+ * After a rotate, no epoch is unsealable with the old secret
167
+ * If the bot is missing some historical epochs it reseals what it has, the rest can be patched on a later rotate
168
+ */
169
+ rotateGroupSecret(conversationId: number): Promise<{
170
+ epoch: number;
171
+ version: number;
172
+ }>;
173
+ /**
174
+ * Replace the bot's slash-command catalogue (the /-autocomplete the composer offers users)
175
+ * Call after start(). Defining handlers does not advertise commands, the catalogue is separate
176
+ * Server bounds: up to 32 entries, name /^[a-z][a-z0-9_]{0,31}$/, description trimmed to 256 chars
177
+ * An empty array clears it. Idempotent, safe to call on every start
178
+ */
179
+ setMyCommands(commands: ReadonlyArray<{
180
+ command: string;
181
+ description: string;
182
+ sortOrder?: number;
183
+ }>): Promise<{
184
+ count: number;
185
+ }>;
186
+ setMyControls(controls: ReadonlyArray<BotControl>): Promise<{
187
+ count: number;
188
+ }>;
189
+ /**
190
+ * Set the control buttons for ONE user's chat without touching the global menu others see
191
+ * Use it to drive a stateful flow, for example search results as buttons or a step-by-step wizard
192
+ * Pass the user id from an incoming message or control event (sender.userId)
193
+ * The override is short-lived on the server and survives that user's reload
194
+ * An empty array shows no buttons, call clearControlsFor to revert to the global menu
195
+ * Bounds match setMyControls, up to 16 top-level and 64 total nodes and depth 4
196
+ */
197
+ setControlsFor(peerUserId: number, controls: ReadonlyArray<BotControl>): Promise<{
198
+ count: number;
199
+ }>;
200
+ /**
201
+ * Drop a user's per-chat control override and revert them to the global menu set by setMyControls
202
+ * Call this when the flow ends
203
+ */
204
+ clearControlsFor(peerUserId: number): Promise<void>;
205
+ /** Reply to an incoming message. Threads replyToId/clientMsgId,
206
+ * routes DM vs group/channel by msg.conversationType */
207
+ reply(msg: IncomingMessage, args: ReplyArgs): Promise<SendResult>;
208
+ /**
209
+ * React to a message with a unicode symbol (any character, emoji included)
210
+ * DM reactions are encrypted per peer device (Signal), group-chat/channel reactions under the shared channel-key
211
+ * The reactor (this bot) is never echoed its own reaction back,
212
+ * so this resolves as soon as the frame is queued, there is no own-echo to await
213
+ * Re-reacting with a different symbol replaces the bot's previous one server-side
214
+ *
215
+ * `msg` is an incoming message or command. It carries messageId, conversationId,
216
+ * conversationType and sender. In a DM the reaction is encrypted to msg.sender (the peer)
217
+ */
218
+ react(msg: IncomingMessage, unicode: string): Promise<void>;
219
+ /**
220
+ * Remove this bot's reaction from a message. The server keys deletion off (messageId, reactorUserId),
221
+ * so no ciphertext is needed. One frame clears every distribution shape the bot wrote
222
+ */
223
+ unreact(msg: IncomingMessage): Promise<void>;
224
+ /** Resolve userId or username to a userId. Usernames hit GET /users/:username every time
225
+ * (bots usually pass userId from an incoming message, so the miss is rare) */
226
+ private resolvePeerUserId;
227
+ on<K extends keyof MorokBotEvents>(event: K, listener: MorokBotEvents[K]): this;
228
+ off<K extends keyof MorokBotEvents>(event: K, listener: MorokBotEvents[K]): this;
229
+ emit<K extends keyof MorokBotEvents>(event: K, ...args: Parameters<MorokBotEvents[K]>): boolean;
230
+ }
231
+ export {};
232
+ //# sourceMappingURL=bot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"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"}