kage-baileys 3.0.6 → 3.2.4

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 (217) hide show
  1. package/Example/connection.cjs +4 -0
  2. package/README.MD +4726 -48
  3. package/README.md +5941 -0
  4. package/WAProto/WAProto.proto +3395 -415
  5. package/WAProto/compat.cjs +12 -0
  6. package/WAProto/index.d.ts +47104 -19888
  7. package/WAProto/index.js +131979 -57361
  8. package/lib/Addon/http-error.js +43 -0
  9. package/lib/Addon/index.js +32 -0
  10. package/lib/Addon/keyed-db.js +250 -0
  11. package/lib/Addon/link-preview.js +82 -0
  12. package/lib/Defaults/baileys-version.json +3 -0
  13. package/lib/Defaults/connection.js +110 -0
  14. package/lib/Defaults/constants.js +156 -0
  15. package/lib/Defaults/history.js +46 -0
  16. package/lib/Defaults/index.js +230 -0
  17. package/lib/Defaults/media.js +104 -0
  18. package/lib/Defaults/phonenumber-mcc.json +223 -0
  19. package/lib/Defaults/prefix.js +44 -0
  20. package/lib/Extensions/business-advanced.js +382 -0
  21. package/lib/Extensions/business.js +159 -0
  22. package/lib/Extensions/chats-advanced.js +1106 -0
  23. package/lib/Extensions/chats.js +349 -0
  24. package/lib/Extensions/communities-advanced.js +430 -0
  25. package/lib/Extensions/community.js +94 -0
  26. package/lib/Extensions/groups-advanced.js +343 -0
  27. package/lib/Extensions/index.js +30 -0
  28. package/lib/Extensions/messages-recv-advanced.js +1690 -0
  29. package/lib/Extensions/messages-send-advanced.js +622 -0
  30. package/lib/Extensions/messages-send.js +1380 -0
  31. package/lib/Extensions/newsletter-advanced.js +228 -0
  32. package/lib/Extensions/newsletter.js +72 -0
  33. package/lib/Extensions/socket.js +389 -0
  34. package/lib/Modded/message_builder.js +2084 -4
  35. package/lib/Signal/Group/ciphertext-message.js +54 -0
  36. package/lib/Signal/Group/group-session-builder.js +124 -0
  37. package/lib/Signal/Group/group_cipher.js +216 -0
  38. package/lib/Signal/Group/index.js +124 -0
  39. package/lib/Signal/Group/keyhelper.js +108 -0
  40. package/lib/Signal/Group/sender-chain-key.js +83 -0
  41. package/lib/Signal/Group/sender-key-distribution-message.js +157 -0
  42. package/lib/Signal/Group/sender-key-message.js +166 -0
  43. package/lib/Signal/Group/sender-key-name.js +130 -0
  44. package/lib/Signal/Group/sender-key-record.js +113 -0
  45. package/lib/Signal/Group/sender-key-state.js +208 -0
  46. package/lib/Signal/Group/sender-message-key.js +82 -0
  47. package/lib/Signal/libsignal.js +935 -0
  48. package/lib/Signal/lid-mapping.js +545 -1
  49. package/lib/Socket/Client/index.js +60 -0
  50. package/lib/Socket/Client/types.js +51 -0
  51. package/lib/Socket/Client/websocket.js +152 -0
  52. package/lib/Socket/business.js +831 -0
  53. package/lib/Socket/chats.js +2535 -49
  54. package/lib/Socket/communities.js +450 -1
  55. package/lib/Socket/community.js +1022 -0
  56. package/lib/Socket/dugong.js +1 -1
  57. package/lib/Socket/groups.js +747 -0
  58. package/lib/Socket/index.js +60 -2
  59. package/lib/Socket/messages-recv.js +3450 -5
  60. package/lib/Socket/messages-send.js +3123 -0
  61. package/lib/Socket/mex.js +126 -1
  62. package/lib/Socket/newsletter.js +465 -0
  63. package/lib/Socket/socket.js +2217 -1
  64. package/lib/Store/index.js +79 -0
  65. package/lib/Store/make-cache-manager-store.js +186 -0
  66. package/lib/Store/make-in-memory-store.js +878 -0
  67. package/lib/Store/make-ordered-dictionary.js +187 -0
  68. package/lib/Store/object-repository.js +78 -0
  69. package/lib/Types/Auth.js +25 -0
  70. package/lib/Types/Bussines.js +25 -1
  71. package/lib/Types/Call.js +25 -0
  72. package/lib/Types/Chat.js +39 -0
  73. package/lib/Types/Contact.js +25 -0
  74. package/lib/Types/Events.js +25 -0
  75. package/lib/Types/GroupMetadata.js +25 -0
  76. package/lib/Types/Label.js +76 -0
  77. package/lib/Types/LabelAssociation.js +40 -0
  78. package/lib/Types/Message.js +57 -0
  79. package/lib/Types/Mex.js +56 -1
  80. package/lib/Types/MexUpdates.js +46 -0
  81. package/lib/Types/Newsletter.js +56 -0
  82. package/lib/Types/Product.js +25 -0
  83. package/lib/Types/RichType.js +23 -0
  84. package/lib/Types/Signal.js +25 -0
  85. package/lib/Types/Socket.js +25 -0
  86. package/lib/Types/State.js +92 -0
  87. package/lib/Types/USync.js +25 -0
  88. package/lib/Types/index.js +133 -0
  89. package/lib/Utils/auth-utils.js +703 -0
  90. package/lib/Utils/automation-tools.js +51 -16
  91. package/lib/Utils/baileys-event-stream.js +146 -0
  92. package/lib/Utils/browser-utils.js +95 -0
  93. package/lib/Utils/business.js +525 -0
  94. package/lib/Utils/chat-utils.js +1861 -0
  95. package/lib/Utils/companion-reg-client-utils.js +55 -1
  96. package/lib/Utils/crypto.js +355 -0
  97. package/lib/Utils/decode-wa-message.js +709 -0
  98. package/lib/Utils/event-buffer.js +1323 -8
  99. package/lib/Utils/generics.js +945 -1
  100. package/lib/Utils/history.js +266 -0
  101. package/lib/Utils/identity-change-handler.js +62 -1
  102. package/lib/Utils/index.js +114 -0
  103. package/lib/Utils/link-preview.js +179 -0
  104. package/lib/Utils/logger.js +42 -0
  105. package/lib/Utils/lt-hash.js +73 -0
  106. package/lib/Utils/make-mutex.js +104 -0
  107. package/lib/Utils/message-inspector.js +110 -0
  108. package/lib/Utils/message-retry-manager.js +507 -2
  109. package/lib/Utils/messages-media.js +1931 -1
  110. package/lib/Utils/messages.js +3748 -0
  111. package/lib/Utils/noise-handler.js +423 -0
  112. package/lib/Utils/offline-node-processor.js +53 -1
  113. package/lib/Utils/pre-key-manager.js +255 -1
  114. package/lib/Utils/process-message.js +1592 -0
  115. package/lib/Utils/reporting-utils.js +272 -1
  116. package/lib/Utils/rich-message-utils.js +377 -0
  117. package/lib/Utils/rich-messages.js +1 -1
  118. package/lib/Utils/signal.js +437 -0
  119. package/lib/Utils/stanza-ack.js +51 -1
  120. package/lib/Utils/status-refresh.js +37 -0
  121. package/lib/Utils/status-tools.js +4 -2
  122. package/lib/Utils/sync-action-utils.js +63 -1
  123. package/lib/Utils/tc-token-utils.js +185 -1
  124. package/lib/Utils/terminal-banner.js +31 -0
  125. package/lib/Utils/use-multi-file-auth-state.js +271 -0
  126. package/lib/Utils/use-single-file-auth-state.js +108 -0
  127. package/lib/Utils/use-sqlite-auth-state.js +142 -0
  128. package/lib/Utils/validate-connection.js +497 -1
  129. package/lib/Utils/view-once-compat.js +13 -5
  130. package/lib/VoIP/audio-feeder.js +150 -0
  131. package/lib/VoIP/index.js +289 -0
  132. package/lib/VoIP/relay-transport.js +608 -0
  133. package/lib/VoIP/signaling.js +583 -0
  134. package/lib/VoIP/types.js +30 -0
  135. package/lib/VoIP/wasm-engine.js +1261 -2
  136. package/lib/VoIP/worker-bootstrap.js +1090 -2
  137. package/lib/WABinary/constants.js +2805 -0
  138. package/lib/WABinary/decode.js +649 -2
  139. package/lib/WABinary/encode.js +564 -2
  140. package/lib/WABinary/generic-utils.js +401 -0
  141. package/lib/WABinary/index.js +82 -0
  142. package/lib/WABinary/jid-utils.js +290 -0
  143. package/lib/WABinary/types.js +25 -0
  144. package/lib/WAM/BinaryInfo.js +50 -0
  145. package/lib/WAM/constants.js +45747 -0
  146. package/lib/WAM/encode.js +393 -0
  147. package/lib/WAM/index.js +78 -0
  148. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +135 -0
  149. package/lib/WAUSync/Protocols/USyncContactProtocol.js +110 -0
  150. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +142 -0
  151. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +85 -0
  152. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +69 -0
  153. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +107 -0
  154. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +38 -1
  155. package/lib/WAUSync/Protocols/index.js +83 -0
  156. package/lib/WAUSync/USyncQuery.js +241 -2
  157. package/lib/WAUSync/USyncUser.js +86 -0
  158. package/lib/WAUSync/index.js +78 -0
  159. package/lib/assets/wasm/loader.js +1875 -1
  160. package/lib/assets/wasm/worker-modules.js +11047 -1
  161. package/lib/index.d.ts +126 -0
  162. package/lib/index.js +53 -21
  163. package/lib/index.mjs +437 -0
  164. package/licenses/upstream-MIT.txt +22 -0
  165. package/maintenance/api-coverage.json +1642 -0
  166. package/maintenance/archivos-sha256.json +207 -0
  167. package/maintenance/consumer-validation.log +3 -0
  168. package/maintenance/dependency-audit.json +4 -4
  169. package/maintenance/extension-inventory.json +57 -0
  170. package/maintenance/protocol-update.json +1101 -0
  171. package/maintenance/protocol-wire-audit.json +4 -0
  172. package/maintenance/reference-socket-surface.json +209 -0
  173. package/maintenance/resumen-validacion.json +50 -0
  174. package/maintenance/validation.log +2725 -0
  175. package/maintenance/verification.json +566 -0
  176. package/package.json +107 -9
  177. package/scripts/check-imports.cjs +10 -0
  178. package/scripts/check-package.cjs +40 -0
  179. package/scripts/check-syntax.cjs +1 -1
  180. package/scripts/generate-protobuf.cjs +6 -1
  181. package/scripts/generate-public-types.cjs +9 -0
  182. package/scripts/kage-base64-fix.cjs +45 -0
  183. package/scripts/maintenance.cjs +10 -0
  184. package/test/advanced.test.cjs +24 -0
  185. package/test/base64-fix.test.cjs +49 -0
  186. package/test/maintenance.test.cjs +1 -1
  187. package/test/npm-publication.test.cjs +141 -0
  188. package/test/recepcion-reparada.test.cjs +98 -0
  189. package/test/resilience-binary.test.cjs +69 -0
  190. package/test/resilience-transport.test.cjs +34 -0
  191. package/test/types.test.ts +5 -0
  192. package/test/upgrade.test.cjs +104 -0
  193. package/tsconfig.json +20 -0
  194. package/WAProto/p.html +0 -1
  195. package/lib/KageExtra/Modded/message_builder.js +0 -2330
  196. package/lib/KageExtra/VoIP/audio-feeder.js +0 -136
  197. package/lib/KageExtra/VoIP/index.js +0 -282
  198. package/lib/KageExtra/VoIP/relay-transport.js +0 -559
  199. package/lib/KageExtra/VoIP/signaling.js +0 -603
  200. package/lib/KageExtra/VoIP/types.js +0 -17
  201. package/lib/KageExtra/VoIP/wasm-engine.js +0 -1214
  202. package/lib/KageExtra/VoIP/worker-bootstrap.js +0 -1042
  203. package/lib/KageExtra/assets/wasm/loader.js +0 -5
  204. package/lib/KageExtra/assets/wasm/whatsapp.wasm +0 -0
  205. package/lib/KageExtra/assets/wasm/worker-modules.js +0 -273
  206. package/lib/KageExtra/index.js +0 -3
  207. package/lib/KageExtra/package.json +0 -1
  208. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -53
  209. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -24
  210. package/maintenance/revision-full-check.txt +0 -1097
  211. package/maintenance/revision-library-tests.tap +0 -1088
  212. package/maintenance/revision-protobuf.txt +0 -5
  213. package/maintenance/revision-syntax.txt +0 -5
  214. package/maintenance/schema-coverage.json +0 -23
  215. package/maintenance/schema-merge.json +0 -30
  216. package/maintenance/validation-node20.txt +0 -191
  217. package/maintenance/validation-node22.txt +0 -237
