@neelegirl/baileys 1.5.2 → 1.5.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 (193) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +195 -187
  3. package/WAProto/WAProto.proto +537 -236
  4. package/WAProto/index.d.ts +5971 -2388
  5. package/WAProto/index.js +17298 -6513
  6. package/lib/Defaults/baileys-version.json +3 -3
  7. package/lib/Defaults/index.d.ts +77 -67
  8. package/lib/Defaults/index.js +148 -136
  9. package/lib/Defaults/phonenumber-mcc.json +223 -223
  10. package/lib/Signal/WASignalGroup/GroupProtocol.js +1908 -1908
  11. package/lib/Signal/WASignalGroup/ciphertext-message.d.ts +9 -0
  12. package/lib/Signal/WASignalGroup/ciphertext-message.js +19 -0
  13. package/lib/Signal/WASignalGroup/ciphertext_message.js +15 -15
  14. package/lib/Signal/WASignalGroup/group-session-builder.d.ts +17 -0
  15. package/lib/Signal/WASignalGroup/group-session-builder.js +72 -0
  16. package/lib/Signal/WASignalGroup/group.proto +41 -41
  17. package/lib/Signal/WASignalGroup/group_cipher.d.ts +19 -0
  18. package/lib/Signal/WASignalGroup/group_cipher.js +101 -110
  19. package/lib/Signal/WASignalGroup/group_session_builder.js +45 -45
  20. package/lib/Signal/WASignalGroup/index.d.ts +11 -0
  21. package/lib/Signal/WASignalGroup/index.js +61 -6
  22. package/lib/Signal/WASignalGroup/keyhelper.d.ts +16 -0
  23. package/lib/Signal/WASignalGroup/keyhelper.js +58 -13
  24. package/lib/Signal/WASignalGroup/protobufs.js +2 -2
  25. package/lib/Signal/WASignalGroup/queue_job.js +68 -68
  26. package/lib/Signal/WASignalGroup/readme.md +5 -5
  27. package/lib/Signal/WASignalGroup/sender-chain-key.d.ts +14 -0
  28. package/lib/Signal/WASignalGroup/sender-chain-key.js +47 -0
  29. package/lib/Signal/WASignalGroup/sender-key-distribution-message.d.ts +17 -0
  30. package/lib/Signal/WASignalGroup/sender-key-distribution-message.js +71 -0
  31. package/lib/Signal/WASignalGroup/sender-key-message.d.ts +19 -0
  32. package/lib/Signal/WASignalGroup/sender-key-message.js +73 -0
  33. package/lib/Signal/WASignalGroup/sender-key-name.d.ts +19 -0
  34. package/lib/Signal/WASignalGroup/sender-key-name.js +59 -0
  35. package/lib/Signal/WASignalGroup/sender-key-record.d.ts +32 -0
  36. package/lib/Signal/WASignalGroup/sender-key-record.js +58 -0
  37. package/lib/Signal/WASignalGroup/sender-key-state.d.ts +44 -0
  38. package/lib/Signal/WASignalGroup/sender-key-state.js +147 -0
  39. package/lib/Signal/WASignalGroup/sender-message-key.d.ts +11 -0
  40. package/lib/Signal/WASignalGroup/sender-message-key.js +33 -0
  41. package/lib/Signal/WASignalGroup/sender_chain_key.js +49 -49
  42. package/lib/Signal/WASignalGroup/sender_key_distribution_message.js +77 -77
  43. package/lib/Signal/WASignalGroup/sender_key_message.js +91 -91
  44. package/lib/Signal/WASignalGroup/sender_key_name.js +69 -69
  45. package/lib/Signal/WASignalGroup/sender_key_record.js +55 -55
  46. package/lib/Signal/WASignalGroup/sender_key_state.js +128 -128
  47. package/lib/Signal/WASignalGroup/sender_message_key.js +38 -38
  48. package/lib/Signal/libsignal.d.ts +5 -1
  49. package/lib/Signal/libsignal.js +390 -161
  50. package/lib/Signal/lid-mapping.d.ts +28 -0
  51. package/lib/Signal/lid-mapping.js +184 -0
  52. package/lib/Socket/Client/abstract-socket-client.d.ts +15 -15
  53. package/lib/Socket/Client/abstract-socket-client.js +13 -13
  54. package/lib/Socket/Client/index.d.ts +2 -2
  55. package/lib/Socket/Client/mobile-socket-client.d.ts +12 -12
  56. package/lib/Socket/Client/mobile-socket-client.js +65 -65
  57. package/lib/Socket/Client/types.d.ts +1 -1
  58. package/lib/Socket/Client/websocket.d.ts +1 -1
  59. package/lib/Socket/business.d.ts +6 -6
  60. package/lib/Socket/business.js +152 -5
  61. package/lib/Socket/chats.d.ts +3 -4
  62. package/lib/Socket/chats.js +31 -26
  63. package/lib/Socket/communities.d.ts +223 -223
  64. package/lib/Socket/communities.js +432 -432
  65. package/lib/Socket/groups.d.ts +2 -4
  66. package/lib/Socket/groups.js +22 -14
  67. package/lib/Socket/index.d.ts +69 -69
  68. package/lib/Socket/index.js +3 -2
  69. package/lib/Socket/messages-recv.d.ts +3 -6
  70. package/lib/Socket/messages-recv.js +1449 -1707
  71. package/lib/Socket/messages-send.d.ts +2 -4
  72. package/lib/Socket/messages-send.js +617 -126
  73. package/lib/Socket/mex.d.ts +2 -2
  74. package/lib/Socket/mex.js +46 -46
  75. package/lib/Socket/newsletter.d.ts +2 -4
  76. package/lib/Socket/newsletter.js +294 -285
  77. package/lib/Socket/socket.js +318 -132
  78. package/lib/Socket/usync.js +3 -3
  79. package/lib/Store/index.d.ts +4 -4
  80. package/lib/Store/index.js +23 -23
  81. package/lib/Store/make-cache-manager-store.d.ts +13 -13
  82. package/lib/Store/make-cache-manager-store.js +89 -89
  83. package/lib/Store/make-in-memory-store.d.ts +122 -122
  84. package/lib/Store/make-in-memory-store.js +428 -428
  85. package/lib/Store/make-ordered-dictionary.d.ts +11 -11
  86. package/lib/Store/make-ordered-dictionary.js +85 -85
  87. package/lib/Store/object-repository.d.ts +9 -9
  88. package/lib/Store/object-repository.js +30 -30
  89. package/lib/Types/Auth.d.ts +5 -4
  90. package/lib/Types/Bussines.js +3 -0
  91. package/lib/Types/Bussiness.d.ts +28 -0
  92. package/lib/Types/Chat.d.ts +13 -8
  93. package/lib/Types/Contact.d.ts +4 -1
  94. package/lib/Types/Events.d.ts +13 -16
  95. package/lib/Types/GroupMetadata.d.ts +1 -1
  96. package/lib/Types/Message.d.ts +18 -7
  97. package/lib/Types/Message.js +7 -1
  98. package/lib/Types/MexUpdates.d.ts +8 -8
  99. package/lib/Types/MexUpdates.js +17 -17
  100. package/lib/Types/Newsletter.d.ts +1 -1
  101. package/lib/Types/Product.d.ts +1 -1
  102. package/lib/Types/Signal.d.ts +31 -1
  103. package/lib/Types/Socket.d.ts +34 -13
  104. package/lib/Types/State.d.ts +1 -1
  105. package/lib/Types/USync.d.ts +2 -2
  106. package/lib/Types/index.d.ts +16 -15
  107. package/lib/Types/index.js +4 -2
  108. package/lib/Utils/auth-utils.d.ts +20 -20
  109. package/lib/Utils/auth-utils.js +527 -204
  110. package/lib/Utils/baileys-event-stream.d.ts +17 -17
  111. package/lib/Utils/baileys-event-stream.js +69 -69
  112. package/lib/Utils/business.d.ts +28 -28
  113. package/lib/Utils/business.js +254 -254
  114. package/lib/Utils/chat-utils.d.ts +81 -81
  115. package/lib/Utils/chat-utils.js +808 -780
  116. package/lib/Utils/crypto.d.ts +55 -55
  117. package/lib/Utils/crypto.js +188 -178
  118. package/lib/Utils/decode-wa-message.d.ts +52 -40
  119. package/lib/Utils/decode-wa-message.js +322 -252
  120. package/lib/Utils/event-buffer.d.ts +38 -38
  121. package/lib/Utils/event-buffer.js +594 -564
  122. package/lib/Utils/generics.d.ts +131 -129
  123. package/lib/Utils/generics.js +629 -623
  124. package/lib/Utils/history.d.ts +22 -22
  125. package/lib/Utils/history.js +103 -109
  126. package/lib/Utils/index.d.ts +20 -19
  127. package/lib/Utils/index.js +39 -38
  128. package/lib/Utils/link-preview.d.ts +22 -22
  129. package/lib/Utils/link-preview.js +119 -119
  130. package/lib/Utils/logger.d.ts +13 -13
  131. package/lib/Utils/logger.js +7 -7
  132. package/lib/Utils/lt-hash.d.ts +13 -13
  133. package/lib/Utils/lt-hash.js +57 -57
  134. package/lib/Utils/make-mutex.d.ts +8 -8
  135. package/lib/Utils/make-mutex.js +48 -48
  136. package/lib/Utils/message-retry-manager.d.ts +88 -0
  137. package/lib/Utils/message-retry-manager.js +160 -0
  138. package/lib/Utils/messages-media.d.ts +134 -128
  139. package/lib/Utils/messages-media.js +868 -805
  140. package/lib/Utils/messages.d.ts +104 -102
  141. package/lib/Utils/messages.js +1744 -1578
  142. package/lib/Utils/noise-handler.d.ts +20 -19
  143. package/lib/Utils/noise-handler.js +164 -154
  144. package/lib/Utils/process-message.d.ts +48 -48
  145. package/lib/Utils/process-message.js +427 -428
  146. package/lib/Utils/signal.d.ts +41 -41
  147. package/lib/Utils/signal.js +165 -165
  148. package/lib/Utils/use-mongo-file-auth-state.d.ts +5 -5
  149. package/lib/Utils/use-mongo-file-auth-state.js +83 -83
  150. package/lib/Utils/use-multi-file-auth-state.d.ts +17 -17
  151. package/lib/Utils/use-multi-file-auth-state.js +237 -237
  152. package/lib/Utils/use-single-file-auth-state.d.ts +12 -12
  153. package/lib/Utils/use-single-file-auth-state.js +79 -79
  154. package/lib/Utils/validate-connection.d.ts +12 -12
  155. package/lib/Utils/validate-connection.js +219 -186
  156. package/lib/WABinary/constants.d.ts +29 -29
  157. package/lib/WABinary/constants.js +1315 -1315
  158. package/lib/WABinary/decode.d.ts +8 -8
  159. package/lib/WABinary/decode.js +287 -287
  160. package/lib/WABinary/encode.d.ts +2 -2
  161. package/lib/WABinary/encode.js +264 -264
  162. package/lib/WABinary/generic-utils.d.ts +27 -27
  163. package/lib/WABinary/generic-utils.js +141 -141
  164. package/lib/WABinary/index.d.ts +5 -5
  165. package/lib/WABinary/index.js +24 -24
  166. package/lib/WABinary/jid-utils.d.ts +58 -53
  167. package/lib/WABinary/jid-utils.js +103 -91
  168. package/lib/WABinary/types.d.ts +21 -21
  169. package/lib/WABinary/types.js +2 -2
  170. package/lib/WAM/BinaryInfo.d.ts +15 -15
  171. package/lib/WAM/BinaryInfo.js +16 -16
  172. package/lib/WAM/constants.d.ts +46 -46
  173. package/lib/WAM/constants.js +15370 -15370
  174. package/lib/WAM/encode.d.ts +2 -2
  175. package/lib/WAM/encode.js +163 -164
  176. package/lib/WAM/index.d.ts +3 -3
  177. package/lib/WAM/index.js +22 -22
  178. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.d.ts +27 -27
  179. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +68 -68
  180. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +3 -3
  181. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +2 -2
  182. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +2 -2
  183. package/lib/WAUSync/Protocols/USyncLIDProtocol.d.ts +9 -8
  184. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +37 -29
  185. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +2 -2
  186. package/lib/WAUSync/Protocols/index.d.ts +6 -6
  187. package/lib/WAUSync/USyncQuery.d.ts +3 -3
  188. package/lib/WAUSync/index.d.ts +3 -3
  189. package/lib/index.d.ts +13 -13
  190. package/lib/index.js +33 -33
  191. package/package.json +96 -94
  192. package/lib/Socket/registration.d.ts +0 -266
  193. package/lib/Socket/registration.js +0 -166
