signal-sdk 0.1.1 → 0.1.3

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 (54) hide show
  1. package/README.md +23 -11
  2. package/dist/MultiAccountManager.js +11 -19
  3. package/dist/SignalBot.js +40 -36
  4. package/dist/SignalCli.d.ts +25 -301
  5. package/dist/SignalCli.js +226 -971
  6. package/dist/__tests__/DeviceManager.test.d.ts +1 -0
  7. package/dist/__tests__/DeviceManager.test.js +135 -0
  8. package/dist/__tests__/MultiAccountManager.coverage.test.d.ts +1 -0
  9. package/dist/__tests__/MultiAccountManager.coverage.test.js +33 -0
  10. package/dist/__tests__/MultiAccountManager.test.js +3 -3
  11. package/dist/__tests__/SignalBot.additional.test.js +40 -37
  12. package/dist/__tests__/SignalBot.coverage.test.d.ts +1 -0
  13. package/dist/__tests__/SignalBot.coverage.test.js +385 -0
  14. package/dist/__tests__/SignalBot.test.js +8 -8
  15. package/dist/__tests__/SignalCli.advanced.test.js +47 -58
  16. package/dist/__tests__/SignalCli.connections.test.d.ts +1 -0
  17. package/dist/__tests__/SignalCli.connections.test.js +110 -0
  18. package/dist/__tests__/SignalCli.e2e.test.js +28 -32
  19. package/dist/__tests__/SignalCli.events.test.d.ts +1 -0
  20. package/dist/__tests__/SignalCli.events.test.js +113 -0
  21. package/dist/__tests__/SignalCli.integration.test.js +6 -5
  22. package/dist/__tests__/SignalCli.methods.test.js +150 -66
  23. package/dist/__tests__/SignalCli.parsing.test.js +4 -13
  24. package/dist/__tests__/SignalCli.simple.test.d.ts +1 -0
  25. package/dist/__tests__/SignalCli.simple.test.js +77 -0
  26. package/dist/__tests__/SignalCli.test.js +133 -74
  27. package/dist/__tests__/config.test.js +19 -29
  28. package/dist/__tests__/errors.test.js +2 -2
  29. package/dist/__tests__/retry.test.js +10 -8
  30. package/dist/__tests__/robustness.test.d.ts +1 -0
  31. package/dist/__tests__/robustness.test.js +59 -0
  32. package/dist/__tests__/security.test.d.ts +1 -0
  33. package/dist/__tests__/security.test.js +50 -0
  34. package/dist/config.js +3 -3
  35. package/dist/interfaces.d.ts +27 -0
  36. package/dist/managers/AccountManager.d.ts +27 -0
  37. package/dist/managers/AccountManager.js +147 -0
  38. package/dist/managers/BaseManager.d.ts +9 -0
  39. package/dist/managers/BaseManager.js +17 -0
  40. package/dist/managers/ContactManager.d.ts +15 -0
  41. package/dist/managers/ContactManager.js +123 -0
  42. package/dist/managers/DeviceManager.d.ts +11 -0
  43. package/dist/managers/DeviceManager.js +139 -0
  44. package/dist/managers/GroupManager.d.ts +12 -0
  45. package/dist/managers/GroupManager.js +78 -0
  46. package/dist/managers/MessageManager.d.ts +18 -0
  47. package/dist/managers/MessageManager.js +301 -0
  48. package/dist/managers/StickerManager.d.ts +8 -0
  49. package/dist/managers/StickerManager.js +39 -0
  50. package/dist/retry.js +3 -3
  51. package/dist/validators.d.ts +9 -0
  52. package/dist/validators.js +20 -0
  53. package/package.json +11 -4
  54. package/scripts/install.js +1 -1
