signal-sdk 0.1.2 → 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 (53) hide show
  1. package/README.md +18 -8
  2. package/dist/MultiAccountManager.js +11 -19
  3. package/dist/SignalBot.js +40 -36
  4. package/dist/SignalCli.d.ts +23 -319
  5. package/dist/SignalCli.js +224 -998
  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 +77 -77
  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 +96 -82
  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 +18 -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
@@ -1,6 +1,12 @@
1
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,66 +78,11 @@ 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[]>;
161
- /**
162
- * Update a linked device name (signal-cli v0.13.23+).
163
- * Allows changing the display name of a linked device.
164
- *
165
- * @param options - Device update options
166
- * @returns Promise that resolves when device is updated
167
- *
168
- * @example
169
- * ```typescript
170
- * // List devices to get device IDs
171
- * const devices = await signal.listDevices();
172
- *
173
- * // Update device name
174
- * await signal.updateDevice({
175
- * deviceId: 2,
176
- * deviceName: 'My New Device Name'
177
- * });
178
- * ```
179
- */
180
86
  updateDevice(options: UpdateDeviceOptions): Promise<void>;
181
87
  listAccounts(): Promise<string[]>;
182
88
  /**
@@ -216,239 +122,37 @@ export declare class SignalCli extends EventEmitter {
216
122
  * ```
217
123
  */
218
124
  receive(options?: ReceiveOptions): Promise<Message[]>;
219
- /**
220
- * Parse a message envelope from signal-cli into a Message object.
221
- * @private
222
- */
223
125
  private parseEnvelope;
224
- /**
225
- * Remove a contact from the contact list.
226
- * @param number - The phone number of the contact to remove
227
- * @param options - Options for how to remove the contact
228
- */
229
126
  removeContact(number: string, options?: RemoveContactOptions): Promise<void>;
230
- /**
231
- * Check if phone numbers are registered with Signal.
232
- * @param numbers - Array of phone numbers to check
233
- * @param usernames - Optional array of usernames to check
234
- * @returns Array of user status results
235
- */
236
127
  getUserStatus(numbers?: string[], usernames?: string[]): Promise<UserStatusResult[]>;
237
- /**
238
- * Send a payment notification to a recipient (MobileCoin).
239
- * Sends a notification about a cryptocurrency payment made through Signal's MobileCoin integration.
240
- *
241
- * @param recipient - The phone number or group ID of the recipient
242
- * @param paymentData - Payment notification data including receipt and optional note
243
- * @returns Send result with timestamp
244
- * @throws {Error} If receipt is invalid or sending fails
245
- *
246
- * @example
247
- * ```typescript
248
- * const receiptBlob = 'base64EncodedReceiptData...';
249
- * await signal.sendPaymentNotification('+33612345678', {
250
- * receipt: receiptBlob,
251
- * note: 'Thanks for dinner!'
252
- * });
253
- * ```
254
- */
255
128
  sendPaymentNotification(recipient: string, paymentData: PaymentNotificationData): Promise<SendResponse>;
256
- /**
257
- * Upload a custom sticker pack to Signal.
258
- * @param manifest - Sticker pack manifest information
259
- * @returns Upload result with pack ID and key
260
- */
261
129
  uploadStickerPack(manifest: StickerPackManifest): Promise<StickerPackUploadResult>;
262
- /**
263
- * Submit a rate limit challenge to lift rate limiting.
264
- * @param challenge - Challenge token from the proof required error
265
- * @param captcha - Captcha token from solved captcha
266
- * @returns Challenge result indicating success/failure
267
- */
268
130
  submitRateLimitChallenge(challenge: string, captcha: string): Promise<RateLimitChallengeResult>;
269
- /**
270
- * Start the phone number change process.
271
- * Initiates SMS or voice verification for changing your account to a new phone number.
272
- * After calling this, you must verify the new number with finishChangeNumber().
273
- *
274
- * @param newNumber - The new phone number in E164 format (e.g., "+33612345678")
275
- * @param voice - Use voice verification instead of SMS (default: false)
276
- * @param captcha - Optional captcha token if required
277
- * @throws {Error} If not a primary device or rate limited
278
- */
279
131
  startChangeNumber(newNumber: string, voice?: boolean, captcha?: string): Promise<void>;
280
- /**
281
- * Complete the phone number change process.
282
- * Verifies the code received via SMS or voice and changes your account to the new number.
283
- * Must be called after startChangeNumber().
284
- *
285
- * @param newNumber - The new phone number (same as startChangeNumber)
286
- * @param verificationCode - The verification code received via SMS or voice
287
- * @param pin - Optional registration lock PIN if one was set
288
- * @throws {Error} If verification fails or incorrect PIN
289
- */
290
132
  finishChangeNumber(newNumber: string, verificationCode: string, pin?: string): Promise<void>;
291
- /**
292
- * Enhanced send message with progress callback support.
293
- * @param recipient - Phone number or group ID
294
- * @param message - Message text
295
- * @param options - Send options including progress callback
296
- * @returns Send response
297
- */
298
133
  sendMessageWithProgress(recipient: string, message: string, options?: SendMessageOptions & {
299
134
  onProgress?: (progress: UploadProgress) => void;
300
135
  }): Promise<SendResponse>;
301
- /**
302
- * Send a poll create message to a recipient or group.
303
- * @param options Poll creation options
304
- * @returns Send response with timestamp
305
- */
306
136
  sendPollCreate(options: PollCreateOptions): Promise<SendResponse>;