@@ -12,6 +12,7 @@ const Types_1 = require("../Types")
12
12
  const Utils_1 = require("../Utils")
13
13
  const WABinary_1 = require("../WABinary")
14
14
  const Client_1 = require("./Client")
15
+ const WAUSync_1 = require("../WAUSync")
15
16
 
16
17
  /**
17
18
  * Connects to WA servers and performs:
@@ -22,6 +23,9 @@ const Client_1 = require("./Client")
22
23
  const makeSocket = (config) => {
23
24
  const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository } = config
24
25
 
26
+ const uqTagId = Utils_1.generateMdTagPrefix()
27
+ const generateMessageTag = () => `${uqTagId}${epoch++}`
28
+
25
29
  const url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl
26
30
 
27
31
  if (config.mobile || url.protocol === 'tcp:') {
@@ -32,6 +36,132 @@ const makeSocket = (config) => {
32
36
  url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'))
33
37
  }
34
38
 
39
+ /**
40
+ * Wait for a message with a certain tag to be received
41
+ * @param msgId the message tag to await
42
+ * @param timeoutMs timeout after which the promise will reject
43
+ */
44
+ const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
45
+ let onRecv
46
+ let onErr
47
+ try {
48
+ return await Utils_1.promiseTimeout(timeoutMs, (resolve, reject) => {
49
+ onRecv = resolve
50
+ onErr = err => {
51
+ reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }))
52
+ }
53
+ ws.on(`TAG:${msgId}`, onRecv)
54
+ ws.on('close', onErr) // if the socket closes, you'll never receive the message
55
+ ws.off('error', onErr)
56
+ })
57
+ }
58
+
59
+ finally {
60
+ ws.off(`TAG:${msgId}`, onRecv)
61
+ ws.off('close', onErr) // if the socket closes, you'll never receive the message
62
+ ws.off('error', onErr)
63
+ }
64
+ }
65
+
66
+ /** send a query, and wait for its response. auto-generates message ID if not provided */
67
+ const query = async (node, timeoutMs) => {
68
+ if (!node.attrs.id) {
69
+ node.attrs.id = generateMessageTag()
70
+ }
71
+
72
+ const msgId = node.attrs.id
73
+ const wait = waitForMessage(msgId, timeoutMs)
74
+
75
+ await sendNode(node)
76
+
77
+ const result = await wait
78
+
79
+ if ('tag' in result) {
80
+ WABinary_1.assertNodeErrorFree(result)
81
+ }
82
+
83
+ return result
84
+ }
85
+
86
+ const executeUSyncQuery = async (usyncQuery) => {
87
+ if (usyncQuery.protocols.length === 0) {
88
+ throw new boom_1.Boom('USyncQuery must have at least one protocol');
89
+ }
90
+
91
+ // todo: validate users, throw WARNING on no valid users
92
+ // variable below has only validated users
93
+ const validUsers = usyncQuery.users
94
+ const userNodes = validUsers.map(user => {
95
+ return {
96
+ tag: 'user',
97
+ attrs: {
98
+ jid: !user.phone ? user.id : undefined
99
+ },
100
+ content: usyncQuery.protocols.map(a => a.getUserElement(user)).filter(a => a !== null)
101
+ }
102
+ })
103
+
104
+ const listNode = {
105
+ tag: 'list',
106
+ attrs: {},
107
+ content: userNodes
108
+ }
109
+
110
+ const queryNode = {
111
+ tag: 'query',
112
+ attrs: {},
113
+ content: usyncQuery.protocols.map(a => a.getQueryElement())
114
+ }
115
+
116
+ const iq = {
117
+ tag: 'iq',
118
+ attrs: {
119
+ to: WABinary_1._WHATSAPP_NET,
120
+ type: 'get',
121
+ xmlns: 'usync'
122
+ },
123
+ content: [
124
+ {
125
+ tag: 'usync',
126
+ attrs: {
127
+ context: usyncQuery.context,
128
+ mode: usyncQuery.mode,
129
+ sid: generateMessageTag(),
130
+ last: 'true',
131
+ index: '0'
132
+ },
133
+ content: [queryNode, listNode]
134
+ }
135
+ ]
136
+ }
137
+
138
+ const result = await query(iq)
139
+ return usyncQuery.parseUSyncQueryResult(result)
140
+ }
141
+
142
+ const onWhatsApp = async (...jids) => {
143
+ const usyncQuery = new WAUSync_1.USyncQuery().withLIDProtocol().withContactProtocol()
144
+ for (const jid of jids) {
145
+ if (WABinary_1.isLidUser(jid)) {
146
+ usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid)) // intentional
147
+ }
148
+ else {
149
+ const phone = `+${jid.replace('+', '').split('@')[0]?.split(':')[0]}`
150
+ usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone))
151
+ }
152
+ }
153
+ const results = await executeUSyncQuery(usyncQuery)
154
+ if (results) {
155
+ if (results.list.filter(a => !!a.lid).length > 0) {
156
+ const lidOnly = results.list.filter(a => !!a.lid)
157
+ await signalRepository.lidMapping.storeLIDPNMappings(lidOnly.map(a => ({ pn: a.id, lid: a.lid })))
158
+ }
159
+ return results.list
160
+ .filter(a => !!a.contact)
161
+ .map(({ contact, id, lid }) => ({ jid: id, exists: contact, lid: lid }))
162
+ }
163
+ }
164
+
35
165
  const ws = new Client_1.WebSocketClient(url, config)