@@ -1,6 +1,12 @@
1
- import { Message, Contact, GroupUpdateOptions, SendMessageOptions, ContactUpdateOptions, AccountConfiguration, Device, ReceiptType, StickerPack, IdentityKey, LinkingOptions, LinkingResult, MessageRequestResponseType, SendResponse, GroupInfo, RemoveContactOptions, UserStatusResult, PaymentNotificationData, StickerPackManifest, StickerPackUploadResult, RateLimitChallengeResult, ReceiveOptions, UploadProgress, PollCreateOptions, PollVoteOptions, PollTerminateOptions, GetAttachmentOptions, GetAvatarOptions, GetStickerOptions, UpdateAccountOptions, AccountUpdateResult, SendContactsOptions, ListGroupsOptions } from './interfaces';
1
+ import { Message, Contact, GroupUpdateOptions, SendMessageOptions, ContactUpdateOptions, AccountConfiguration, Device, ReceiptType, StickerPack, IdentityKey, LinkingOptions, LinkingResult, MessageRequestResponseType, SendResponse, GroupInfo, RemoveContactOptions, UserStatusResult, PaymentNotificationData, StickerPackManifest, StickerPackUploadResult, RateLimitChallengeResult, ReceiveOptions, UploadProgress, PollCreateOptions, PollVoteOptions, PollTerminateOptions, GetAttachmentOptions, GetAvatarOptions, GetStickerOptions, UpdateAccountOptions, AccountUpdateResult, SendContactsOptions, ListGroupsOptions, UpdateDeviceOptions } from './interfaces';
2
2
  import { EventEmitter } from 'events';
3
3
  import { SignalCliConfig } from './config';
