@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
@@ -0,0 +1,489 @@
1
+ # WhatsApp Protocol Reverse Engineering
2
+
3
+ This document describes the WhatsApp protocols implemented in Waliwa, based on publicly documented reverse engineering efforts.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [WhatsApp Web Multi-Device Protocol](#whatsapp-web-multi-device-protocol)
8
+ 2. [Mobile API Pairing Protocol](#mobile-api-pairing-protocol)
9
+ 3. [Binary Protocol Format](#binary-protocol-format)
10
+ 4. [Noise Protocol Handshake](#noise-protocol-handshake)
11
+ 5. [Media Encryption](#media-encryption)
12
+ 6. [Message Types](#message-types)
13
+
14
+ ## WhatsApp Web Multi-Device Protocol
15
+
16
+ ### Connection
17
+
18
+ WhatsApp Web MD connects to `wss://web.whatsapp.com/ws/chat` via WebSocket with custom headers:
19
+
20
+ ```
21
+ Origin: https://web.whatsapp.com
22
+ User-Agent: Mozilla/5.0 ...
23
+ ```
24
+
25
+ WebSocket compression is disabled to reduce CPU overhead.
26
+
27
+ ### Frame Format
28
+
29
+ Every frame follows this structure:
30
+
31
+ ```
32
+ ┌─────────┬──────────┬───────────┬─────────────────────┐
33
+ │ WA (2B) │ Ver (2B) │ Len (3B) │ Encrypted Payload │
34
+ └─────────┴──────────┴───────────┴─────────────────────┘
35
+ ```
36
+
37
+ - **WA (2 bytes)**: Magic header `0x57 0x41` ("WA")
38
+ - **Version (2 bytes)**: Protocol version, typically `0x05 0x2d`
39
+ - **Length (3 bytes)**: Big-endian length of payload (max 16MB)
40
+ - **Payload**: AES-256-GCM encrypted with traffic keys
41
+
42
+ ### Traffic Encryption
43
+
44
+ After Noise handshake completes, two traffic keys are derived:
45
+ - `sendKey` (32 bytes) - For encrypting outgoing frames
46
+ - `recvKey` (32 bytes) - For decrypting incoming frames
47
+
48
+ Each frame uses counter-based nonce:
49
+ ```
50
+ Nonce (12 bytes):
51
+ ┌───────────────┬───────────────┐
52
+ │ 4 bytes zeros │ 8 bytes counter│
53
+ └───────────────┴───────────────┘
54
+ ```
55
+
56
+ Counter increments per message (separate counters for send/recv).
57
+
58
+ ### Keep-Alive
59
+
60
+ Every 20 seconds, client sends ping:
61
+ ```xml
62
+ <iq type="get" id="ping-123">
63
+ <ping/>
64
+ </iq>
65
+ ```
66
+
67
+ Server responds with `<iq type="result" id="ping-123"/>`.
68
+
69
+ ## Mobile API Pairing Protocol
70
+
71
+ ### Pairing Code Generation
72
+
73
+ Pairing code is 8 alphanumeric characters derived via HKDF:
74
+
75
+ 1. Inputs:
76
+ - Phone number (target, digits only)
77
+ - Pairing static key (Curve25519 private key, 32 bytes)
78
+
79
+ 2. Derivation:
80
+ ```
81
+ derived = HKDF-SHA256(
82
+ ikm = pairingKey.private,
83
+ salt = phoneNumber_bytes,
84
+ info = "pairing-code-v1",
85
+ length = 4 bytes
86
+ )
87
+ ```
88
+
89
+ 3. Encoding (4 bytes → 8 chars):
90
+ - Each nibble (4 bits) → 1 char from "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
91
+ - Ambiguous characters (0/O, 1/I) excluded
92
+ - Format: `XXXX-XXXX` (dash separator at position 4)
93
+
94
+ ### Pairing Request Flow
95
+
96
+ ```
97
+ Client Server
98
+ │ │
99
+ │ WebSocket + Noise handshake │
100
+ │ ─────────────────────────────────→ │
101
+ │ │
102
+ │ Pairing request: │
103
+ │ <iq type="set" to="s.whatsapp.net">│
104
+ │ <pair code="AB12CD34" │
105
+ │ phone="6281234567890" │
106
+ │ pubkey="<base64>" │
107
+ │ platform="Waliwa"/> │
108
+ │ </iq> │
109
+ │ ─────────────────────────────────→ │
110
+ │ │
111
+ │ User inputs code in mobile app │
112
+ │ │
113
+ │ Pairing result: │
114
+ │ <iq type="result"> │
115
+ │ <pair jid="6281234567890@..." │
116
+ │ platform="android" │
117
+ │ identity="<base64>"/> │
118
+ │ </iq> │
119
+ │ ←─────────────────────────────────│
120
+ │ │
121
+ ```
122
+
123
+ ### Pairing Code Expiry
124
+
125
+ - Code expires after 65 seconds
126
+ - Client must refresh and request new code if expired
127
+ - Server rejects expired codes with `<error code="410">`
128
+
129
+ ## Binary Protocol Format
130
+
131
+ WhatsApp uses a custom binary format for encoding XML-like nodes.
132
+
133
+ ### Node Structure
134
+
135
+ ```
136
+ Node = Tag + Attributes + Content
137
+
138
+ Tag: string (dictionary-encoded)
139
+ Attributes: { key: value, ... }
140
+ Content: string | bytes | Node[] | undefined
141
+ ```
142
+
143
+ ### Encoding Tags
144
+
145
+ | Tag Value | Meaning | Description |
146
+ |-----------|----------------------|------------------------------------------|
147
+ | 0x00 | EMPTY | Empty string or no content |
148
+ | 0xF8 | LIST_8 | List with 8-bit count |
149
+ | 0xF9 | LIST_16 | List with 16-bit count |
150
+ | 0xFA | JID_PAIR | JID user@server format |
151
+ | 0xFB | PACKED_NIBBLE | Numeric string (4 bits per char) |
152
+ | 0xFC | BINARY_8 / PACKED_HEX| Binary 8-bit length / Hex string |
153
+ | 0xFD | BINARY_20 | Binary 20-bit length |
154
+ | 0xFE | BINARY_32 | Binary 32-bit length |
155
+ | 0xFF | ADJACENT | Adjacent node marker |
156
+
157
+ ### Dictionary Encoding
158
+
159
+ Common strings are stored in 4 dictionaries (240+ entries each). Encoding:
160
+ - Look up string in dictionary
161
+ - If found: emit `0xFC + dict_num` byte, then index byte (1 byte total)
162
+ - If not found: emit as raw bytes with length prefix
163
+
164
+ ### Packed Nibble Encoding
165
+
166
+ For numeric strings (phone numbers, IDs), use nibble packing:
167
+ - 2 characters per byte (4 bits each)
168
+ - Append `0xF` terminator if odd length
169
+
170
+ Example: `"12345"` → `[0x12, 0x34, 0x5F]`
171
+
172
+ ### Packed Hex Encoding
173
+
174
+ For hex strings (hashes, IDs), use hex packing:
175
+ - Same as nibble but supports `a-f` characters
176
+ - Append `0xF` terminator if odd length
177
+
178
+ ### Binary Encoding
179
+
180
+ For arbitrary bytes (media hashes, encrypted payloads):
181
+ - **BINARY_8**: 1-byte length prefix (max 255 bytes)
182
+ - **BINARY_20**: 3-byte length prefix (max 1MB)
183
+ - **BINARY_32**: 4-byte length prefix (max 4GB)
184
+
185
+ ## Noise Protocol Handshake
186
+
187
+ WhatsApp uses Noise Protocol Framework with **XX pattern**:
188
+
189
+ ### Protocol Name
190
+ ```
191
+ Noise_XX_25519_AESGCM_SHA256
192
+ ```
193
+
194
+ ### Handshake Flow
195
+
196
+ ```
197
+ Client Server
198
+ │ │
199
+ │ -> e │ (ephemeral key, 32 bytes)
200
+ │ ─────────────────────────────────→ │
201
+ │ │
202
+ │ <- e, ee, s, es │
203
+ │ │
204
+ │ (server ephemeral + encrypted │
205
+ │ server static + DH computations) │
206
+ │ ←─────────────────────────────────│
207
+ │ │
208
+ │ -> s, se │
209
+ │ │
210
+ │ (client static, encrypted with │
211
+ │ current handshake key) │
212
+ │ ─────────────────────────────────→ │
213
+ │ │
214
+ │ Handshake complete │
215
+ │ Traffic keys derived │
216
+ │ │
217
+ ```
218
+
219
+ ### Key Derivation
220
+
221
+ ```
222
+ Initial state:
223
+ ck = SHA256("Noise_XX_25519_AESGCM_SHA256")
224
+ h = SHA256("Noise_XX_25519_AESGCM_SHA256")
225
+
226
+ Step 1: Client sends ephemeral
227
+ h = SHA256(h || client_ephemeral_pub)
228
+ ck, k = HKDF(ck, client_ephemeral_pub, info=empty, 64 bytes)
229
+ (split: ck = first 32, k = next 32)
230
+
231
+ Step 2: Server sends ephemeral + encrypted static
232
+ h = SHA256(h || server_ephemeral_pub)
233
+ ck, k = HKDF(ck, server_ephemeral_pub, info=empty, 64 bytes)
234
+
235
+ ee = X25519(client_ephemeral_priv, server_ephemeral_pub)
236
+ ck, k = HKDF(ck, ee, info=empty, 64 bytes)
237
+
238
+ server_static_encrypted = AES-GCM-Encrypt(k, h, server_static_pub)
239
+ h = SHA256(h || server_static_pub)
240
+
241
+ es = X25519(client_ephemeral_priv, server_static_pub)
242
+ ck, k = HKDF(ck, es, info=empty, 64 bytes)
243
+
244
+ Step 3: Client sends encrypted static
245
+ client_static_encrypted = AES-GCM-Encrypt(k, h, client_static_pub)
246
+ h = SHA256(h || client_static_pub)
247
+
248
+ se = X25519(client_static_priv, server_ephemeral_pub)
249
+ ck, k = HKDF(ck, se, info=empty, 64 bytes)
250
+
251
+ Final: Traffic keys
252
+ prk = HKDF(ck, empty_input, "Noise_XX_..._handshake_done", 64 bytes)
253
+ sendKey = prk[:32]
254
+ recvKey = prk[32:64]
255
+ ```
256
+
257
+ ### AEAD Construction
258
+
259
+ AES-256-GCM with:
260
+ - Key: 32 bytes (derived from HKDF)
261
+ - Nonce: 12 bytes (4 bytes zeros + 8 bytes counter, big-endian)
262
+ - AAD: Current handshake hash `h`
263
+ - Plaintext: Message payload
264
+ - Output: Ciphertext + 16-byte tag
265
+
266
+ Counter starts at 0 and increments per message (separate for send/recv).
267
+
268
+ ## Media Encryption
269
+
270
+ ### Media Key Derivation
271
+
272
+ ```
273
+ mediaKey = random 32 bytes
274
+ derived = HKDF-SHA256(
275
+ ikm = mediaKey,
276
+ salt = [mediaType_byte],
277
+ info = "WhatsApp ${mediaType} Keys",
278
+ length = 112 bytes
279
+ )
280
+
281
+ iv = derived[0:16]
282
+ cipherKey = derived[16:48]
283
+ macKey = derived[48:80]
284
+ refKey = derived[80:112]
285
+ ```
286
+
287
+ Media type bytes:
288
+ - 1 = image
289
+ - 2 = video
290
+ - 3 = audio
291
+ - 4 = document
292
+ - 5 = sticker
293
+ - etc.
294
+
295
+ ### Encryption Process
296
+
297
+ ```
298
+ 1. fileSha256 = SHA256(plaintext)
299
+ 2. ciphertext = AES-256-CBC-Encrypt(cipherKey, iv, plaintext + PKCS7_PAD)
300
+ 3. mac = HMAC-SHA256(macKey, iv + ciphertext)[0:10]
301
+ 4. encFileSha256 = SHA256(ciphertext + mac)
302
+ 5. Upload (ciphertext + mac) to CDN
303
+ ```
304
+
305
+ Note: MAC is truncated to 10 bytes (not full 32) for bandwidth efficiency.
306
+
307
+ ### Decryption Process
308
+
309
+ ```
310
+ 1. Split: ciphertext = data[:-10], mac = data[-10:]
311
+ 2. expectedMac = HMAC-SHA256(macKey, iv + ciphertext)[0:10]
312
+ 3. Verify mac == expectedMac (constant-time comparison)
313
+ 4. plaintext = AES-256-CBC-Decrypt(cipherKey, iv, ciphertext)
314
+ 5. Strip PKCS7 padding
315
+ ```
316
+
317
+ ## Message Types
318
+
319
+ ### Text Message
320
+
321
+ ```xml
322
+ <message to="jid" type="text" id="msgId">
323
+ <conversation>Text content</conversation>
324
+ </message>
325
+ ```
326
+
327
+ ### Image Message
328
+
329
+ ```xml
330
+ <message to="jid" type="media" id="msgId">
331
+ <imageMessage
332
+ url="https://mmg.whatsapp.net/..."
333
+ mimetype="image/jpeg"
334
+ fileSha256="<base64>"
335
+ fileLength="12345"
336
+ mediaKey="<base64>"
337
+ encFileSha256="<base64>">
338
+ <caption>Optional caption</caption>
339
+ </imageMessage>
340
+ </message>
341
+ ```
342
+
343
+ ### Reply (Quoted) Message
344
+
345
+ ```xml
346
+ <message to="jid" type="text" id="msgId">
347
+ <conversation>Reply text</conversation>
348
+ <contextInfo>
349
+ <stanzaId>original_msg_id</stanzaId>
350
+ <participant>original_sender@s.whatsapp.net</participant>
351
+ <quotedMessage>Original text</quotedMessage>
352
+ <mentionedJidList>
353
+ <user>mentioned_user@s.whatsapp.net</user>
354
+ </mentionedJidList>
355
+ </contextInfo>
356
+ </message>
357
+ ```
358
+
359
+ ### Reaction
360
+
361
+ ```xml
362
+ <message to="jid" type="reaction" id="msgId">
363
+ <reactionMessage
364
+ key='{"id":"original_id","fromMe":false,"remoteJid":"..."}'
365
+ text="👍"
366
+ timestamp="1234567890"/>
367
+ </message>
368
+ ```
369
+
370
+ ### Poll
371
+
372
+ ```xml
373
+ <message to="jid" type="poll" id="msgId">
374
+ <pollCreationMessage name="Question?" selectableOptionsCount="[1]">
375
+ <option index="0" name="Option 1"/>
376
+ <option index="1" name="Option 2"/>
377
+ </pollCreationMessage>
378
+ </message>
379
+ ```
380
+
381
+ ## Receipts
382
+
383
+ ### Read Receipt
384
+
385
+ ```xml
386
+ <receipt id="msgId" type="read" to="jid@s.whatsapp.net" t="1234567890">
387
+ <receipt id="msgId1"/>
388
+ <receipt id="msgId2"/>
389
+ </receipt>
390
+ ```
391
+
392
+ ### Delivery Receipt
393
+
394
+ ```xml
395
+ <receipt id="msgId" type="delivered" to="jid" t="1234567890"/>
396
+ ```
397
+
398
+ ## Presence
399
+
400
+ ### Subscribe to User Presence
401
+
402
+ ```xml
403
+ <iq type="set" to="s.whatsapp.net" id="sub-1">
404
+ <user jid="target@s.whatsapp.net"/>
405
+ </iq>
406
+ ```
407
+
408
+ ### Presence Update
409
+
410
+ ```xml
411
+ <presence from="user@s.whatsapp.net" type="available" t="1234567890"/>
412
+ ```
413
+
414
+ ### Typing Indicator
415
+
416
+ ```xml
417
+ <chat to="jid" type="composing"/>
418
+ <chat to="jid" type="recording"/>
419
+ <chat to="jid" type="paused"/>
420
+ ```
421
+
422
+ ## Group Operations
423
+
424
+ ### Create Group
425
+
426
+ ```xml
427
+ <iq type="set" to="g.us" id="create-1">
428
+ <create subject="Group Name">
429
+ <participant jid="user1@s.whatsapp.net"/>
430
+ <participant jid="user2@s.whatsapp.net"/>
431
+ </create>
432
+ </iq>
433
+ ```
434
+
435
+ ### Add/Remove Participants
436
+
437
+ ```xml
438
+ <iq type="set" to="group@g.us" id="add-1">
439
+ <add>
440
+ <participant jid="newuser@s.whatsapp.net"/>
441
+ </add>
442
+ </iq>
443
+ ```
444
+
445
+ ### Group Settings
446
+
447
+ ```xml
448
+ <!-- Restrict (only admins can send) -->
449
+ <iq type="set" to="group@g.us" id="restrict-1">
450
+ <announce type="restrict"/>
451
+ </iq>
452
+
453
+ <!-- Announce (only admins can edit info) -->
454
+ <iq type="set" to="group@g.us" id="announce-1">
455
+ <info type="announce"/>
456
+ </iq>
457
+ ```
458
+
459
+ ## Call Events
460
+
461
+ ### Incoming Call
462
+
463
+ ```xml
464
+ <call
465
+ from="caller@s.whatsapp.net"
466
+ id="call-123"
467
+ to="me@s.whatsapp.net"
468
+ video="false"
469
+ status="ringing"/>
470
+ ```
471
+
472
+ ### Reject Call
473
+
474
+ ```xml
475
+ <call
476
+ id="call-123"
477
+ to="caller@s.whatsapp.net"
478
+ action="reject"
479
+ type="reject"/>
480
+ ```
481
+
482
+ ## References
483
+
484
+ - [Noise Protocol Framework Specification](https://noiseprotocol.org/)
485
+ - [Signal Protocol Documentation](https://signal.org/docs/)
486
+ - [HKDF (RFC 5869)](https://tools.ietf.org/html/rfc5869)
487
+ - [WhatsApp Multi-Device Documentation](https://faq.whatsapp.com/384073008)
488
+
489
+ *Note: Protocol details are based on publicly documented reverse engineering efforts. WhatsApp may change protocol without notice.*