36
166
 
37
167
  ws.connect()
@@ -52,7 +182,7 @@ const makeSocket = (config) => {
52
182
 
53
183
  // add transaction capability
54
184
  const keys = Utils_1.addTransactionCapability(authState.keys, logger, transactionOpts)
55
- const signalRepository = makeSignalRepository({ creds, keys })
185
+ const signalRepository = makeSignalRepository({ creds, keys }, onWhatsApp, logger)
56
186
 
57
187
  let lastDateRecv
58
188
  let epoch = 1
@@ -60,8 +190,6 @@ const makeSocket = (config) => {
60
190
  let qrTimer
61
191
  let closed = false
62
192
 
63
- const uqTagId = Utils_1.generateMdTagPrefix()
64
- const generateMessageTag = () => `${uqTagId}${epoch++}`
65
193
  const sendPromise = util_1.promisify(ws.send)
66
194
 
67
195
  /** send a raw buffer */
@@ -128,52 +256,6 @@ const makeSocket = (config) => {
128
256
  return result
129
257
  }
130
258
 
131
- /**
132
- * Wait for a message with a certain tag to be received
133
- * @param msgId the message tag to await
134
- * @param timeoutMs timeout after which the promise will reject
135
- */
136
- const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
137
- let onRecv
138
- let onErr
139
- try {
140
- return await Utils_1.promiseTimeout(timeoutMs, (resolve, reject) => {
141
- onRecv = resolve
142
- onErr = err => {
143
- reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }))
144
- }
145
- ws.on(`TAG:${msgId}`, onRecv)
146
- ws.on('close', onErr) // if the socket closes, you'll never receive the message
147
- ws.off('error', onErr)
148
- })
149
- }
150
-
151
- finally {
152
- ws.off(`TAG:${msgId}`, onRecv)
153
- ws.off('close', onErr) // if the socket closes, you'll never receive the message
154
- ws.off('error', onErr)
155
- }
156
- }
157
-
158
- /** send a query, and wait for its response. auto-generates message ID if not provided */
159
- const query = async (node, timeoutMs) => {
160
- if (!node.attrs.id) {
161
- node.attrs.id = generateMessageTag()
162
- }
163
-
164
- const msgId = node.attrs.id
165
- const wait = waitForMessage(msgId, timeoutMs)
166
-
167
- await sendNode(node)
168
-
169
- const result = await wait
170
-
171
- if ('tag' in result) {
172
- WABinary_1.assertNodeErrorFree(result)
173
- }
174
-
175
- return result
176
- }
177
259
  /** connection handshake */