4
+ import { MessageManager } from './managers/MessageManager';
5
+ import { GroupManager } from './managers/GroupManager';
6
+ import { ContactManager } from './managers/ContactManager';
7
+ import { DeviceManager } from './managers/DeviceManager';
8
+ import { AccountManager } from './managers/AccountManager';
9
+ import { StickerManager } from './managers/StickerManager';
4
10
  export declare class SignalCli extends EventEmitter {
5
11
  private signalCliPath;
6
12
  private account?;
@@ -11,6 +17,12 @@ export declare class SignalCli extends EventEmitter {
11
17
  private rateLimiter;
12
18
  private reconnectAttempts;
13
19
  private maxReconnectAttempts;
20
+ readonly messages: MessageManager;
21
+ readonly groups: GroupManager;
22
+ readonly contacts: ContactManager;
23
+ readonly devices: DeviceManager;
24
+ readonly accounts: AccountManager;
25
+ readonly stickers: StickerManager;
14
26
  constructor(accountOrPath?: string, account?: string, config?: SignalCliConfig);
15
27
  connect(): Promise<void>;
16
28
  private connectJsonRpc;
@@ -21,21 +33,27 @@ export declare class SignalCli extends EventEmitter {
21
33
  disconnect(): void;
22
34
  gracefulShutdown(): Promise<void>;
23
35
  private handleRpcResponse;
36
+ private emitDetailedEvents;
37
+ private handleProcessClose;
24
38
  private handleStderrData;
25
39
  private sendJsonRpcRequest;
26
40
  private isGroupId;
27
41
  register(number: string, voice?: boolean, captcha?: string): Promise<void>;
28
42
  verify(number: string, token: string, pin?: string): Promise<void>;
29
43
  sendMessage(recipient: string, message: string, options?: Omit<SendMessageOptions, 'message'>): Promise<SendResponse>;
30
- sendReaction(recipient: string, targetAuthor: string, targetTimestamp: number, emoji: string, remove?: boolean): Promise<SendResponse>;
44
+ sendReaction(recipient: string, targetAuthor: string, targetTimestamp: number, emoji: string, remove?: boolean, isStory?: boolean): Promise<SendResponse>;
31
45
  sendTyping(recipient: string, stop?: boolean): Promise<void>;
32
46
  remoteDeleteMessage(recipient: string, targetTimestamp: number): Promise<void>;
33
- updateContact(number: string, name: string, options?: Omit<ContactUpdateOptions, 'name'>): Promise<void>;
47
+ updateContact(number: string, name?: string, options?: Omit<ContactUpdateOptions, 'name'>): Promise<void>;
34
48
  block(recipients: string[], groupId?: string): Promise<void>;
35
49
  unblock(recipients: string[], groupId?: string): Promise<void>;
36
50
  quitGroup(groupId: string): Promise<void>;
37
51
  joinGroup(uri: string): Promise<void>;
38
- updateProfile(name: string, about?: string, aboutEmoji?: string, avatar?: string): Promise<void>;
52
+ updateProfile(name: string, about?: string, aboutEmoji?: string, avatar?: string, options?: {
53
+ familyName?: string;
54
+ mobileCoinAddress?: string;
55
+ removeAvatar?: boolean;
56
+ }): Promise<void>;
39
57
  sendReceipt(recipient: string, targetTimestamp: number, type?: ReceiptType): Promise<void>;
40
58
  listStickerPacks(): Promise<StickerPack[]>;
41
59
  addStickerPack(packId: string, packKey: string): Promise<void>;
@@ -47,68 +65,11 @@ export declare class SignalCli extends EventEmitter {
47
65
  removePin(): Promise<void>;
48
66
  listIdentities(number?: string): Promise<IdentityKey[]>;
49
67
  trustIdentity(number: string, safetyNumber: string, verified?: boolean): Promise<void>;
50
- /**
51
- * Get the safety number for a specific contact.
52
- * This is a helper method that extracts just the safety number from identity information.
53
- *
54
- * @param number - The phone number of the contact
55
- * @returns The safety number string, or null if not found
56
- *
57
- * @example
58
- * ```typescript
59
- * const safetyNumber = await signal.getSafetyNumber('+33123456789');
60
- * console.log(`Safety number: ${safetyNumber}`);
61
- * ```
62
- */
63
68
  getSafetyNumber(number: string): Promise<string | null>;
64
- /**
65
- * Verify a safety number for a contact.
66
- * Checks if the provided safety number matches the stored one and marks it as trusted if it does.
67
- *
68
- * @param number - The phone number of the contact
69
- * @param safetyNumber - The safety number to verify
70
- * @returns True if the safety number matches and was trusted, false otherwise
71
- *
72
- * @example
73
- * ```typescript
74
- * const verified = await signal.verifySafetyNumber('+33123456789', '123456 78901...');
75
- * if (verified) {
76
- * console.log('Safety number verified and trusted');
77
- * } else {
78
- * console.log('Safety number does not match!');
79
- * }
80
- * ```
81
- */
82
69
  verifySafetyNumber(number: string, safetyNumber: string): Promise<boolean>;
83
- /**
84
- * List all untrusted identities.
85
- * Returns identities that have not been explicitly trusted.
86
- *
87
- * @returns Array of untrusted identity keys
88
- *
89
- * @example
90
- * ```typescript
91
- * const untrusted = await signal.listUntrustedIdentities();
92
- * console.log(`Found ${untrusted.length} untrusted identities`);
93
- * untrusted.forEach(id => {
94
- * console.log(`${id.number}: ${id.safetyNumber}`);
95
- * });
96
- * ```
97
- */
98
70
  listUntrustedIdentities(): Promise<IdentityKey[]>;
99
71
  link(deviceName?: string): Promise<string>;
100
- /**
101
- * Link a new device to an existing Signal account with QR code support.
102
- * This method provides a complete device linking solution with QR code generation.
103
- *
104
- * @param options - Linking options including device name and QR code output preferences
105
- * @returns Promise resolving to LinkingResult with QR code data and linking status
106
- */
107
72
  deviceLink(options?: LinkingOptions): Promise<LinkingResult>;
108
- /**
109
- * Display ASCII QR code in console.
110
- * Uses qrcode-terminal which is included as a dependency.
111
- */
112
73
  private displayQRCode;
113
74
  addDevice(uri: string, deviceName?: string): Promise<void>;
114
75
  sendSyncRequest(): Promise<void>;
@@ -117,47 +78,12 @@ export declare class SignalCli extends EventEmitter {
117
78
  createGroup(name: string, members: string[]): Promise<GroupInfo>;
118
79
  updateGroup(groupId: string, options: GroupUpdateOptions): Promise<void>;
119
80
  listGroups(): Promise<GroupInfo[]>;
120
- /**
121
- * Send group invite link to a recipient.
122
- * Retrieves and sends the invitation link for a group.
123
- *
124
- * @param groupId - The group ID
125
- * @param recipient - The recipient to send the invite link to
126
- * @returns Send response
127
- *
128
- * @example
129
- * ```typescript
130
- * await signal.sendGroupInviteLink('groupId123==', '+33123456789');
131
- * ```
132
- */
133
81
  sendGroupInviteLink(groupId: string, recipient: string): Promise<SendResponse>;
134
- /**
135
- * Set banned members for a group.
136
- * Ban specific members from the group.
137
- *
138
- * @param groupId - The group ID
139
- * @param members - Array of phone numbers to ban
140
- *
141
- * @example
142
- * ```typescript
143
- * await signal.setBannedMembers('groupId123==', ['+33111111111', '+33222222222']);
144
- * ```
145
- */
146
82
  setBannedMembers(groupId: string, members: string[]): Promise<void>;
147
- /**
148
- * Reset group invite link.
149
- * Invalidates the current group invite link and generates a new one.
150
- *
151
- * @param groupId - The group ID
152
- *
153
- * @example
154
- * ```typescript
155
- * await signal.resetGroupLink('groupId123==');
156
- * ```
157
- */
158
83
  resetGroupLink(groupId: string): Promise<void>;
159
84
  listContacts(): Promise<Contact[]>;
160
85
  listDevices(): Promise<Device[]>;
86
+ updateDevice(options: UpdateDeviceOptions): Promise<void>;
161
87
  listAccounts(): Promise<string[]>;
162
88
  /**
163
89
  * @deprecated Use `connect` and listen for `message` events instead.
@@ -196,239 +122,37 @@ export declare class SignalCli extends EventEmitter {
196
122
  * ```
197
123
  */
198
124
  receive(options?: ReceiveOptions): Promise<Message[]>;
199
- /**
200
- * Parse a message envelope from signal-cli into a Message object.
201
- * @private
202
- */
203
125
  private parseEnvelope;
204
- /**
205
- * Remove a contact from the contact list.
206
- * @param number - The phone number of the contact to remove
207
- * @param options - Options for how to remove the contact
208
- */
209
126
  removeContact(number: string, options?: RemoveContactOptions): Promise<void>;
210
- /**
211
- * Check if phone numbers are registered with Signal.
212
- * @param numbers - Array of phone numbers to check
213
- * @param usernames - Optional array of usernames to check
214
- * @returns Array of user status results
215
- */
216
127
  getUserStatus(numbers?: string[], usernames?: string[]): Promise<UserStatusResult[]>;
217
- /**
218
- * Send a payment notification to a recipient (MobileCoin).
219
- * Sends a notification about a cryptocurrency payment made through Signal's MobileCoin integration.
220
- *
221
- * @param recipient - The phone number or group ID of the recipient
222
- * @param paymentData - Payment notification data including receipt and optional note
223
- * @returns Send result with timestamp
224
- * @throws {Error} If receipt is invalid or sending fails
225
- *
226
- * @example
227
- * ```typescript
228
- * const receiptBlob = 'base64EncodedReceiptData...';
229
- * await signal.sendPaymentNotification('+33612345678', {
230
- * receipt: receiptBlob,
231
- * note: 'Thanks for dinner!'
232
- * });
233
- * ```
234
- */
235
128
  sendPaymentNotification(recipient: string, paymentData: PaymentNotificationData): Promise<SendResponse>;
236
- /**
237
- * Upload a custom sticker pack to Signal.
238
- * @param manifest - Sticker pack manifest information
239
- * @returns Upload result with pack ID and key
240
- */
241
129
  uploadStickerPack(manifest: StickerPackManifest): Promise<StickerPackUploadResult>;
242
- /**
243
- * Submit a rate limit challenge to lift rate limiting.
244
- * @param challenge - Challenge token from the proof required error
245
- * @param captcha - Captcha token from solved captcha
246
- * @returns Challenge result indicating success/failure
247
- */
248
130
  submitRateLimitChallenge(challenge: string, captcha: string): Promise<RateLimitChallengeResult>;
249
- /**
250
- * Start the phone number change process.
251
- * Initiates SMS or voice verification for changing your account to a new phone number.
252
- * After calling this, you must verify the new number with finishChangeNumber().
253
- *
254
- * @param newNumber - The new phone number in E164 format (e.g., "+33612345678")
255
- * @param voice - Use voice verification instead of SMS (default: false)
256
- * @param captcha - Optional captcha token if required
257
- * @throws {Error} If not a primary device or rate limited
258
- */
259
131
  startChangeNumber(newNumber: string, voice?: boolean, captcha?: string): Promise<void>;
260
- /**
261
- * Complete the phone number change process.
262
- * Verifies the code received via SMS or voice and changes your account to the new number.
263
- * Must be called after startChangeNumber().
264
- *
265
- * @param newNumber - The new phone number (same as startChangeNumber)
266
- * @param verificationCode - The verification code received via SMS or voice
267
- * @param pin - Optional registration lock PIN if one was set
268
- * @throws {Error} If verification fails or incorrect PIN
269
- */
270
132
  finishChangeNumber(newNumber: string, verificationCode: string, pin?: string): Promise<void>;
271
- /**
272
- * Enhanced send message with progress callback support.
273
- * @param recipient - Phone number or group ID
274
- * @param message - Message text
275
- * @param options - Send options including progress callback
276
- * @returns Send response
277
- */
278
133
  sendMessageWithProgress(recipient: string, message: string, options?: SendMessageOptions & {
279
134
  onProgress?: (progress: UploadProgress) => void;
280
135
  }): Promise<SendResponse>;
281
- /**
282
- * Send a poll create message to a recipient or group.
283
- * @param options Poll creation options
284
- * @returns Send response with timestamp
285
- */
286
136
  sendPollCreate(options: PollCreateOptions): Promise<SendResponse>;
287
- /**
288
- * Send a poll vote message to vote on a poll.
289
- * @param recipient Recipient or group ID
290
- * @param options Poll vote options
291
- * @returns Send response with timestamp
292
- */
293
137
  sendPollVote(recipient: string, options: PollVoteOptions): Promise<SendResponse>;
294
- /**
295
- * Send a poll terminate message to close a poll.
296
- * @param recipient Recipient or group ID
297
- * @param options Poll terminate options
298
- * @returns Send response with timestamp
299
- */
300
138
  sendPollTerminate(recipient: string, options: PollTerminateOptions): Promise<SendResponse>;
301
- /**
302
- * Update account information (device name, username, privacy settings).
303
- * @param options Account update options
304
- * @returns Account update result
305
- */
306
139
  updateAccount(options: UpdateAccountOptions): Promise<AccountUpdateResult>;
307
- /**
308
- * Set or update the username for this account.
309
- * Helper method that wraps updateAccount() for simpler username management.
310
- *
311
- * @param username - The username to set (without discriminator)
312
- * @returns Account update result with username and link
313
- *
314
- * @example
315
- * ```typescript
316
- * const result = await signal.setUsername('myusername');
317
- * console.log(`Username: ${result.username}`);
318
- * console.log(`Link: ${result.usernameLink}`);
319
- * ```
320
- */
321
140
  setUsername(username: string): Promise<AccountUpdateResult>;
322
- /**
323
- * Delete the current username from this account.
324
- * Helper method that wraps updateAccount() for simpler username deletion.
325
- *
326
- * @returns Account update result
327
- *
328
- * @example
329
- * ```typescript
330
- * const result = await signal.deleteUsername();
331
- * if (result.success) {
332
- * console.log('Username deleted successfully');
333
- * }
334
- * ```
335
- */
336
141
  deleteUsername(): Promise<AccountUpdateResult>;
337
- /**
338
- * Get raw attachment data as base64 string.
339
- * @param options Attachment retrieval options
340
- * @returns Base64 encoded attachment data
341
- */
342
142
  getAttachment(options: GetAttachmentOptions): Promise<string>;
343
- /**
344
- * Get raw avatar data as base64 string.
345
- * @param options Avatar retrieval options
346
- * @returns Base64 encoded avatar data
347
- */
348
143
  getAvatar(options: GetAvatarOptions): Promise<string>;
349
- /**
350
- * Get raw sticker data as base64 string.
351
- * @param options Sticker retrieval options
352
- * @returns Base64 encoded sticker data
353
- */
354
144
  getSticker(options: GetStickerOptions): Promise<string>;
355
- /**
356
- * Send contacts synchronization message to linked devices.
357
- * @param options Contacts sync options
358
- */
359
145
  sendContacts(options?: SendContactsOptions): Promise<void>;
360
- /**
361
- * List groups with optional filtering and details.
362
- * @param options List groups options
363
- * @returns Array of group information
364
- */
365
146
  listGroupsDetailed(options?: ListGroupsOptions): Promise<GroupInfo[]>;
366
- /**
367
- * List all local accounts.
368
- * @returns Array of account phone numbers
369
- */
370
147
  listAccountsDetailed(): Promise<Array<{
371
148
  number: string;
372
149
  name?: string;
373
150
  uuid?: string;
374
151
  }>>;
375
- /**
376
- * Extract profile information from a contact.
377
- * Parses givenName, familyName, mobileCoinAddress from profile data.
378
- *
379
- * @param contact - The contact object to parse
380
- * @returns Enhanced contact with extracted profile fields
381
- *
382
- * @example
383
- * ```typescript
384
- * const contacts = await signal.listContacts();
385
- * const enriched = signal.parseContactProfile(contacts[0]);
386
- * console.log(enriched.givenName, enriched.familyName);
387
- * ```
388
- */
389
152
  parseContactProfile(contact: Contact): Contact;
390
- /**
391
- * Extract group membership details.
392
- * Parses pendingMembers, bannedMembers, inviteLink from group data.
393
- *
394
- * @param group - The group info to parse
395
- * @returns Enhanced group with extracted membership fields
396
- *
397
- * @example
398
- * ```typescript
399
- * const groups = await signal.listGroups();
400
- * const enriched = signal.parseGroupDetails(groups[0]);
401
- * console.log(enriched.pendingMembers, enriched.bannedMembers);
402
- * ```
403
- */
404
153
  parseGroupDetails(group: GroupInfo): GroupInfo;
405
- /**
406
- * Get enriched contacts list with parsed profile information.
407
- *
408
- * @returns Array of contacts with full profile data
409
- *
410
- * @example
411
- * ```typescript
412
- * const contacts = await signal.getContactsWithProfiles();
413
- * contacts.forEach(c => {
414
- * console.log(`${c.givenName} ${c.familyName} - ${c.mobileCoinAddress}`);
415
- * });
416
- * ```
417
- */
418
154
  getContactsWithProfiles(): Promise<Contact[]>;
419
- /**
420
- * Get enriched groups list with parsed membership details.
421
- *
422
- * @param options - List groups options
423
- * @returns Array of groups with full membership data
424
- *
425
- * @example
426
- * ```typescript
427
- * const groups = await signal.getGroupsWithDetails();
428
- * groups.forEach(g => {
429
- * console.log(`${g.name}: ${g.members.length} members, ${g.pendingMembers.length} pending`);
430
- * });
431
- * ```
432
- */
433
155
  getGroupsWithDetails(options?: ListGroupsOptions): Promise<GroupInfo[]>;
156
+ isRegistered(number: string): Promise<boolean>;
157
+ sendNoteToSelf(message: string, options?: Omit<SendMessageOptions, 'message' | 'noteToSelf'>): Promise<SendResponse>;
434
158
  }