@kangwifi-pro/waliwa 1.0.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 (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +600 -0
  3. package/dist/advanced/features.d.ts +211 -0
  4. package/dist/advanced/features.d.ts.map +1 -0
  5. package/dist/advanced/features.js +671 -0
  6. package/dist/advanced/features.js.map +1 -0
  7. package/dist/auth/auth-state.d.ts +89 -0
  8. package/dist/auth/auth-state.d.ts.map +1 -0
  9. package/dist/auth/auth-state.js +330 -0
  10. package/dist/auth/auth-state.js.map +1 -0
  11. package/dist/auth/pairing-code.d.ts +78 -0
  12. package/dist/auth/pairing-code.d.ts.map +1 -0
  13. package/dist/auth/pairing-code.js +191 -0
  14. package/dist/auth/pairing-code.js.map +1 -0
  15. package/dist/auth/qr-code.d.ts +60 -0
  16. package/dist/auth/qr-code.d.ts.map +1 -0
  17. package/dist/auth/qr-code.js +151 -0
  18. package/dist/auth/qr-code.js.map +1 -0
  19. package/dist/calls/handler.d.ts +61 -0
  20. package/dist/calls/handler.d.ts.map +1 -0
  21. package/dist/calls/handler.js +117 -0
  22. package/dist/calls/handler.js.map +1 -0
  23. package/dist/core/binary.d.ts +74 -0
  24. package/dist/core/binary.d.ts.map +1 -0
  25. package/dist/core/binary.js +448 -0
  26. package/dist/core/binary.js.map +1 -0
  27. package/dist/core/crypto.d.ts +60 -0
  28. package/dist/core/crypto.d.ts.map +1 -0
  29. package/dist/core/crypto.js +170 -0
  30. package/dist/core/crypto.js.map +1 -0
  31. package/dist/core/noise.d.ts +106 -0
  32. package/dist/core/noise.d.ts.map +1 -0
  33. package/dist/core/noise.js +307 -0
  34. package/dist/core/noise.js.map +1 -0
  35. package/dist/events/emitter.d.ts +44 -0
  36. package/dist/events/emitter.d.ts.map +1 -0
  37. package/dist/events/emitter.js +79 -0
  38. package/dist/events/emitter.js.map +1 -0
  39. package/dist/features/index.d.ts +342 -0
  40. package/dist/features/index.d.ts.map +1 -0
  41. package/dist/features/index.js +755 -0
  42. package/dist/features/index.js.map +1 -0
  43. package/dist/fixes/index.d.ts +333 -0
  44. package/dist/fixes/index.d.ts.map +1 -0
  45. package/dist/fixes/index.js +762 -0
  46. package/dist/fixes/index.js.map +1 -0
  47. package/dist/groups/management.d.ts +86 -0
  48. package/dist/groups/management.d.ts.map +1 -0
  49. package/dist/groups/management.js +443 -0
  50. package/dist/groups/management.js.map +1 -0
  51. package/dist/index.d.ts +65 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +236 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/messages/media.d.ts +93 -0
  56. package/dist/messages/media.d.ts.map +1 -0
  57. package/dist/messages/media.js +252 -0
  58. package/dist/messages/media.js.map +1 -0
  59. package/dist/messages/message-encoder.d.ts +70 -0
  60. package/dist/messages/message-encoder.d.ts.map +1 -0
  61. package/dist/messages/message-encoder.js +453 -0
  62. package/dist/messages/message-encoder.js.map +1 -0
  63. package/dist/messages/send.d.ts +101 -0
  64. package/dist/messages/send.d.ts.map +1 -0
  65. package/dist/messages/send.js +409 -0
  66. package/dist/messages/send.js.map +1 -0
  67. package/dist/recovery/index.d.ts +125 -0
  68. package/dist/recovery/index.d.ts.map +1 -0
  69. package/dist/recovery/index.js +584 -0
  70. package/dist/recovery/index.js.map +1 -0
  71. package/dist/skdm/index.d.ts +220 -0
  72. package/dist/skdm/index.d.ts.map +1 -0
  73. package/dist/skdm/index.js +600 -0
  74. package/dist/skdm/index.js.map +1 -0
  75. package/dist/socket/hybrid.d.ts +118 -0
  76. package/dist/socket/hybrid.d.ts.map +1 -0
  77. package/dist/socket/hybrid.js +352 -0
  78. package/dist/socket/hybrid.js.map +1 -0
  79. package/dist/socket/wa-socket.d.ts +300 -0
  80. package/dist/socket/wa-socket.d.ts.map +1 -0
  81. package/dist/socket/wa-socket.js +1094 -0
  82. package/dist/socket/wa-socket.js.map +1 -0
  83. package/dist/socket/ws-socket.d.ts +96 -0
  84. package/dist/socket/ws-socket.d.ts.map +1 -0
  85. package/dist/socket/ws-socket.js +302 -0
  86. package/dist/socket/ws-socket.js.map +1 -0
  87. package/dist/types/index.d.ts +444 -0
  88. package/dist/types/index.d.ts.map +1 -0
  89. package/dist/types/index.js +7 -0
  90. package/dist/types/index.js.map +1 -0
  91. package/dist/utils/jid.d.ts +46 -0
  92. package/dist/utils/jid.d.ts.map +1 -0
  93. package/dist/utils/jid.js +152 -0
  94. package/dist/utils/jid.js.map +1 -0
  95. package/dist/utils/logger.d.ts +45 -0
  96. package/dist/utils/logger.d.ts.map +1 -0
  97. package/dist/utils/logger.js +79 -0
  98. package/dist/utils/logger.js.map +1 -0
  99. package/dist/utils/retry.d.ts +43 -0
  100. package/dist/utils/retry.d.ts.map +1 -0
  101. package/dist/utils/retry.js +175 -0
  102. package/dist/utils/retry.js.map +1 -0
  103. package/docs/API.md +745 -0
  104. package/docs/ARCHITECTURE.md +307 -0
  105. package/docs/BAILEYS_FIXES.md +360 -0
  106. package/docs/FEATURES.md +532 -0
  107. package/docs/PROTOCOL.md +489 -0
  108. package/docs/RECOVERY.md +409 -0
  109. package/docs/SKDM.md +233 -0
  110. package/examples/ai-bot/index.ts +479 -0
  111. package/examples/ai-bot/package.json +17 -0
  112. package/examples/echo-bot/index.ts +171 -0
  113. package/examples/echo-bot/package.json +18 -0
  114. package/examples/group-bot/index.ts +557 -0
  115. package/examples/group-bot/package.json +17 -0
  116. package/examples/rest-gateway/index.ts +499 -0
  117. package/examples/rest-gateway/package.json +19 -0
  118. package/package.json +75 -0
  119. package/src/advanced/features.ts +817 -0
  120. package/src/auth/auth-state.ts +342 -0
  121. package/src/auth/pairing-code.ts +246 -0
  122. package/src/auth/qr-code.ts +191 -0
  123. package/src/calls/handler.ts +153 -0
  124. package/src/core/binary.ts +464 -0
  125. package/src/core/crypto.ts +189 -0
  126. package/src/core/noise.ts +406 -0
  127. package/src/events/emitter.ts +88 -0
  128. package/src/features/index.ts +921 -0
  129. package/src/fixes/index.ts +882 -0
  130. package/src/groups/management.ts +497 -0
  131. package/src/index.ts +274 -0
  132. package/src/messages/media.ts +372 -0
  133. package/src/messages/message-encoder.ts +520 -0
  134. package/src/messages/send.ts +521 -0
  135. package/src/recovery/index.ts +704 -0
  136. package/src/skdm/index.ts +693 -0
  137. package/src/socket/hybrid.ts +414 -0
  138. package/src/socket/wa-socket.ts +1347 -0
  139. package/src/socket/ws-socket.ts +355 -0
  140. package/src/types/index.ts +457 -0
  141. package/src/utils/jid.ts +156 -0
  142. package/src/utils/logger.ts +84 -0
  143. package/src/utils/retry.ts +205 -0
  144. package/tsconfig.json +30 -0
package/docs/API.md ADDED
@@ -0,0 +1,745 @@
1
+ # Waliwa API Reference
2
+
3
+ Complete API reference for Waliwa library.
4
+
5
+ ## Table of Contents
6
+
7
+ - [makeWASocket](#makewasocket)
8
+ - [useFileAuthState](#usefileauthstate)
9
+ - [WASocket](#wasocket)
10
+ - [Events](#events)
11
+ - [Send Messages](#send-messages)
12
+ - [Media](#media)
13
+ - [Groups](#groups)
14
+ - [Calls](#calls)
15
+ - [Chat Operations](#chat-operations)
16
+ - [Presence](#presence)
17
+ - [Connection](#connection)
18
+ - [Core APIs](#core-apis)
19
+ - [Auth APIs](#auth-apis)
20
+ - [Utility APIs](#utility-apis)
21
+
22
+ ---
23
+
24
+ ## makeWASocket
25
+
26
+ Main entry point. Creates WhatsApp socket and auto-connects.
27
+
28
+ ```typescript
29
+ import { makeWASocket, useFileAuthState } from 'waliwa';
30
+
31
+ const { state } = await useFileAuthState('./auth');
32
+ const sock = makeWASocket({
33
+ authState: state,
34
+ printQRInTerminal: true
35
+ });
36
+ ```
37
+
38
+ ### Parameters
39
+
40
+ | Parameter | Type | Required | Description |
41
+ |-----------|------|----------|-------------|
42
+ | config | WaliwaConfig | Yes | Configuration object |
43
+
44
+ ### Returns
45
+
46
+ `WASocket` instance (already connected asynchronously).
47
+
48
+ ---
49
+
50
+ ## useFileAuthState
51
+
52
+ Initialize file-based auth state for persistent sessions.
53
+
54
+ ```typescript
55
+ const { state, saveCreds } = await useFileAuthState('./auth-folder');
56
+ ```
57
+
58
+ ### Parameters
59
+
60
+ | Parameter | Type | Required | Description |
61
+ |-----------|------|----------|-------------|
62
+ | folder | string | Yes | Directory path for storing session files |
63
+ | prefix | string | No | File prefix (default: 'waliwa-session') |
64
+ | logger | WALogger | No | Logger instance |
65
+
66
+ ### Returns
67
+
68
+ ```typescript
69
+ {
70
+ state: AuthState;
71
+ saveCreds: () => Promise<void>;
72
+ }
73
+ ```
74
+
75
+ ---
76
+
77
+ ## WASocket
78
+
79
+ The main socket interface for WhatsApp operations.
80
+
81
+ ### Events
82
+
83
+ All events are emitted via `sock.ev.on(eventName, callback)`.
84
+
85
+ #### connection.update
86
+
87
+ ```typescript
88
+ sock.ev.on('connection.update', (update: ConnectionUpdate) => {
89
+ const { connection, lastDisconnect, qr, isNewLogin } = update;
90
+ // connection: 'close' | 'open' | 'connecting'
91
+ });
92
+ ```
93
+
94
+ #### message.upsert
95
+
96
+ ```typescript
97
+ sock.ev.on('message.upsert', ({ messages, type }) => {
98
+ // type: 'append' (history sync) | 'notify' (new message)
99
+ for (const msg of messages) {
100
+ console.log(msg.key.remoteJid, msg.message?.text);
101
+ }
102
+ });
103
+ ```
104
+
105
+ #### message.update
106
+
107
+ ```typescript
108
+ sock.ev.on('message.update', ({ messages, keys }) => {
109
+ for (const msg of messages) {
110
+ console.log(`Message ${msg.key.id} status: ${msg.status}`);
111
+ }
112
+ });
113
+ ```
114
+
115
+ #### message.reaction
116
+
117
+ ```typescript
118
+ sock.ev.on('message.reaction', ({ key, reaction, sender }) => {
119
+ console.log(`${sender} reacted ${reaction} to ${key.id}`);
120
+ });
121
+ ```
122
+
123
+ #### presence.update
124
+
125
+ ```typescript
126
+ sock.ev.on('presence.update', ({ jid, presence, t }) => {
127
+ console.log(`${jid} is ${presence}`);
128
+ });
129
+ ```
130
+
131
+ #### calls
132
+
133
+ ```typescript
134
+ sock.ev.on('calls', (callEvent) => {
135
+ console.log(`Incoming ${callEvent.isVideo ? 'video' : 'voice'} call from ${callEvent.from}`);
136
+ });
137
+ ```
138
+
139
+ #### group-participants.update
140
+
141
+ ```typescript
142
+ sock.ev.on('group-participants.update', (update) => {
143
+ const { id, participants, action, author } = update;
144
+ // action: 'add' | 'remove' | 'promote' | 'demote'
145
+ });
146
+ ```
147
+
148
+ #### qr.update
149
+
150
+ ```typescript
151
+ sock.ev.on('qr.update', (qrData) => {
152
+ console.log('New QR:', qrData.qrString);
153
+ });
154
+ ```
155
+
156
+ #### pairing-code.update
157
+
158
+ ```typescript
159
+ sock.ev.on('pairing-code.update', (result) => {
160
+ console.log(`Pairing code: ${result.code}`);
161
+ });
162
+ ```
163
+
164
+ ---
165
+
166
+ ### Send Messages
167
+
168
+ #### sendMessage
169
+
170
+ ```typescript
171
+ const result = await sock.sendMessage(
172
+ jid: JIDLike,
173
+ content: MessageContent,
174
+ options?: { messageId?: string; participant?: string; timeoutMs?: number }
175
+ );
176
+ ```
177
+
178
+ **Examples:**
179
+
180
+ ```typescript
181
+ // Text
182
+ await sock.sendMessage(jid, { text: 'Hello!' });
183
+
184
+ // Reply
185
+ await sock.sendMessage(jid, {
186
+ text: 'Reply',
187
+ quoted: originalMessage
188
+ });
189
+
190
+ // Image with caption
191
+ await sock.sendMessage(jid, {
192
+ image: { stream: buffer, mimetype: 'image/jpeg' },
193
+ caption: 'Photo caption'
194
+ });
195
+
196
+ // Mention users
197
+ await sock.sendMessage(jid, {
198
+ text: 'Hi @user1 @user2',
199
+ mentions: ['6281@whatsapp.net', '6282@whatsapp.net']
200
+ });
201
+
202
+ // Poll
203
+ await sock.sendMessage(jid, {
204
+ poll: {
205
+ name: 'Which one?',
206
+ values: ['A', 'B', 'C'],
207
+ selectableCounts: [1]
208
+ }
209
+ });
210
+
211
+ // Location
212
+ await sock.sendMessage(jid, {
213
+ location: {
214
+ degreesLatitude: -6.2088,
215
+ degreesLongitude: 106.8456,
216
+ name: 'Jakarta'
217
+ }
218
+ });
219
+
220
+ // Contact card
221
+ await sock.sendMessage(jid, {
222
+ contact: {
223
+ displayName: 'John Doe',
224
+ vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:John\nTEL:+62...\nEND:VCARD'
225
+ }
226
+ });
227
+
228
+ // View once media
229
+ await sock.sendMessage(jid, {
230
+ image: { stream: buf, mimetype: 'image/jpeg' },
231
+ viewOnce: true
232
+ });
233
+
234
+ // Ephemeral (auto-delete after 7 days)
235
+ await sock.sendMessage(jid, {
236
+ text: 'This disappears',
237
+ ephemeralExpiration: 604800
238
+ });
239
+ ```
240
+
241
+ #### forwardMessage
242
+
243
+ ```typescript
244
+ await sock.forwardMessage(to, originalMessage);
245
+ ```
246
+
247
+ #### deleteMessage
248
+
249
+ ```typescript
250
+ // Delete for me only
251
+ await sock.deleteMessage(jid, msgKey, { revokeEveryone: false });
252
+
253
+ // Delete for everyone
254
+ await sock.deleteMessage(jid, msgKey, { revokeEveryone: true });
255
+ ```
256
+
257
+ #### reactToMessage
258
+
259
+ ```typescript
260
+ await sock.reactToMessage(jid, msgKey, '👍');
261
+ await sock.reactToMessage(jid, msgKey, ''); // Remove reaction
262
+ ```
263
+
264
+ #### sendReadReceipt
265
+
266
+ ```typescript
267
+ await sock.sendReadReceipt(jid, [messageId1, messageId2]);
268
+ // For group messages:
269
+ await sock.sendReadReceipt(groupJid, [messageId], senderJid);
270
+ ```
271
+
272
+ #### sendPresenceUpdate
273
+
274
+ ```typescript
275
+ // Typing indicator
276
+ await sock.sendPresenceUpdate(jid, 'composing');
277
+
278
+ // Voice recording indicator
279
+ await sock.sendPresenceUpdate(jid, 'recording');
280
+
281
+ // Stop typing
282
+ await sock.sendPresenceUpdate(jid, 'paused');
283
+ ```
284
+
285
+ #### updatePresence
286
+
287
+ ```typescript
288
+ // Set yourself online
289
+ await sock.updatePresence('available');
290
+
291
+ // Set yourself offline
292
+ await sock.updatePresence('unavailable');
293
+ ```
294
+
295
+ ---
296
+
297
+ ### Media
298
+
299
+ #### uploadMedia
300
+
301
+ ```typescript
302
+ import { readFileSync } from 'fs';
303
+ const buffer = readFileSync('photo.jpg');
304
+
305
+ const result = await sock.uploadMedia(
306
+ buffer,
307
+ 'image', // media type: 'image' | 'video' | 'audio' | 'document' | 'sticker'
308
+ 'image/jpeg', // mimetype
309
+ 'photo.jpg' // filename (optional, required for documents)
310
+ );
311
+
312
+ console.log(result.url, result.mediaKey, result.fileLength);
313
+ ```
314
+
315
+ #### downloadMedia
316
+
317
+ ```typescript
318
+ const result = await sock.downloadMedia(
319
+ msg.message.image.url, // URL dari incoming message
320
+ msg.message.image.mediaKey,
321
+ 'image',
322
+ msg.message.image.mimetype,
323
+ 'downloaded.jpg'
324
+ );
325
+
326
+ import { writeFileSync } from 'fs';
327
+ writeFileSync('photo.jpg', result.buffer);
328
+ ```
329
+
330
+ ---
331
+
332
+ ### Groups
333
+
334
+ #### groupCreate
335
+
336
+ ```typescript
337
+ const group = await sock.groupCreate({
338
+ subject: 'My Group',
339
+ participants: ['6281@s.whatsapp.net', '6282@s.whatsapp.net'],
340
+ desc: 'Group description'
341
+ });
342
+ ```
343
+
344
+ #### groupMetadata
345
+
346
+ ```typescript
347
+ const metadata = await sock.groupMetadata(groupJid);
348
+ console.log(metadata.subject, metadata.participants.length);
349
+
350
+ // Check if user is admin
351
+ const isAdmin = metadata.participants.find(
352
+ p => jidToString(p.id) === userJid
353
+ )?.isAdmin;
354
+ ```
355
+
356
+ #### Group Operations
357
+
358
+ ```typescript
359
+ // Update subject
360
+ await sock.groupUpdateSubject(groupJid, 'New Name');
361
+
362
+ // Update description
363
+ await sock.groupUpdateDescription(groupJid, 'New description');
364
+
365
+ // Participant actions
366
+ await sock.groupParticipantsUpdate(groupJid, [userJid], 'add');
367
+ await sock.groupParticipantsUpdate(groupJid, [userJid], 'remove');
368
+ await sock.groupParticipantsUpdate(groupJid, [userJid], 'promote');
369
+ await sock.groupParticipantsUpdate(groupJid, [userJid], 'demote');
370
+
371
+ // Invite links
372
+ const code = await sock.groupInviteCode(groupJid);
373
+ // → "AbCdEfGhIjK"
374
+ const url = `https://chat.whatsapp.com/${code}`;
375
+
376
+ await sock.groupRevokeInvite(groupJid); // Revoke old, get new code
377
+ await sock.groupJoinViaCode('inviteCode'); // Join external group
378
+
379
+ // Leave group
380
+ await sock.groupLeave(groupJid);
381
+
382
+ // Settings
383
+ await sock.groupSettingUpdate(groupJid, 'restrict', true); // Only admins send
384
+ await sock.groupSettingUpdate(groupJid, 'announce', true); // Only admins edit info
385
+ ```
386
+
387
+ ---
388
+
389
+ ### Calls
390
+
391
+ ```typescript
392
+ sock.ev.on('calls', async (callEvent) => {
393
+ console.log(`Call from ${callEvent.from}`);
394
+
395
+ // Auto reject all calls
396
+ await sock.rejectCall(callEvent.id, callEvent.from);
397
+ });
398
+ ```
399
+
400
+ ---
401
+
402
+ ### Chat Operations
403
+
404
+ #### readChat
405
+
406
+ ```typescript
407
+ await sock.readChat(jid);
408
+ ```
409
+
410
+ #### archiveChat
411
+
412
+ ```typescript
413
+ await sock.archiveChat(jid, true); // Archive
414
+ await sock.archiveChat(jid, false); // Unarchive
415
+ ```
416
+
417
+ #### muteChat
418
+
419
+ ```typescript
420
+ await sock.muteChat(jid, 60 * 60 * 1000); // Mute for 1 hour
421
+ await sock.muteChat(jid, 7 * 24 * 60 * 60 * 1000); // Mute for 1 week
422
+ await sock.muteChat(jid, 0); // Unmute
423
+ ```
424
+
425
+ #### pinChat
426
+
427
+ ```typescript
428
+ await sock.pinChat(jid, 7 * 24 * 60 * 60 * 1000); // Pin for 7 days
429
+ await sock.pinChat(jid, 0); // Unpin
430
+ ```
431
+
432
+ #### deleteChat
433
+
434
+ ```typescript
435
+ await sock.deleteChat(jid);
436
+ ```
437
+
438
+ ---
439
+
440
+ ### Presence
441
+
442
+ #### presenceSubscribe
443
+
444
+ ```typescript
445
+ // Subscribe to presence updates for multiple users
446
+ await sock.presenceSubscribe([
447
+ '6281@s.whatsapp.net',
448
+ '6282@s.whatsapp.net'
449
+ ]);
450
+
451
+ // Listen to updates
452
+ sock.ev.on('presence.update', ({ jid, presence }) => {
453
+ console.log(`${jid} is ${presence}`);
454
+ // presence: 'available' | 'unavailable' | 'composing' | 'recording' | 'paused'
455
+ });
456
+ ```
457
+
458
+ ---
459
+
460
+ ### Connection
461
+
462
+ #### end
463
+
464
+ ```typescript
465
+ await sock.end(); // Close connection
466
+ await sock.end(true); // End and signal new connection needed
467
+ ```
468
+
469
+ #### getConnectionState
470
+
471
+ ```typescript
472
+ const state = sock.getConnectionState();
473
+ // 'close' | 'open' | 'connecting'
474
+ ```
475
+
476
+ #### logout
477
+
478
+ ```typescript
479
+ await sock.logout(); // Logout and clear session files
480
+ ```
481
+
482
+ #### refreshQR
483
+
484
+ ```typescript
485
+ const newQR = await sock.refreshQR();
486
+ console.log(newQR.qrString);
487
+ ```
488
+
489
+ #### requestPairingCode
490
+
491
+ ```typescript
492
+ const result = await sock.requestPairingCode('6281234567890');
493
+ console.log(`Pairing code: ${result.code}`);
494
+ // → "AB12-CD34"
495
+ ```
496
+
497
+ ---
498
+
499
+ ## Core APIs
500
+
501
+ ### Crypto
502
+
503
+ ```typescript
504
+ import {
505
+ generateCurveKeyPair,
506
+ curveSharedSecret,
507
+ sha256Hash,
508
+ hmacSha256,
509
+ hkdfDerive,
510
+ createAESCipher,
511
+ aesEncryptCBC,
512
+ aesDecryptCBC,
513
+ getRandomBytes
514
+ } from 'waliwa';
515
+
516
+ const keypair = generateCurveKeyPair();
517
+ const shared = curveSharedSecret(keypair.private, otherPublic);
518
+ const hash = sha256Hash(data);
519
+ const mac = hmacSha256(key, data);
520
+ const derived = hkdfDerive(ikm, salt, info, 32);
521
+ ```
522
+
523
+ ### Noise Protocol
524
+
525
+ ```typescript
526
+ import { NoiseHandshake, TrafficCipher } from 'waliwa';
527
+
528
+ const handshake = new NoiseHandshake(staticKeyPair, true);
529
+ const clientHello = handshake.buildClientHello(payload);
530
+ // ... send to server, receive response ...
531
+ handshake.readResponderHandshake(response);
532
+ const { sendKey, recvKey } = handshake.finalize();
533
+
534
+ const cipher = new TrafficCipher(sendKey, recvKey);
535
+ const encrypted = cipher.encrypt(plaintext);
536
+ const decrypted = cipher.decrypt(ciphertext);
537
+ ```
538
+
539
+ ### Binary Protocol
540
+
541
+ ```typescript
542
+ import { encodeBinaryNode, decodeBinaryNode, binaryNodeToString } from 'waliwa';
543
+
544
+ const node = {
545
+ tag: 'message',
546
+ attrs: { to: 'user@s.whatsapp.net', type: 'text' },
547
+ content: [{ tag: 'conversation', attrs: {}, content: 'Hello' }]
548
+ };
549
+
550
+ const bytes = encodeBinaryNode(node);
551
+ const decoded = decodeBinaryNode(bytes);
552
+ console.log(binaryNodeToString(decoded));
553
+ ```
554
+
555
+ ---
556
+
557
+ ## Auth APIs
558
+
559
+ ### FileAuthState
560
+
561
+ ```typescript
562
+ import { FileAuthState, createDefaultCreds } from 'waliwa';
563
+
564
+ const state = new FileAuthState({
565
+ folder: './auth',
566
+ prefix: 'session',
567
+ writeDebounceMs: 100
568
+ });
569
+
570
+ // Access creds
571
+ console.log(state.creds.registered);
572
+
573
+ // Save manually
574
+ state.markCredsDirty();
575
+
576
+ // Clear session (logout)
577
+ await state.clear();
578
+
579
+ // Manage pre-keys
580
+ const preKey = state.generatePreKey(1);
581
+ state.setPreKey(2, keyPair);
582
+ ```
583
+
584
+ ### QR Code Generation
585
+
586
+ ```typescript
587
+ import { generateQRCodeData, buildQRString, parseQRString } from 'waliwa';
588
+
589
+ const qrData = generateQRCodeData({
590
+ creds: state.creds,
591
+ printInTerminal: true
592
+ });
593
+
594
+ console.log(qrData.qrString);
595
+ console.log(qrData.ref);
596
+ console.log(qrData.publicKey);
597
+
598
+ // Parse existing QR
599
+ const parsed = parseQRString(qrData.qrString);
600
+ ```
601
+
602
+ ### Pairing Code
603
+
604
+ ```typescript
605
+ import { generatePairingCode, normalizePairingCode } from 'waliwa';
606
+
607
+ const result = generatePairingCode('6281234567890', state.creds);
608
+ console.log(result.code); // "AB12-CD34"
609
+
610
+ // Normalize user input
611
+ const clean = normalizePairingCode('ab12cd34'); // "AB12-CD34"
612
+ ```
613
+
614
+ ---
615
+
616
+ ## Utility APIs
617
+
618
+ ### JID Utilities
619
+
620
+ ```typescript
621
+ import {
622
+ parseJid,
623
+ jidToString,
624
+ isGroupJid,
625
+ isUserJid,
626
+ jidEqual,
627
+ userJid,
628
+ groupJid
629
+ } from 'waliwa';
630
+
631
+ const jid = parseJid('6281234567890@s.whatsapp.net');
632
+ console.log(jid.user); // "6281234567890"
633
+ console.log(jid.server); // "s.whatsapp.net"
634
+
635
+ isGroupJid('12345@g.us'); // true
636
+ isUserJid('6281@s.whatsapp.net'); // true
637
+ jidEqual('6281@s.whatsapp.net', '6281@s.whatsapp.net'); // true
638
+
639
+ userJid('6281234567890'); // "6281234567890@s.whatsapp.net"
640
+ groupJid('12345-67890'); // "12345-67890@g.us"
641
+ ```
642
+
643
+ ### Logger
644
+
645
+ ```typescript
646
+ import { DefaultLogger, SilentLogger, defaultLogger } from 'waliwa';
647
+
648
+ const logger = new DefaultLogger('debug');
649
+ logger.info('Hello');
650
+ logger.child({ module: 'auth' }).debug('Sub-logger');
651
+
652
+ // Silent logger (no output)
653
+ const silent = new SilentLogger();
654
+ ```
655
+
656
+ ### Retry & Throttle
657
+
658
+ ```typescript
659
+ import { retry, RateLimiter, sleep, debounce, throttle } from 'waliwa';
660
+
661
+ // Retry with exponential backoff
662
+ const result = await retry(async () => {
663
+ return await riskyOperation();
664
+ }, {
665
+ retries: 5,
666
+ minTimeout: 500,
667
+ maxTimeout: 30000,
668
+ onFailedAttempt: (err, attempt) => console.log(`Attempt ${attempt} failed`)
669
+ });
670
+
671
+ // Rate limiter (20 ops/second)
672
+ const limiter = new RateLimiter(20);
673
+ await limiter.acquire();
674
+ // do work
675
+
676
+ // Debounce
677
+ const debounced = debounce(() => save(), 100);
678
+
679
+ // Throttle
680
+ const throttled = throttle(() => send(), 1000);
681
+ ```
682
+
683
+ ---
684
+
685
+ ## Type Definitions
686
+
687
+ All types are exported from the main package:
688
+
689
+ ```typescript
690
+ import type {
691
+ // Auth
692
+ AuthState, AuthenticationCreds, KeyPair, SignalKeyStore,
693
+
694
+ // Messages
695
+ MessageContent, WAMessage, WAMessageKey, MessageStatus,
696
+
697
+ // Groups
698
+ WAGroupMetadata, WAGroupParticipant, GroupCreateOptions,
699
+
700
+ // Calls
701
+ WACallEvent, CallStatus,
702
+
703
+ // Connection
704
+ WaliwaConfig, ConnectionUpdate, WALogger,
705
+
706
+ // JID
707
+ JID, JIDLike,
708
+
709
+ // Events
710
+ WAEventMap,
711
+
712
+ // Advanced
713
+ PollOptions, NewsletterMetadata, BusinessProfileOptions
714
+ } from 'waliwa';
715
+ ```
716
+
717
+ ---
718
+
719
+ ## Error Handling
720
+
721
+ All async operations may throw errors. Common error types:
722
+
723
+ ```typescript
724
+ try {
725
+ await sock.sendMessage(jid, { text: 'Hello' });
726
+ } catch (err) {
727
+ if (err.message.includes('timeout')) {
728
+ // Message send timeout
729
+ } else if (err.message.includes('not connected')) {
730
+ // WebSocket not connected
731
+ } else if (err.message.includes('rate limit')) {
732
+ // Rate limited
733
+ }
734
+ }
735
+ ```
736
+
737
+ For robust production usage, always wrap in try/catch and implement retry logic with exponential backoff.
738
+
739
+ ---
740
+
741
+ ## Version
742
+
743
+ Current version: **1.0.0**
744
+
745
+ For changelog and migration guides, see [CHANGELOG.md](../CHANGELOG.md).