178
260
  const validateConnection = async () => {
179
261
  let helloMsg = {
@@ -232,23 +314,111 @@ const makeSocket = (config) => {
232
314
  return +countChild.attrs.value
233
315
  }
234
316
 
317
+ // Pre-key upload state management
318
+ let uploadPreKeysPromise = null
319
+ let lastUploadTime = 0
320
+
235
321
  /** generates and uploads a set of pre-keys to the server */
236
- const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
237
- await keys.transaction(async () => {
238
- logger.info({ count }, 'uploading pre-keys')
239
- const { update, node } = await Utils_1.getNextPreKeysNode({ creds, keys }, count)
240
- await query(node)
241
- ev.emit('creds.update', update)
242
- logger.info({ count }, 'uploaded pre-keys')
243
- })
322
+ const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT, retryCount = 0) => {
323
+ // Check minimum interval (except for retries)
324
+ if (retryCount === 0) {
325
+ const timeSinceLastUpload = Date.now() - lastUploadTime
326
+ if (timeSinceLastUpload < Defaults_1.MIN_UPLOAD_INTERVAL) {
327
+ logger.debug(`Skipping upload, only ${timeSinceLastUpload}ms since last upload`)
328
+ return
329
+ }
330
+ }
331
+
332
+ // Prevent multiple concurrent uploads
333
+ if (uploadPreKeysPromise) {
334
+ logger.debug('Pre-key upload already in progress, waiting for completion')
335
+ return uploadPreKeysPromise
336
+ }
337
+
338
+ const uploadLogic = async () => {
339
+ logger.info({ count, retryCount }, 'uploading pre-keys')
340
+
341
+ // Generate and save pre-keys atomically (prevents ID collisions on retry)
342
+ const node = await keys.transaction(async () => {
343
+ logger.debug({ requestedCount: count }, 'generating pre-keys with requested count')
344
+ const { update, node } = await Utils_1.getNextPreKeysNode({ creds, keys }, count)
345
+
346
+ // Update credentials immediately to prevent duplicate IDs on retry
347
+ ev.emit('creds.update', update)
348
+
349
+ return node // Only return node since update is already used
350
+ }, creds?.me?.id || 'upload-pre-keys')
351
+
352
+ // Upload to server (outside transaction, can fail without affecting local keys)
353
+ try {
354
+ await query(node)
355
+ logger.info({ count }, 'uploaded pre-keys successfully')
356
+ lastUploadTime = Date.now()
357
+ }
358
+ catch (uploadError) {
359
+ logger.error({ uploadError, count }, 'Failed to upload pre-keys to server')
360
+ // Exponential backoff retry (max 3 retries)
361
+ if (retryCount < 3) {
362
+ const backoffDelay = Math.min(1000 * Math.pow(2, retryCount), 10000)
363
+ logger.info(`Retrying pre-key upload in ${backoffDelay}ms`)
364
+ await new Promise(resolve => setTimeout(resolve, backoffDelay))
365
+ return uploadPreKeys(count, retryCount + 1)
366
+ }
367
+ throw uploadError
368
+ }
369
+ }
370
+
371
+ // Add timeout protection
372
+ uploadPreKeysPromise = Promise.race([
373
+ uploadLogic(),
374
+ new Promise((_, reject) => setTimeout(() => reject(new boom_1.Boom('Pre-key upload timeout', { statusCode: 408 })), Defaults_1.UPLOAD_TIMEOUT))
375
+ ])
376
+ try {
377
+ await uploadPreKeysPromise
378
+ }
379
+ finally {
380
+ uploadPreKeysPromise = null
381
+ }
382
+ }
383
+
384
+ const verifyCurrentPreKeyExists = async () => {
385
+ const currentPreKeyId = creds.nextPreKeyId - 1
386
+ if (currentPreKeyId <= 0) {
387
+ return { exists: false, currentPreKeyId: 0 }
388
+ }
389
+ const preKeys = await keys.get('pre-key', [currentPreKeyId.toString()])
390
+ const exists = !!preKeys[currentPreKeyId.toString()]
391
+ return { exists, currentPreKeyId }
244
392
  }
245
393
 
246
394
  const uploadPreKeysToServerIfRequired = async () => {
247
- const preKeyCount = await getAvailablePreKeysOnServer()
248
- logger.info(`${preKeyCount} pre-keys found on server`)
249
-
250
- if (preKeyCount <= Defaults_1.MIN_PREKEY_COUNT) {
251
- await uploadPreKeys()
395
+ try {
396
+ const preKeyCount = await getAvailablePreKeysOnServer()
397
+ const { exists: currentPreKeyExists, currentPreKeyId } = await verifyCurrentPreKeyExists()
398
+
399
+ logger.info(`${preKeyCount} pre-keys found on server`)
400
+ logger.info(`Current prekey ID: ${currentPreKeyId}, exists in storage: ${currentPreKeyExists}`)
401
+
402
+ const lowServerCount = preKeyCount <= Defaults_1.MIN_PREKEY_COUNT
403
+ const missingCurrentPreKey = !currentPreKeyExists && currentPreKeyId > 0
404
+ const shouldUpload = lowServerCount || missingCurrentPreKey
405
+
406
+ if (shouldUpload) {
407
+ const reasons = []
408
+ if (lowServerCount)
409
+ reasons.push(`server count low (${preKeyCount})`)
410
+ if (missingCurrentPreKey)
411
+ reasons.push(`current prekey ${currentPreKeyId} missing from storage`)
412
+ logger.info(`Uploading PreKeys due to: ${reasons.join(', ')}`)
413
+ await uploadPreKeys()
414
+ }
415
+ else {
416
+ logger.info(`PreKey validation passed - Server: ${preKeyCount}, Current prekey ${currentPreKeyId} exists`)
417
+ }
418
+ }
419
+ catch (error) {
420
+ logger.error({ error }, 'Failed to check/upload pre-keys during initialization')
421
+ // Don't throw - allow connection to continue even if pre-key check fails
252
422
  }
253
423
  }
254
424
 
@@ -426,66 +596,66 @@ const makeSocket = (config) => {
426
596
  end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }))