307
- /**
308
- * Send a poll vote message to vote on a poll.
309
- * @param recipient Recipient or group ID
310
- * @param options Poll vote options
311
- * @returns Send response with timestamp
312
- */
313
137
  sendPollVote(recipient: string, options: PollVoteOptions): Promise<SendResponse>;
314
- /**
315
- * Send a poll terminate message to close a poll.
316
- * @param recipient Recipient or group ID
317
- * @param options Poll terminate options
318
- * @returns Send response with timestamp
319
- */
320
138
  sendPollTerminate(recipient: string, options: PollTerminateOptions): Promise<SendResponse>;
321
- /**
322
- * Update account information (device name, username, privacy settings).
323
- * @param options Account update options
324
- * @returns Account update result
325
- */
326
139
  updateAccount(options: UpdateAccountOptions): Promise<AccountUpdateResult>;
327
- /**
328
- * Set or update the username for this account.
329
- * Helper method that wraps updateAccount() for simpler username management.
330
- *
331
- * @param username - The username to set (without discriminator)
332
- * @returns Account update result with username and link
333
- *
334
- * @example
335
- * ```typescript
336
- * const result = await signal.setUsername('myusername');
337
- * console.log(`Username: ${result.username}`);
338
- * console.log(`Link: ${result.usernameLink}`);
339
- * ```
340
- */
341
140
  setUsername(username: string): Promise<AccountUpdateResult>;
342
- /**
343
- * Delete the current username from this account.
344
- * Helper method that wraps updateAccount() for simpler username deletion.
345
- *
346
- * @returns Account update result
347
- *
348
- * @example
349
- * ```typescript
350
- * const result = await signal.deleteUsername();
351
- * if (result.success) {
352
- * console.log('Username deleted successfully');
353
- * }
354
- * ```
355
- */
356
141
  deleteUsername(): Promise<AccountUpdateResult>;
357
- /**
358
- * Get raw attachment data as base64 string.
359
- * @param options Attachment retrieval options
360
- * @returns Base64 encoded attachment data
361
- */
362
142
  getAttachment(options: GetAttachmentOptions): Promise<string>;
363
- /**
364
- * Get raw avatar data as base64 string.
365
- * @param options Avatar retrieval options
366
- * @returns Base64 encoded avatar data
367
- */
368
143
  getAvatar(options: GetAvatarOptions): Promise<string>;
369
- /**
370
- * Get raw sticker data as base64 string.
371
- * @param options Sticker retrieval options
372
- * @returns Base64 encoded sticker data
373
- */
374
144
  getSticker(options: GetStickerOptions): Promise<string>;
375
- /**
376
- * Send contacts synchronization message to linked devices.
377
- * @param options Contacts sync options
378
- */
379
145
  sendContacts(options?: SendContactsOptions): Promise<void>;
380
- /**
381
- * List groups with optional filtering and details.
382
- * @param options List groups options
383
- * @returns Array of group information
384
- */
385
146
  listGroupsDetailed(options?: ListGroupsOptions): Promise<GroupInfo[]>;
386
- /**
387
- * List all local accounts.
388
- * @returns Array of account phone numbers
389
- */
390
147
  listAccountsDetailed(): Promise<Array<{
391
148
  number: string;
392
149
  name?: string;
393
150
  uuid?: string;
394
151
  }>>;
395
- /**
396
- * Extract profile information from a contact.
397
- * Parses givenName, familyName, mobileCoinAddress from profile data.
398
- *
399
- * @param contact - The contact object to parse
400
- * @returns Enhanced contact with extracted profile fields
401
- *
402
- * @example
403
- * ```typescript
404
- * const contacts = await signal.listContacts();
405
- * const enriched = signal.parseContactProfile(contacts[0]);
406
- * console.log(enriched.givenName, enriched.familyName);
407
- * ```
408
- */
409
152
  parseContactProfile(contact: Contact): Contact;
410
- /**
411
- * Extract group membership details.
412
- * Parses pendingMembers, bannedMembers, inviteLink from group data.
413
- *
414
- * @param group - The group info to parse
415
- * @returns Enhanced group with extracted membership fields
416
- *
417
- * @example
418
- * ```typescript
419
- * const groups = await signal.listGroups();
420
- * const enriched = signal.parseGroupDetails(groups[0]);
421
- * console.log(enriched.pendingMembers, enriched.bannedMembers);
422
- * ```
423
- */
424
153
  parseGroupDetails(group: GroupInfo): GroupInfo;
425
- /**
426
- * Get enriched contacts list with parsed profile information.
427
- *
428
- * @returns Array of contacts with full profile data
429
- *
430
- * @example
431
- * ```typescript
432
- * const contacts = await signal.getContactsWithProfiles();
433
- * contacts.forEach(c => {
434
- * console.log(`${c.givenName} ${c.familyName} - ${c.mobileCoinAddress}`);
435
- * });
436
- * ```
437
- */
438
154
  getContactsWithProfiles(): Promise<Contact[]>;
439
- /**
440
- * Get enriched groups list with parsed membership details.
441
- *
442
- * @param options - List groups options
443
- * @returns Array of groups with full membership data
444
- *
445
- * @example
446
- * ```typescript
447
- * const groups = await signal.getGroupsWithDetails();
448
- * groups.forEach(g => {
449
- * console.log(`${g.name}: ${g.members.length} members, ${g.pendingMembers.length} pending`);
450
- * });
451
- * ```
452
- */
453
155
  getGroupsWithDetails(options?: ListGroupsOptions): Promise<GroupInfo[]>;
156
+ isRegistered(number: string): Promise<boolean>;
157
+ sendNoteToSelf(message: string, options?: Omit<SendMessageOptions, 'message' | 'noteToSelf'>): Promise<SendResponse>;
454
158
  }