@@ -197,3 +197,706 @@ const initAuthCreds = () => {
197
197
  };
198
198
  };
199
199
  exports.initAuthCreds = initAuthCreds;
200
+
201
+ // Kage: compatibilidad de API.
202
+ const __kageModule57 = (() => {
203
+ const module = { exports: {} }; const exports = module.exports;
204
+ "use strict"
205
+
206
+ Object.defineProperty(exports, "__esModule", { value: true })
207
+
208
+ const { randomBytes } = require("crypto")
209
+ const { default: PQueue } = require("p-queue")
210
+ const { default: NodeCache } = require("@cacheable/node-cache")
211
+ const { DEFAULT_CACHE_TTLS } = require("../Defaults/constants")
212
+ const { AsyncLocalStorage } = require("async_hooks")
213
+ const { LRUCache } = require("lru-cache")
214
+ const { Mutex }= require("async-mutex")
215
+ const {
216
+ Curve,
217
+ signedKeyPair
218
+ } = require("./crypto")
219
+ const {
220
+ delay,
221
+ generateRegistrationId
222
+ } = require("./generics")
223
+ const { PreKeyManager } = require("./pre-key-manager")
224
+
225
+ /**
226
+ * Adds caching capability to a SignalKeyStore
227
+ * @param store the store to add caching to
228
+ * @param logger to log trace events
229
+ * @param _cache cache store to use
230
+ */
231
+ function makeCacheableSignalKeyStore(store, logger, _cache) {
232
+ const cache = _cache || new NodeCache({
233
+ stdTTL: DEFAULT_CACHE_TTLS.SIGNAL_STORE,
234
+ useClones: false,
235
+ deleteOnExpire: true
236
+ })
237
+
238
+ // Mutex for protecting cache operations
239
+ const cacheMutex = new Mutex()
240
+
241
+ function getUniqueId(type, id) {
242
+ return `${type}.${id}`
243
+ }
244
+ return {
245
+ async get(type, ids) {
246
+ return cacheMutex.runExclusive(async () => {
247
+ const data = {}
248
+ const idsToFetch = []
249
+ for (const id of ids) {
250
+ const item = cache.get(getUniqueId(type, id))
251
+ if (typeof item !== 'undefined') {
252
+ data[id] = item
253
+ }
254
+ else {
255
+ idsToFetch.push(id)
256
+ }
257
+ }
258
+ if (idsToFetch.length) {
259
+ logger?.trace({ items: idsToFetch.length }, 'loading from store')
260
+ const fetched = await store.get(type, idsToFetch)
261
+ for (const id of idsToFetch) {
262
+ const item = fetched[id]
263
+ if (item) {
264
+ data[id] = item
265
+ cache.set(getUniqueId(type, id), item)
266
+ }
267
+ }
268
+ }
269
+ return data
270
+ })
271
+ },
272
+ async set(data) {
273
+ return cacheMutex.runExclusive(async () => {
274
+ let keys = 0
275
+ for (const type in data) {
276
+ for (const id in data[type]) {
277
+ await cache.set(getUniqueId(type, id), data[type][id])
278
+ keys += 1
279
+ }
280
+ }
281
+ logger?.trace({ keys }, 'updated cache')
282
+ await store.set(data)
283
+ })
284
+ },
285
+ async clear() {
286
+ await cache.flushAll()
287
+ await store.clear?.call(store)
288
+ }
289
+ }
290
+ }
291
+
292
+ /**
293
+ * Adds DB-like transaction capability to the SignalKeyStore
294
+ * Uses AsyncLocalStorage for automatic context management
295
+ * @param state the key store to apply this capability to
296
+ * @param logger logger to log events
297
+ * @returns SignalKeyStore with transaction capability
298
+ */
299
+ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetweenTriesMs }) => {
300
+ const txStorage = new AsyncLocalStorage()
301
+
302
+ // Queues for concurrency control (keyed by signal data type - bounded set)
303
+ const keyQueues = new Map()
304
+
305
+ // Transaction mutexes with reference counting for cleanup
306
+ const txMutexes = new Map()
307
+
308
+ const txMutexRefCounts = new Map()
309
+
310
+ // Pre-key manager for specialized operations
311
+ const preKeyManager = new PreKeyManager(state, logger)
312
+
313
+ /**
314
+ * Get or create a queue for a specific key type
315
+ */
316
+ function getQueue(key) {
317
+ if (!keyQueues.has(key)) {
318
+ keyQueues.set(key, new PQueue({ concurrency: 1 }))
319
+ }
320
+
321
+ return keyQueues.get(key)
322
+ }
323
+
324
+ /**
325
+ * Get or create a transaction mutex
326
+ */
327
+ function getTxMutex(key) {
328
+ if (!txMutexes.has(key)) {
329
+ txMutexes.set(key, new Mutex())
330
+ txMutexRefCounts.set(key, 0)
331
+ }
332
+
333
+ return txMutexes.get(key)
334
+ }
335
+
336
+ /**
337
+ * Acquire a reference to a transaction mutex
338
+ */
339
+ function acquireTxMutexRef(key) {
340
+ const count = txMutexRefCounts.get(key) ?? 0
341
+ txMutexRefCounts.set(key, count + 1)
342
+ }
343
+
344
+ /**
345
+ * Release a reference to a transaction mutex and cleanup if no longer needed
346
+ */
347
+ function releaseTxMutexRef(key) {
348
+ const count = (txMutexRefCounts.get(key) ?? 1) - 1
349
+
350
+ txMutexRefCounts.set(key, count)
351
+
352
+ // Cleanup if no more references and mutex is not locked
353
+ if (count <= 0) {
354
+ const mutex = txMutexes.get(key)
355
+
356
+ if (mutex && !mutex.isLocked()) {
357
+ txMutexes.delete(key)
358
+ txMutexRefCounts.delete(key)
359
+ }
360
+ }
361
+ }
362
+
363
+ /**
364
+ * Check if currently in a transaction
365
+ */
366
+ function isInTransaction() {
367
+ return !!txStorage.getStore()
368
+ }
369
+
370
+ /**
371
+ * Commit transaction with retries
372
+ */
373
+ async function commitWithRetry(mutations) {
374
+ if (Object.keys(mutations).length === 0) {
375
+ logger.trace('no mutations in transaction')
376
+ return
377
+ }
378
+
379
+ logger.trace('committing transaction')
380
+
381
+ for (let attempt = 0; attempt < maxCommitRetries; attempt++) {
382
+ try {
383
+ await state.set(mutations)
384
+ logger.trace({ mutationCount: Object.keys(mutations).length }, 'committed transaction')
385
+ return
386
+ }
387
+
388
+ catch (error) {
389
+ const retriesLeft = maxCommitRetries - attempt - 1
390
+
391
+ logger.warn(`failed to commit mutations, retries left=${retriesLeft}`)
392
+
393
+ if (retriesLeft === 0) {
394
+ throw error
395
+ }
396
+
397
+ await delay(delayBetweenTriesMs)
398
+ }
399
+ }
400
+ }
401
+
402
+ return {
403
+ get: async (type, ids) => {
404
+ const ctx = txStorage.getStore()
405
+
406
+ if (!ctx) {
407
+ // No transaction - direct read without exclusive lock for concurrency
408
+ return state.get(type, ids)
409
+ }
410
+
411
+ // In transaction - check cache first
412
+ const cached = ctx.cache[type] || {}
413
+ const missing = ids.filter(id => !(id in cached))
414
+
415
+ if (missing.length > 0) {
416
+ ctx.dbQueries++
417
+
418
+ logger.trace({ type, count: missing.length }, 'fetching missing keys in transaction')
419
+
420
+ const fetched = await getTxMutex(type).runExclusive(() => state.get(type, missing))
421
+
422
+ // Update cache
423
+ ctx.cache[type] = ctx.cache[type] || {};
424
+ Object.assign(ctx.cache[type], fetched);
425
+ }
426
+
427
+ // Return requested ids from cache
428
+ const result = {}
429
+
430
+ for (const id of ids) {
431
+ const value = ctx.cache[type]?.[id]
432
+
433
+ if (value !== undefined && value !== null) {
434
+ result[id] = value;
435
+ }
436
+ }
437
+
438
+ return result
439
+ },
440
+ set: async (data) => {
441
+ const ctx = txStorage.getStore()
442
+
443
+ if (!ctx) {
444
+ // No transaction - direct write with queue protection
445
+ const types = Object.keys(data)
446
+
447
+ // Process pre-keys with validation
448
+ for (const type_ of types) {
449
+ const type = type_
450
+ if (type === 'pre-key') {
451
+ await preKeyManager.validateDeletions(data, type)
452
+ }
453
+ }
454
+
455
+ // Write all data in parallel
456
+ await Promise.all(types.map(type => getQueue(type).add(async () => {
457
+ const typeData = { [type]: data[type] }
458
+ await state.set(typeData)
459
+ })))
460
+
461
+ return
462
+ }
463
+
464
+ // In transaction - update cache and mutations
465
+ logger.trace({ types: Object.keys(data) }, 'caching in transaction')
466
+
467
+ for (const key_ in data) {
468
+ const key = key_
469
+
470
+ // Ensure structures exist
471
+ ctx.cache[key] = ctx.cache[key] || {}
472
+ ctx.mutations[key] = ctx.mutations[key] || {}
473
+
474
+ // Special handling for pre-keys
475
+ if (key === 'pre-key') {
476
+ await preKeyManager.processOperations(data, key, ctx.cache, ctx.mutations, true)
477
+ }
478
+
479
+ else {
480
+ // Normal key types
481
+ Object.assign(ctx.cache[key], data[key])
482
+ Object.assign(ctx.mutations[key], data[key])
483
+ }
484
+ }
485
+ },
486
+ isInTransaction,
487
+ transaction: async (work, key) => {
488
+ const existing = txStorage.getStore()
489
+
490
+ // Nested transaction - reuse existing context
491
+ if (existing) {
492
+ logger.trace('reusing existing transaction context')
493
+ return work()
494
+ }
495
+
496
+ // New transaction - acquire mutex and create context
497
+ const mutex = getTxMutex(key)
498
+
499
+ acquireTxMutexRef(key)
500
+
501
+ try {
502
+ return await mutex.runExclusive(async () => {
503
+ const ctx = {
504
+ cache: {},
505
+ mutations: {},
506
+ dbQueries: 0
507
+ }
508
+
509
+ logger.trace('entering transaction')
510
+
511
+ try {
512
+ const result = await txStorage.run(ctx, work)
513
+
514
+ // Commit mutations
515
+ await commitWithRetry(ctx.mutations)
516
+
517
+ logger.trace({ dbQueries: ctx.dbQueries }, 'transaction completed')
518
+
519
+ return result
520
+ }
521
+
522
+ catch (error) {
523
+ logger.error({ error }, 'transaction failed, rolling back')
524
+ throw error
525
+ }
526
+ })
527
+ }
528
+ finally {
529
+ releaseTxMutexRef(key)
530
+ }
531
+ }
532
+ }
533
+ }
534
+
535
+ const initAuthCreds = () => {
536
+ const identityKey = Curve.generateKeyPair()
537
+ return {
538
+ noiseKey: Curve.generateKeyPair(),
539
+ pairingEphemeralKeyPair: Curve.generateKeyPair(),
540
+ signedIdentityKey: identityKey,
541
+ signedPreKey: signedKeyPair(identityKey, 1),
542
+ registrationId: generateRegistrationId(),
543
+ advSecretKey: randomBytes(32).toString('base64'),
544
+ processedHistoryMessages: [],
545
+ nextPreKeyId: 1,
546
+ firstUnuploadedPreKeyId: 1,
547
+ accountSyncCounter: 0,
548
+ accountSettings: {
549
+ unarchiveChats: false
550
+ },
551
+ registered: false,
552
+ pairingCode: undefined,
553
+ lastPropHash: undefined,
554
+ routingInfo: undefined,
555
+ additionalData: undefined
556
+ }
557
+ }
558
+
559
+ module.exports = {
560
+ makeCacheableSignalKeyStore,
561
+ addTransactionCapability,
562
+ initAuthCreds
563
+ }
564
+ return module.exports;
565
+ })();
566
+ for (const key of Object.keys(__kageModule57)) {
567
+ if (key !== '__esModule' && !Object.prototype.hasOwnProperty.call(exports,key)) Object.defineProperty(exports,key,{enumerable:true,configurable:true,get:()=>__kageModule57[key]});
568
+ }
569
+
570
+ // Kage: funciones avanzadas.
571
+ const __kageModule161 = (() => {
572
+ const module = { exports: {} }; const exports = module.exports;
573
+ "use strict";
574
+ Object.defineProperty(exports, "__esModule", { value: true });
575
+ exports.initAuthCreds = exports.assertMeId = exports.addTransactionCapability = void 0;
576
+ exports.makeCacheableSignalKeyStore = makeCacheableSignalKeyStore;
577
+ const node_async_hooks_1 = require("node:async_hooks");
578
+ const node_crypto_1 = require("node:crypto");
579
+ const index_js_1 = require("../Addon/index.js");
580
+ const index_js_2 = require("../Defaults/index.js");
581
+ const crypto_js_1 = require("./crypto.js");
582
+ const generics_js_1 = require("./generics.js");
583
+ const pre_key_manager_js_1 = require("./pre-key-manager.js");
584
+ // One instance per process: a per-socket AsyncLocalStorage leaks the heap under Node's legacy
585
+ // async-context propagation, where every live instance tags every pending async resource. The
586
+ // value is keyed by store token so a store only ever sees its own context, even when another
587
+ // wrapped store runs inside its transaction.
588
+ const txStorage = new node_async_hooks_1.AsyncLocalStorage();
589
+ /**
590
+ * Adds caching capability to a SignalKeyStore
591
+ * @param store the store to add caching to
592
+ * @param logger to log trace events
593
+ * @param _cache cache store to use
594
+ */
595
+ function makeCacheableSignalKeyStore(store, logger, _cache) {
596
+ const cache = _cache ||
597
+ (0, index_js_1.createCache)({
598
+ ttl: index_js_2.DEFAULT_CACHE_TTLS.SIGNAL_STORE // 5 minutes
599
+ });
600
+ // Mutex for protecting cache operations
601
+ const cacheMutex = (0, index_js_1.createMutex)();
602
+ function getUniqueId(type, id) {
603
+ return `${type}.${id}`;
604
+ }
605
+ return {
606
+ async get(type, ids) {
607
+ return cacheMutex.runExclusive(async () => {
608
+ const data = {};
609
+ const idsToFetch = [];
610
+ for (const id of ids) {
611
+ const item = (await cache.get(getUniqueId(type, id)));
612
+ if (typeof item !== 'undefined') {
613
+ data[id] = item;
614
+ }
615
+ else {
616
+ idsToFetch.push(id);
617
+ }
618
+ }
619
+ if (idsToFetch.length) {
620
+ logger?.trace({ items: idsToFetch.length }, 'loading from store');
621
+ const fetched = await store.get(type, idsToFetch);
622
+ for (const id of idsToFetch) {
623
+ const item = fetched[id];
624
+ if (item) {
625
+ data[id] = item;
626
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
627
+ await cache.set(getUniqueId(type, id), item);
628
+ }
629
+ }
630
+ }
631
+ return data;
632
+ });
633
+ },
634
+ async set(data) {
635
+ return cacheMutex.runExclusive(async () => {
636
+ let keys = 0;
637
+ for (const type in data) {
638
+ for (const id in data[type]) {
639
+ await cache.set(getUniqueId(type, id), data[type][id]);
640
+ keys += 1;
641
+ }
642
+ }
643
+ logger?.trace({ keys }, 'updated cache');
644
+ await store.set(data);
645
+ });
646
+ },
647
+ async clear() {
648
+ await cache.flushAll();
649
+ await store.clear?.();
650
+ }
651
+ };
652
+ }
653
+ /**
654
+ * Adds DB-like transaction capability to the SignalKeyStore
655
+ * Uses AsyncLocalStorage for automatic context management
656
+ * @param state the key store to apply this capability to
657
+ * @param logger logger to log events
658
+ * @returns SignalKeyStore with transaction capability
659
+ */
660
+ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetweenTriesMs }) => {
661
+ // Queues for concurrency control (keyed by signal data type - bounded set)
662
+ const keyQueues = new Map();
663
+ // Transaction mutexes with reference counting for cleanup
664
+ const txMutexes = new Map();
665
+ const txMutexRefCounts = new Map();
666
+ // Pre-key manager for specialized operations
667
+ const preKeyManager = new pre_key_manager_js_1.PreKeyManager(state, logger);
668
+ /**
669
+ * Get or create a queue for a specific key type
670
+ */
671
+ function getQueue(key) {
672
+ if (!keyQueues.has(key)) {
673
+ keyQueues.set(key, (0, index_js_1.createQueue)(1));
674
+ }
675
+ return keyQueues.get(key);
676
+ }
677
+ /**
678
+ * Get or create a transaction mutex
679
+ */
680
+ function getTxMutex(key) {
681
+ if (!txMutexes.has(key)) {
682
+ txMutexes.set(key, (0, index_js_1.createMutex)());
683
+ txMutexRefCounts.set(key, 0);
684
+ }
685
+ return txMutexes.get(key);
686
+ }
687
+ /**
688
+ * Acquire a reference to a transaction mutex
689
+ */
690
+ function acquireTxMutexRef(key) {
691
+ const count = txMutexRefCounts.get(key) ?? 0;
692
+ txMutexRefCounts.set(key, count + 1);
693
+ }
694
+ /**
695
+ * Release a reference to a transaction mutex and cleanup if no longer needed
696
+ */
697
+ function releaseTxMutexRef(key) {
698
+ const count = (txMutexRefCounts.get(key) ?? 1) - 1;
699
+ txMutexRefCounts.set(key, count);
700
+ // Cleanup if no more references and mutex is not locked
701
+ if (count <= 0) {
702
+ const mutex = txMutexes.get(key);
703
+ if (mutex && !mutex.isLocked()) {
704
+ txMutexes.delete(key);
705
+ txMutexRefCounts.delete(key);
706
+ }
707
+ }
708
+ }
709
+ /**
710
+ * Check if currently in a transaction
711
+ */
712
+ function isInTransaction() {
713
+ return !!txStorage.getStore();
714
+ }
715
+ /**
716
+ * Commit transaction with retries
717
+ */
718
+ async function commitWithRetry(mutations) {
719
+ if (Object.keys(mutations).length === 0) {
720
+ logger.trace('no mutations in transaction');
721
+ return;
722
+ }
723
+ logger.trace('committing transaction');
724
+ for (let attempt = 0; attempt < maxCommitRetries; attempt++) {
725
+ try {
726
+ await state.set(mutations);
727
+ logger.trace({ mutationCount: Object.keys(mutations).length }, 'committed transaction');
728
+ return;
729
+ }
730
+ catch (error) {
731
+ const retriesLeft = maxCommitRetries - attempt - 1;
732
+ logger.warn(`failed to commit mutations, retries left=${retriesLeft}`);
733
+ if (retriesLeft === 0) {
734
+ throw error;
735
+ }
736
+ await (0, generics_js_1.delay)(delayBetweenTriesMs);
737
+ }
738
+ }
739
+ }
740
+ return {
741
+ get: async (type, ids) => {
742
+ const ctx = txStorage.getStore();
743
+ if (!ctx) {
744
+ // No transaction - direct read without exclusive lock for concurrency
745
+ return state.get(type, ids);
746
+ }
747
+ // In transaction - check cache first
748
+ const cached = ctx.cache[type] || {};
749
+ const missing = ids.filter(id => !(id in cached));
750
+ if (missing.length > 0) {
751
+ ctx.dbQueries++;
752
+ logger.trace({ type, count: missing.length }, 'fetching missing keys in transaction');
753
+ const fetched = await getTxMutex(type).runExclusive(() => state.get(type, missing));
754
+ // Update cache
755
+ ctx.cache[type] = ctx.cache[type] || {};
756
+ Object.assign(ctx.cache[type], fetched);
757
+ }
758
+ // Return requested ids from cache
759
+ const result = {};
760
+ for (const id of ids) {
761
+ const value = ctx.cache[type]?.[id];
762
+ if (value !== undefined && value !== null) {
763
+ result[id] = value;
764
+ }
765
+ }
766
+ return result;
767
+ },
768
+ set: async (data) => {
769
+ const ctx = txStorage.getStore();
770
+ if (!ctx) {
771
+ // No transaction - direct write with queue protection
772
+ const types = Object.keys(data);
773
+ // Process pre-keys with validation
774
+ for (const type_ of types) {
775
+ const type = type_;
776
+ if (type === 'pre-key') {
777
+ await preKeyManager.validateDeletions(data, type);
778
+ }
779
+ }
780
+ // Write all data in parallel
781
+ await Promise.all(types.map(type => getQueue(type).add(async () => {
782
+ const typeData = { [type]: data[type] };
783
+ await state.set(typeData);
784
+ })));
785
+ return;
786
+ }
787
+ // In transaction - update cache and mutations
788
+ logger.trace({ types: Object.keys(data) }, 'caching in transaction');
789
+ for (const key_ in data) {
790
+ const key = key_;
791
+ // Ensure structures exist
792
+ ctx.cache[key] = ctx.cache[key] || {};
793
+ ctx.mutations[key] = ctx.mutations[key] || {};
794
+ // Special handling for pre-keys
795
+ if (key === 'pre-key') {
796
+ await preKeyManager.processOperations(data, key, ctx.cache, ctx.mutations, true);
797
+ }
798
+ else {
799
+ // Normal key types
800
+ Object.assign(ctx.cache[key], data[key]);
801
+ Object.assign(ctx.mutations[key], data[key]);
802
+ }
803
+ }
804
+ },
805
+ isInTransaction,
806
+ transaction: async (work, key) => {
807
+ const existing = txStorage.getStore();
808
+ // Nested transaction - reuse existing context
809
+ if (existing) {
810
+ logger.trace('reusing existing transaction context');
811
+ return work();
812
+ }
813
+ // New transaction - acquire mutex and create context
814
+ const mutex = getTxMutex(key);
815
+ acquireTxMutexRef(key);
816
+ try {
817
+ return await mutex.runExclusive(async () => {
818
+ const ctx = {
819
+ cache: {},
820
+ mutations: {},
821
+ dbQueries: 0
822
+ };
823
+ logger.trace('entering transaction');
824
+ try {
825
+ const result = await txStorage.run(ctx, work);
826
+ // Commit mutations
827
+ await commitWithRetry(ctx.mutations);
828
+ logger.trace({ dbQueries: ctx.dbQueries }, 'transaction completed');
829
+ return result;
830
+ }
831
+ catch (error) {
832
+ logger.error({ error }, 'transaction failed, rolling back');
833
+ throw error;
834
+ }
835
+ });
836
+ }
837
+ finally {
838
+ releaseTxMutexRef(key);
839
+ }
840
+ },
841
+ disposeTransactionStorage: () => {
842
+ // The first txStorage.run() enables the storage, which registers it in a
843
+ // module-global list inside node:async_hooks holding a STRONG reference.
844
+ // On Node < 24 every enabled storage also stamps one symbol-keyed property
845
+ // onto every async resource created anywhere in the process, so the cost of
846
+ // never disabling grows with sockets-ever-created x live async resources
847
+ // (observed: 1.9GB of a 2.1GB heap after 25h at ~250 concurrent sockets).
848
+ // Only .disable() releases it - GC alone never collects an enabled storage,
849
+ // on any Node version.
850
+ try {
851
+ txStorage.disable();
852
+ }
853
+ catch (err) {
854
+ logger.warn({ err }, 'failed to disable transaction storage');
855
+ }
856
+ }
857
+ };
858
+ };
859
+ exports.addTransactionCapability = addTransactionCapability;
860
+ /**
861
+ * Returns the authenticated user's JID, or throws a Boom-401 if creds are not yet authenticated.
862
+ * Use this anywhere we'd otherwise reach for `creds.me!.id` to fail fast with a descriptive error.
863
+ */
864
+ const assertMeId = (creds) => {
865
+ const id = creds.me?.id;
866
+ if (!id) {
867
+ throw new index_js_1.HttpError('Cannot proceed: socket is not authenticated yet (creds.me.id is missing)', { statusCode: 401 });
868
+ }
869
+ return id;
870
+ };
871
+ exports.assertMeId = assertMeId;
872
+ const initAuthCreds = () => {
873
+ const identityKey = crypto_js_1.Curve.generateKeyPair();
874
+ return {
875
+ noiseKey: crypto_js_1.Curve.generateKeyPair(),
876
+ pairingEphemeralKeyPair: crypto_js_1.Curve.generateKeyPair(),
877
+ signedIdentityKey: identityKey,
878
+ signedPreKey: (0, crypto_js_1.signedKeyPair)(identityKey, 1),
879
+ registrationId: (0, generics_js_1.generateRegistrationId)(),
880
+ advSecretKey: (0, node_crypto_1.randomBytes)(32).toString('base64'),
881
+ processedHistoryMessages: [],
882
+ nextPreKeyId: 1,
883
+ firstUnuploadedPreKeyId: 1,
884
+ accountSyncCounter: 0,
885
+ accountSettings: {
886
+ unarchiveChats: false
887
+ },
888
+ registered: false,
889
+ pairingCode: undefined,
890
+ lastPropHash: undefined,
891
+ routingInfo: undefined,
892
+ additionalData: undefined
893
+ };
894
+ };
895
+ exports.initAuthCreds = initAuthCreds;
896
+
897
+ return module.exports;
898
+ })();
899
+ for (const key of Object.keys(__kageModule161)) {
900
+ if (key !== '__esModule' && !Object.prototype.hasOwnProperty.call(exports,key)) Object.defineProperty(exports,key,{enumerable:true,configurable:true,get:()=>__kageModule161[key]});
901
+ }
902
+ Object.defineProperty(exports, Symbol.for('kage.advanced'), {value:__kageModule161, configurable:true});