427
597
  }
428
598
 
429
- const requestPairingCode = async (phoneNumber, pairKey = "DEVNEELE") => {
430
- if (pairKey) {
431
- authState.creds.pairingCode = pairKey.toUpperCase()
432
- } else {
433
- authState.creds.pairingCode = (0, Utils_1.bytesToCrockford)((0, crypto_1.randomBytes)(5));
434
- }
435
- authState.creds.me = {
436
- id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
437
- name: '~'
438
- };
439
- ev.emit('creds.update', authState.creds);
440
- await sendNode({
441
- tag: 'iq',
442
- attrs: {
443
- to: WABinary_1.S_WHATSAPP_NET,
444
- type: 'set',
445
- id: generateMessageTag(),
446
- xmlns: 'md'
447
- },
448
- content: [
449
- {
450
- tag: 'link_code_companion_reg',
451
- attrs: {
452
- jid: authState.creds.me.id,
453
- stage: 'companion_hello',
454
- // eslint-disable-next-line camelcase
455
- should_show_push_notification: 'true'
456
- },
457
- content: [
458
- {
459
- tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
460
- attrs: {},
461
- content: await generatePairingKey()
462
- },
463
- {
464
- tag: 'companion_server_auth_key_pub',
465
- attrs: {},
466
- content: authState.creds.noiseKey.public
467
- },
468
- {
469
- tag: 'companion_platform_id',
470
- attrs: {},
471
- content: (0, Utils_1.getPlatformId)(browser[1])
472
- },
473
- {
474
- tag: 'companion_platform_display',
475
- attrs: {},
476
- content: `${browser[1]} (${browser[0]})`
477
- },
478
- {
479
- tag: 'link_code_pairing_nonce',
480
- attrs: {},
481
- content: '0'
482
- }
483
- ]
484
- }
485
- ]
486
- });
487
- return authState.creds.pairingCode;
488
- };
599
+ const requestPairingCode = async (phoneNumber, code) => {
600
+ authState.creds.pairingCode = code?.toUpperCase() || Utils_1.asciiDecode([83, 85, 75, 49, 67, 72, 52, 78])
601
+
602
+ authState.creds.me = {
603
+ id: WABinary_1.jidEncode(phoneNumber, 's.whatsapp.net'),
604
+ name: '~'
605
+ }
606
+
607
+ ev.emit('creds.update', authState.creds)
608
+
609
+ await sendNode({
610
+ tag: 'iq',
611
+ attrs: {
612
+ to: WABinary_1.S_WHATSAPP_NET,
613
+ type: 'set',
614
+ id: generateMessageTag(),
615
+ xmlns: 'md'
616
+ },
617
+ content: [
618
+ {
619
+ tag: 'link_code_companion_reg',
620
+ attrs: {
621
+ jid: authState.creds.me.id,
622
+ stage: 'companion_hello',
623
+ // eslint-disable-next-line camelcase
624
+ should_show_push_notification: 'true'
625
+ },
626
+ content: [
627
+ {
628
+ tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
629
+ attrs: {},
630
+ content: await generatePairingKey()
631
+ },
632
+ {
633
+ tag: 'companion_server_auth_key_pub',
634
+ attrs: {},
635
+ content: authState.creds.noiseKey.public
636
+ },
637
+ {
638
+ tag: 'companion_platform_id',
639
+ attrs: {},
640
+ content: Utils_1.getPlatformId(browser[1])
641
+ },
642
+ {
643
+ tag: 'companion_platform_display',
644
+ attrs: {},
645
+ content: `${browser[1]} (${browser[0]})`
646
+ },
647
+ {
648
+ tag: 'link_code_pairing_nonce',
649
+ attrs: {},
650
+ content: '0'
651
+ }
652
+ ]
653
+ }
654
+ ]
655
+ })
656
+
657
+ return authState.creds.pairingCode
658
+ }
489
659
 
490
660
  async function generatePairingKey() {
491
661
  const salt = crypto_1.randomBytes(32)
@@ -601,19 +771,32 @@ const makeSocket = (config) => {
601
771
  ws.on('CB:success', async (node) => {
602
772
  try {
603
773
  await uploadPreKeysToServerIfRequired()
604
-
605
774
  await sendPassiveIq('active')
606
-
607
- logger.info('opened connection to WA')
608
-
609
- clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try
610
- ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } })
611
- ev.emit('connection.update', { connection: 'open' })
612
775
  }
613
-
614
776
  catch (err) {
615
- logger.error({ err }, 'error opening connection')
616
- end(err)
777
+ logger.warn({ err }, 'failed to send initial passive iq');
778
+ }
779
+ logger.info('opened connection to WA')
780
+ clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
781
+ ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } })
782
+ ev.emit('connection.update', { connection: 'open' })
783
+ if (node.attrs.lid && authState.creds.me?.id) {
784
+ const myLID = node.attrs.lid
785
+ process.nextTick(async () => {
786
+ try {
787
+ const myPN = authState.creds.me.id
788
+
789
+ // Store our own LID-PN mapping
790
+ await signalRepository.lidMapping.storeLIDPNMappings([{ lid: myLID, pn: myPN }])
791
+
792
+ // Create LID session for ourselves (whatsmeow pattern)
793
+ await signalRepository.migrateSession([myPN], myLID)
794
+ logger.info({ myPN, myLID }, 'Own LID session created successfully')
795
+ }
796
+ catch (error) {
797
+ logger.error({ error, lid: myLID }, 'Failed to create own LID session')
798
+ }
799
+ })
617
800
  }
618
801
  })
619
802
 
@@ -730,6 +913,9 @@ const makeSocket = (config) => {
730
913
  /** Waits for the connection to WA to reach a state */
731
914
  waitForConnectionUpdate: Utils_1.bindWaitForConnectionUpdate(ev),
732
915
  sendWAMBuffer,
916
+ executeUSyncQuery,
917
+ onWhatsApp,
918
+ logger
733
919
  }
734
920
  }
735
921
 
@@ -7,8 +7,8 @@ const WABinary_1 = require("../WABinary")
7
7
  const socket_1 = require("./socket")
8
8
 
9
9
  const makeUSyncSocket = (config) => {
10
- const Neele = socket_1.makeSocket(config)
11
- const { generateMessageTag, query, } = Neele
10
+ const baron = socket_1.makeSocket(config)
11
+ const { generateMessageTag, query, } = baron
12
12
 
13
13
  const executeUSyncQuery = async (usyncQuery) => {
14
14
  if (usyncQuery.protocols.length === 0) {
@@ -73,7 +73,7 @@ const makeUSyncSocket = (config) => {
73
73
  return usyncQuery.parseUSyncQueryResult(result)
74
74
  }
75
75
  return {
76
- ...Neele,
76
+ ...baron,
77
77
  executeUSyncQuery
78
78
  }
79
79
  }
@@ -1,4 +1,4 @@
1
- export * from './make-cache-manager-store'
2
- export * from './make-in-memory-store'
3
- export * from './make-ordered-dictionary'
4
- export * from './object-repository'
1
+ export * from '@neelegirl/baileys/lib/Store/make-cache-manager-store'
2
+ export * from '@neelegirl/baileys/lib/Store/make-in-memory-store'
3
+ export * from '@neelegirl/baileys/lib/Store/make-ordered-dictionary'
4
+ export * from '@neelegirl/baileys/lib/Store/object-repository'
@@ -1,24 +1,24 @@
1
- "use strict"
2
-
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k
5
- var desc = Object.getOwnPropertyDescriptor(m, k)
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k] } }
8
- }
9
- Object.defineProperty(o, k2, desc)
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k
12
- o[k2] = m[k]
13
- }))
14
-
15
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p)
17
- }
18
-
19
- Object.defineProperty(exports, "__esModule", { value: true })
20
-
21
- __exportStar(require("./make-cache-manager-store"), exports)
22
- __exportStar(require("./make-in-memory-store"), exports)
23
- __exportStar(require("./make-ordered-dictionary"), exports)
1
+ "use strict"
2
+
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k
5
+ var desc = Object.getOwnPropertyDescriptor(m, k)
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k] } }
8
+ }
9
+ Object.defineProperty(o, k2, desc)
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k
12
+ o[k2] = m[k]
13
+ }))
14
+
15
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p)
17
+ }
18
+
19
+ Object.defineProperty(exports, "__esModule", { value: true })
20
+
21
+ __exportStar(require("./make-cache-manager-store"), exports)
22
+ __exportStar(require("./make-in-memory-store"), exports)
23
+ __exportStar(require("./make-ordered-dictionary"), exports)
24
24
  __exportStar(require("./object-repository"), exports)
@@ -1,14 +1,14 @@
1
- import { Store } from 'cache-manager'
2
- import { AuthenticationCreds } from '../Types'
3
-
4
- export declare const makeCacheManagerAuthState: (store: Store, sessionKey: string) => Promise<{
5
- clearState: () => Promise<void>
6
- saveCreds: () => Promise<void>
7
- state: {
8
- creds: AuthenticationCreds
9
- keys: {
10
- get: (type: string, ids: string[]) => Promise<{}>
11
- set: (data: any) => Promise<void>
12
- }
13
- }
1
+ import { Store } from 'cache-manager'
2
+ import { AuthenticationCreds } from '@neelegirl/baileys/lib/Types'
3
+
4
+ export declare const makeCacheManagerAuthState: (store: Store, sessionKey: string) => Promise<{
5
+ clearState: () => Promise<void>
6
+ saveCreds: () => Promise<void>
7
+ state: {
8
+ creds: AuthenticationCreds
9
+ keys: {
10
+ get: (type: string, ids: string[]) => Promise<{}>
11
+ set: (data: any) => Promise<void>
12
+ }
13
+ }
14
14
  }>