zapo-js 0.1.1 → 0.1.2

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 (363) hide show
  1. package/README.md +8 -0
  2. package/dist/appstate/WaAppStateCrypto.js +18 -25
  3. package/dist/appstate/WaAppStateSyncClient.js +181 -114
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/utils.js +10 -30
  7. package/dist/auth/WaAuthClient.js +48 -55
  8. package/dist/auth/flow/WaAuthCredentialsFlow.js +21 -14
  9. package/dist/auth/index.js +1 -3
  10. package/dist/auth/pairing/WaPairingFlow.js +21 -23
  11. package/dist/auth/pairing/WaQrFlow.js +37 -24
  12. package/dist/client/WaClient.js +103 -276
  13. package/dist/client/WaClientFactory.js +227 -110
  14. package/dist/client/connection/WaConnectionManager.js +292 -0
  15. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  16. package/dist/client/connection/WaReceiptQueue.js +51 -0
  17. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  18. package/dist/client/coordinators/WaGroupCoordinator.js +27 -17
  19. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
  20. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +231 -686
  21. package/dist/client/coordinators/WaRetryCoordinator.js +70 -37
  22. package/dist/client/dirty.js +35 -29
  23. package/dist/client/events/chat.js +4 -3
  24. package/dist/client/events/group.js +59 -36
  25. package/dist/client/history-sync.js +53 -63
  26. package/dist/client/incoming.js +23 -20
  27. package/dist/client/mailbox.js +8 -8
  28. package/dist/client/messages.js +4 -4
  29. package/dist/client/messaging/fanout.js +189 -0
  30. package/dist/client/messaging/key-protocol.js +130 -0
  31. package/dist/client/messaging/participants.js +191 -0
  32. package/dist/crypto/core/hkdf.js +3 -8
  33. package/dist/crypto/core/index.js +1 -4
  34. package/dist/crypto/core/keys.js +2 -3
  35. package/dist/crypto/core/primitives.js +12 -15
  36. package/dist/crypto/core/random.js +7 -26
  37. package/dist/crypto/curves/Ed25519.js +7 -8
  38. package/dist/crypto/curves/X25519.js +13 -16
  39. package/dist/crypto/index.js +0 -5
  40. package/dist/esm/appstate/WaAppStateCrypto.js +6 -13
  41. package/dist/esm/appstate/WaAppStateSyncClient.js +174 -107
  42. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  43. package/dist/esm/appstate/constants.js +3 -2
  44. package/dist/esm/appstate/utils.js +8 -27
  45. package/dist/esm/auth/WaAuthClient.js +48 -55
  46. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +21 -14
  47. package/dist/esm/auth/index.js +0 -1
  48. package/dist/esm/auth/pairing/WaPairingFlow.js +14 -16
  49. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  50. package/dist/esm/client/WaClient.js +103 -276
  51. package/dist/esm/client/WaClientFactory.js +227 -110
  52. package/dist/esm/client/connection/WaConnectionManager.js +288 -0
  53. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  54. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  55. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  56. package/dist/esm/client/coordinators/WaGroupCoordinator.js +20 -10
  57. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
  58. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +232 -687
  59. package/dist/esm/client/coordinators/WaRetryCoordinator.js +71 -38
  60. package/dist/esm/client/dirty.js +30 -24
  61. package/dist/esm/client/events/chat.js +4 -3
  62. package/dist/esm/client/events/group.js +50 -28
  63. package/dist/esm/client/history-sync.js +50 -60
  64. package/dist/esm/client/incoming.js +23 -20
  65. package/dist/esm/client/mailbox.js +8 -8
  66. package/dist/esm/client/messages.js +1 -1
  67. package/dist/esm/client/messaging/fanout.js +186 -0
  68. package/dist/esm/client/messaging/key-protocol.js +127 -0
  69. package/dist/esm/client/messaging/participants.js +188 -0
  70. package/dist/esm/crypto/core/hkdf.js +3 -8
  71. package/dist/esm/crypto/core/index.js +0 -1
  72. package/dist/esm/crypto/core/keys.js +2 -3
  73. package/dist/esm/crypto/core/primitives.js +12 -15
  74. package/dist/esm/crypto/core/random.js +6 -25
  75. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  76. package/dist/esm/crypto/curves/X25519.js +10 -13
  77. package/dist/esm/crypto/index.js +0 -2
  78. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  79. package/dist/esm/infra/log/PinoLogger.js +15 -9
  80. package/dist/esm/infra/log/types.js +11 -1
  81. package/dist/esm/infra/perf/BoundedTaskQueue.js +13 -17
  82. package/dist/esm/media/WaMediaCrypto.js +2 -4
  83. package/dist/esm/media/WaMediaTransferClient.js +226 -58
  84. package/dist/esm/media/conn.js +10 -6
  85. package/dist/esm/media/constants.js +4 -1
  86. package/dist/esm/message/WaMessageClient.js +4 -13
  87. package/dist/esm/message/ack.js +6 -6
  88. package/dist/esm/message/addon-crypto.js +59 -0
  89. package/dist/esm/message/incoming.js +106 -111
  90. package/dist/esm/message/index.js +2 -0
  91. package/dist/esm/message/reporting-token.js +438 -0
  92. package/dist/esm/message/use-case-secret.js +49 -0
  93. package/dist/esm/protocol/appstate.js +58 -0
  94. package/dist/esm/protocol/constants.js +2 -1
  95. package/dist/esm/protocol/index.js +2 -10
  96. package/dist/esm/protocol/jid.js +63 -51
  97. package/dist/esm/protocol/media.js +3 -3
  98. package/dist/esm/protocol/nodes.js +2 -0
  99. package/dist/esm/protocol/usync.js +11 -0
  100. package/dist/esm/retry/index.js +1 -0
  101. package/dist/esm/retry/outbound.js +4 -5
  102. package/dist/esm/retry/parse.js +58 -76
  103. package/dist/esm/retry/replay.js +48 -49
  104. package/dist/esm/retry/tracker.js +56 -0
  105. package/dist/esm/signal/api/SignalDeviceSyncApi.js +249 -82
  106. package/dist/esm/signal/api/SignalDigestSyncApi.js +6 -1
  107. package/dist/esm/signal/api/SignalIdentitySyncApi.js +49 -34
  108. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +70 -62
  109. package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -30
  110. package/dist/esm/signal/crypto/WaAdvSignature.js +3 -5
  111. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  112. package/dist/esm/signal/group/SenderKeyCodec.js +2 -4
  113. package/dist/esm/signal/group/SenderKeyManager.js +26 -16
  114. package/dist/esm/signal/index.js +1 -0
  115. package/dist/esm/signal/session/SignalProtocol.js +49 -14
  116. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  117. package/dist/esm/signal/session/SignalSession.js +14 -9
  118. package/dist/esm/signal/session/resolver.js +186 -0
  119. package/dist/esm/signal/store/sqlite.js +16 -37
  120. package/dist/esm/store/createStore.js +16 -18
  121. package/dist/esm/store/noop.store.js +3 -6
  122. package/dist/esm/store/providers/memory/appstate.store.js +30 -6
  123. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  124. package/dist/esm/store/providers/memory/device-list.store.js +3 -30
  125. package/dist/esm/store/providers/memory/message.store.js +11 -5
  126. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  127. package/dist/esm/store/providers/memory/sender-key.store.js +5 -7
  128. package/dist/esm/store/providers/memory/signal.store.js +13 -1
  129. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  130. package/dist/esm/store/providers/sqlite/appstate.store.js +82 -1
  131. package/dist/esm/store/providers/sqlite/connection.js +18 -13
  132. package/dist/esm/store/providers/sqlite/contact.store.js +31 -18
  133. package/dist/esm/store/providers/sqlite/device-list.store.js +7 -35
  134. package/dist/esm/store/providers/sqlite/message.store.js +45 -32
  135. package/dist/esm/store/providers/sqlite/migrations.js +1 -1
  136. package/dist/esm/store/providers/sqlite/participants.store.js +1 -9
  137. package/dist/esm/store/providers/sqlite/retry.store.js +8 -11
  138. package/dist/esm/store/providers/sqlite/sender-key.store.js +25 -30
  139. package/dist/esm/store/providers/sqlite/signal.store.js +104 -22
  140. package/dist/esm/store/providers/sqlite/table-names.js +107 -0
  141. package/dist/esm/store/providers/sqlite/thread.store.js +35 -22
  142. package/dist/esm/transport/WaComms.js +25 -23
  143. package/dist/esm/transport/WaWebSocket.js +115 -12
  144. package/dist/esm/transport/binary/decoder.js +4 -4
  145. package/dist/esm/transport/binary/encoder.js +12 -4
  146. package/dist/esm/transport/index.js +1 -0
  147. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  148. package/dist/esm/transport/node/WaNodeOrchestrator.js +2 -4
  149. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  150. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  151. package/dist/esm/transport/node/builders/index.js +2 -1
  152. package/dist/esm/transport/node/builders/message.js +9 -0
  153. package/dist/esm/transport/node/builders/pairing.js +4 -5
  154. package/dist/esm/transport/node/builders/usync.js +41 -0
  155. package/dist/esm/transport/node/helpers.js +107 -5
  156. package/dist/esm/transport/node/usync.js +35 -0
  157. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  158. package/dist/esm/transport/noise/WaNoiseCert.js +3 -6
  159. package/dist/esm/transport/noise/WaNoiseSession.js +17 -10
  160. package/dist/esm/transport/proxy.js +27 -0
  161. package/dist/esm/transport/stream/parse.js +13 -48
  162. package/dist/esm/util/bytes.js +50 -32
  163. package/dist/esm/util/coercion.js +6 -14
  164. package/dist/esm/util/primitives.js +39 -14
  165. package/dist/infra/log/ConsoleLogger.js +18 -17
  166. package/dist/infra/log/PinoLogger.js +15 -9
  167. package/dist/infra/log/types.js +12 -0
  168. package/dist/infra/perf/BoundedTaskQueue.js +13 -17
  169. package/dist/media/WaMediaCrypto.js +1 -3
  170. package/dist/media/WaMediaTransferClient.js +259 -58
  171. package/dist/media/conn.js +10 -6
  172. package/dist/media/constants.js +4 -1
  173. package/dist/message/WaMessageClient.js +5 -14
  174. package/dist/message/ack.js +6 -6
  175. package/dist/message/addon-crypto.js +65 -0
  176. package/dist/message/incoming.js +104 -109
  177. package/dist/message/index.js +2 -0
  178. package/dist/message/reporting-token.js +443 -0
  179. package/dist/message/use-case-secret.js +55 -0
  180. package/dist/protocol/appstate.js +59 -1
  181. package/dist/protocol/constants.js +7 -1
  182. package/dist/protocol/index.js +20 -42
  183. package/dist/protocol/jid.js +64 -51
  184. package/dist/protocol/media.js +3 -3
  185. package/dist/protocol/nodes.js +2 -0
  186. package/dist/protocol/usync.js +14 -0
  187. package/dist/retry/index.js +3 -1
  188. package/dist/retry/outbound.js +6 -7
  189. package/dist/retry/parse.js +57 -75
  190. package/dist/retry/replay.js +46 -47
  191. package/dist/retry/tracker.js +59 -0
  192. package/dist/signal/api/SignalDeviceSyncApi.js +247 -80
  193. package/dist/signal/api/SignalDigestSyncApi.js +6 -1
  194. package/dist/signal/api/SignalIdentitySyncApi.js +49 -34
  195. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +67 -59
  196. package/dist/signal/api/SignalSessionSyncApi.js +23 -30
  197. package/dist/signal/crypto/WaAdvSignature.js +2 -4
  198. package/dist/signal/group/SenderKeyChain.js +27 -22
  199. package/dist/signal/group/SenderKeyCodec.js +1 -3
  200. package/dist/signal/group/SenderKeyManager.js +26 -16
  201. package/dist/signal/index.js +3 -1
  202. package/dist/signal/session/SignalProtocol.js +49 -14
  203. package/dist/signal/session/SignalRatchet.js +24 -15
  204. package/dist/signal/session/SignalSession.js +14 -9
  205. package/dist/signal/session/resolver.js +189 -0
  206. package/dist/signal/store/sqlite.js +16 -37
  207. package/dist/store/createStore.js +16 -18
  208. package/dist/store/noop.store.js +3 -6
  209. package/dist/store/providers/memory/appstate.store.js +28 -4
  210. package/dist/store/providers/memory/contact.store.js +5 -0
  211. package/dist/store/providers/memory/device-list.store.js +3 -30
  212. package/dist/store/providers/memory/message.store.js +11 -5
  213. package/dist/store/providers/memory/participants.store.js +1 -8
  214. package/dist/store/providers/memory/sender-key.store.js +8 -10
  215. package/dist/store/providers/memory/signal.store.js +21 -9
  216. package/dist/store/providers/memory/thread.store.js +5 -0
  217. package/dist/store/providers/sqlite/appstate.store.js +81 -0
  218. package/dist/store/providers/sqlite/connection.js +18 -13
  219. package/dist/store/providers/sqlite/contact.store.js +31 -18
  220. package/dist/store/providers/sqlite/device-list.store.js +7 -35
  221. package/dist/store/providers/sqlite/message.store.js +45 -32
  222. package/dist/store/providers/sqlite/migrations.js +1 -1
  223. package/dist/store/providers/sqlite/participants.store.js +1 -9
  224. package/dist/store/providers/sqlite/retry.store.js +8 -11
  225. package/dist/store/providers/sqlite/sender-key.store.js +24 -29
  226. package/dist/store/providers/sqlite/signal.store.js +105 -23
  227. package/dist/store/providers/sqlite/table-names.js +113 -0
  228. package/dist/store/providers/sqlite/thread.store.js +35 -22
  229. package/dist/transport/WaComms.js +27 -25
  230. package/dist/transport/WaWebSocket.js +148 -12
  231. package/dist/transport/binary/decoder.js +4 -4
  232. package/dist/transport/binary/encoder.js +12 -4
  233. package/dist/transport/index.js +7 -1
  234. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  235. package/dist/transport/node/WaNodeOrchestrator.js +2 -4
  236. package/dist/transport/node/WaNodeTransport.js +0 -3
  237. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  238. package/dist/transport/node/builders/index.js +12 -9
  239. package/dist/transport/node/builders/message.js +9 -0
  240. package/dist/transport/node/builders/pairing.js +4 -5
  241. package/dist/transport/node/builders/usync.js +45 -0
  242. package/dist/transport/node/helpers.js +112 -4
  243. package/dist/transport/node/usync.js +38 -0
  244. package/dist/transport/noise/WaFrameCodec.js +47 -32
  245. package/dist/transport/noise/WaNoiseCert.js +5 -8
  246. package/dist/transport/noise/WaNoiseSession.js +17 -10
  247. package/dist/transport/proxy.js +34 -0
  248. package/dist/transport/stream/parse.js +17 -53
  249. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  250. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  251. package/dist/types/appstate/constants.d.ts +1 -0
  252. package/dist/types/appstate/store/sqlite.d.ts +4 -18
  253. package/dist/types/appstate/utils.d.ts +0 -1
  254. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  255. package/dist/types/auth/index.d.ts +0 -2
  256. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  257. package/dist/types/auth/types.d.ts +6 -9
  258. package/dist/types/client/WaClient.d.ts +27 -25
  259. package/dist/types/client/WaClientFactory.d.ts +22 -23
  260. package/dist/types/client/connection/WaConnectionManager.d.ts +64 -0
  261. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  262. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  263. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  264. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +0 -1
  265. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +18 -41
  266. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +2 -0
  267. package/dist/types/client/dirty.d.ts +1 -0
  268. package/dist/types/client/events/group.d.ts +2 -1
  269. package/dist/types/client/index.d.ts +1 -1
  270. package/dist/types/client/messaging/fanout.d.ts +14 -0
  271. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  272. package/dist/types/client/messaging/participants.d.ts +13 -0
  273. package/dist/types/client/types.d.ts +24 -1
  274. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  275. package/dist/types/crypto/core/index.d.ts +0 -1
  276. package/dist/types/crypto/core/random.d.ts +1 -7
  277. package/dist/types/crypto/index.d.ts +0 -2
  278. package/dist/types/index.d.ts +1 -1
  279. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  280. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  281. package/dist/types/infra/log/types.d.ts +1 -0
  282. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  283. package/dist/types/media/WaMediaTransferClient.d.ts +13 -3
  284. package/dist/types/media/types.d.ts +5 -0
  285. package/dist/types/message/addon-crypto.d.ts +25 -0
  286. package/dist/types/message/index.d.ts +2 -0
  287. package/dist/types/message/reporting-token.d.ts +19 -0
  288. package/dist/types/message/use-case-secret.d.ts +20 -0
  289. package/dist/types/protocol/appstate.d.ts +58 -0
  290. package/dist/types/protocol/constants.d.ts +2 -1
  291. package/dist/types/protocol/index.d.ts +2 -10
  292. package/dist/types/protocol/jid.d.ts +3 -3
  293. package/dist/types/protocol/nodes.d.ts +2 -0
  294. package/dist/types/protocol/usync.d.ts +11 -0
  295. package/dist/types/retry/index.d.ts +1 -0
  296. package/dist/types/retry/replay.d.ts +0 -4
  297. package/dist/types/retry/tracker.d.ts +19 -0
  298. package/dist/types/retry/types.d.ts +4 -3
  299. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +13 -1
  300. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  301. package/dist/types/signal/index.d.ts +1 -0
  302. package/dist/types/signal/session/SignalProtocol.d.ts +9 -0
  303. package/dist/types/signal/session/resolver.d.ts +17 -0
  304. package/dist/types/store/contracts/appstate.store.d.ts +3 -0
  305. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  306. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  307. package/dist/types/store/contracts/message.store.d.ts +1 -0
  308. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  309. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  310. package/dist/types/store/contracts/signal.store.d.ts +6 -0
  311. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  312. package/dist/types/store/index.d.ts +1 -1
  313. package/dist/types/store/providers/memory/appstate.store.d.ts +2 -0
  314. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  315. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  316. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  317. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  318. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  319. package/dist/types/store/providers/memory/signal.store.d.ts +6 -0
  320. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  321. package/dist/types/store/providers/sqlite/appstate.store.d.ts +2 -0
  322. package/dist/types/store/providers/sqlite/contact.store.d.ts +2 -0
  323. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -3
  324. package/dist/types/store/providers/sqlite/message.store.d.ts +2 -0
  325. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -1
  326. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -1
  327. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -1
  328. package/dist/types/store/providers/sqlite/signal.store.d.ts +7 -0
  329. package/dist/types/store/providers/sqlite/table-names.d.ts +5 -0
  330. package/dist/types/store/providers/sqlite/thread.store.d.ts +2 -0
  331. package/dist/types/store/types.d.ts +3 -0
  332. package/dist/types/transport/WaWebSocket.d.ts +3 -0
  333. package/dist/types/transport/index.d.ts +2 -1
  334. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  335. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  336. package/dist/types/transport/node/builders/group.d.ts +4 -6
  337. package/dist/types/transport/node/builders/index.d.ts +2 -1
  338. package/dist/types/transport/node/builders/message.d.ts +14 -25
  339. package/dist/types/transport/node/builders/retry.d.ts +2 -4
  340. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  341. package/dist/types/transport/node/helpers.d.ts +8 -0
  342. package/dist/types/transport/node/usync.d.ts +2 -0
  343. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  344. package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
  345. package/dist/types/transport/proxy.d.ts +6 -0
  346. package/dist/types/transport/stream/parse.d.ts +0 -1
  347. package/dist/types/transport/types.d.ts +18 -1
  348. package/dist/types/util/bytes.d.ts +5 -0
  349. package/dist/types/util/primitives.d.ts +3 -0
  350. package/dist/util/bytes.js +55 -33
  351. package/dist/util/coercion.js +6 -14
  352. package/dist/util/primitives.js +42 -14
  353. package/package.json +26 -5
  354. package/dist/crypto/core/encoding.js +0 -29
  355. package/dist/esm/crypto/core/encoding.js +0 -25
  356. package/dist/esm/util/base64.js +0 -18
  357. package/dist/esm/util/signal-address.js +0 -5
  358. package/dist/types/crypto/core/encoding.d.ts +0 -11
  359. package/dist/types/util/base64.d.ts +0 -4
  360. package/dist/types/util/signal-address.d.ts +0 -2
  361. package/dist/util/base64.js +0 -24
  362. package/dist/util/signal-address.js +0 -8
  363. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -0,0 +1,56 @@
1
+ import { RETRY_OUTBOUND_TTL_MS } from './constants.js';
2
+ import { encodeRetryReplayPayload } from './outbound.js';
3
+ import { toError } from '../util/primitives.js';
4
+ export function createOutboundRetryTracker(options) {
5
+ const { retryStore, logger } = options;
6
+ const retryTtlMs = retryStore.getTtlMs?.() ?? RETRY_OUTBOUND_TTL_MS;
7
+ const safeUpsertRetryOutboundRecord = async (record) => {
8
+ try {
9
+ await retryStore.upsertOutboundMessage(record);
10
+ }
11
+ catch (error) {
12
+ logger.warn('failed to persist retry outbound message record', {
13
+ messageId: record.messageId,
14
+ to: record.toJid,
15
+ mode: record.replayMode,
16
+ message: toError(error).message
17
+ });
18
+ return false;
19
+ }
20
+ return true;
21
+ };
22
+ return {
23
+ track: async (hint, publish) => {
24
+ const nowMs = Date.now();
25
+ const expiresAtMs = nowMs + retryTtlMs;
26
+ const hintedMessageId = hint.messageIdHint?.trim();
27
+ const replayMode = hint.replayPayload.mode;
28
+ const resolvedToJid = hint.toJid ?? (replayMode === 'opaque_node' ? '' : hint.replayPayload.to);
29
+ const replayPayload = encodeRetryReplayPayload(hint.replayPayload);
30
+ let hintedPersisted = false;
31
+ const createRetryOutboundRecord = (messageId, createdAtMs, updatedAtMs, expiresAtMs) => ({
32
+ messageId,
33
+ toJid: resolvedToJid,
34
+ participantJid: hint.participantJid,
35
+ recipientJid: hint.recipientJid,
36
+ messageType: hint.type,
37
+ replayMode,
38
+ replayPayload,
39
+ state: 'pending',
40
+ createdAtMs,
41
+ updatedAtMs,
42
+ expiresAtMs
43
+ });
44
+ if (hintedMessageId) {
45
+ hintedPersisted = await safeUpsertRetryOutboundRecord(createRetryOutboundRecord(hintedMessageId, nowMs, nowMs, expiresAtMs));
46
+ }
47
+ const result = await publish();
48
+ if (hintedPersisted && hintedMessageId && result.id === hintedMessageId) {
49
+ return result;
50
+ }
51
+ const persistedNowMs = Date.now();
52
+ await safeUpsertRetryOutboundRecord(createRetryOutboundRecord(result.id, hintedMessageId ? nowMs : persistedNowMs, persistedNowMs, persistedNowMs + retryTtlMs));
53
+ return result;
54
+ }
55
+ };
56
+ }
@@ -1,8 +1,9 @@
1
- import { randomInt } from 'node:crypto';
2
- import { WA_DEFAULTS, WA_NODE_TAGS, WA_XMLNS } from '../../protocol/constants.js';
1
+ import { WA_DEFAULTS, WA_NODE_TAGS, WA_USYNC_CONTEXTS } from '../../protocol/constants.js';
3
2
  import { parseSignalAddressFromJid, splitJid } from '../../protocol/jid.js';
3
+ import { buildUsyncIq } from '../../transport/node/builders/usync.js';
4
4
  import { findNodeChild, getNodeChildrenByTag } from '../../transport/node/helpers.js';
5
- import { assertIqResult, buildIqNode } from '../../transport/node/query.js';
5
+ import { assertIqResult } from '../../transport/node/query.js';
6
+ import { createUsyncSidGenerator } from '../../transport/node/usync.js';
6
7
  export class SignalDeviceSyncApi {
7
8
  constructor(options) {
8
9
  this.logger = options.logger;
@@ -11,6 +12,7 @@ export class SignalDeviceSyncApi {
11
12
  this.defaultTimeoutMs =
12
13
  options.defaultTimeoutMs ?? WA_DEFAULTS.SIGNAL_FETCH_KEY_BUNDLES_TIMEOUT_MS;
13
14
  this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
15
+ this.generateSid = options.generateSid ?? createUsyncSidGenerator();
14
16
  }
15
17
  async syncDeviceList(userJids, timeoutMs = this.defaultTimeoutMs) {
16
18
  const normalizedUsers = this.normalizeUsers(userJids);
@@ -23,12 +25,18 @@ export class SignalDeviceSyncApi {
23
25
  ? await this.collectUsersToQuery(normalizedUsers, nowMs, cachedByUser, this.deviceListStore)
24
26
  : normalizedUsers;
25
27
  if (usersToQuery.length === 0) {
26
- return normalizedUsers.map((jid) => ({
27
- jid,
28
- deviceJids: cachedByUser.get(jid) ?? []
29
- }));
28
+ const fromCache = new Array(normalizedUsers.length);
29
+ for (let index = 0; index < normalizedUsers.length; index += 1) {
30
+ const jid = normalizedUsers[index];
31
+ fromCache[index] = {
32
+ jid,
33
+ deviceJids: cachedByUser.get(jid) ?? []
34
+ };
35
+ }
36
+ return fromCache;
30
37
  }
31
- const request = this.makeDeviceSyncRequest(usersToQuery);
38
+ const sid = await this.generateSid();
39
+ const request = this.makeDeviceSyncRequest(usersToQuery, sid);
32
40
  this.logger.debug('signal device sync request', {
33
41
  users: usersToQuery.length,
34
42
  timeoutMs
@@ -37,23 +45,82 @@ export class SignalDeviceSyncApi {
37
45
  const parsed = this.parseDeviceSyncResponse(response, usersToQuery);
38
46
  if (this.deviceListStore) {
39
47
  const updatedAtMs = Date.now();
40
- await this.deviceListStore.upsertUserDevicesBatch(parsed.map((entry) => ({
41
- userJid: entry.jid,
42
- deviceJids: entry.deviceJids,
43
- updatedAtMs
44
- })));
45
- }
46
- const parsedByUser = new Map(parsed.map((entry) => [entry.jid, entry.deviceJids]));
47
- const merged = normalizedUsers.map((jid) => ({
48
- jid,
49
- deviceJids: parsedByUser.get(jid) ?? cachedByUser.get(jid) ?? []
50
- }));
48
+ const batch = new Array(parsed.length);
49
+ for (let index = 0; index < parsed.length; index += 1) {
50
+ const entry = parsed[index];
51
+ batch[index] = {
52
+ userJid: entry.jid,
53
+ deviceJids: entry.deviceJids,
54
+ updatedAtMs
55
+ };
56
+ }
57
+ await this.deviceListStore.upsertUserDevicesBatch(batch);
58
+ }
59
+ const parsedByUser = new Map();
60
+ for (let index = 0; index < parsed.length; index += 1) {
61
+ const entry = parsed[index];
62
+ parsedByUser.set(entry.jid, entry.deviceJids);
63
+ }
64
+ const merged = new Array(normalizedUsers.length);
65
+ let totalDevices = 0;
66
+ for (let index = 0; index < normalizedUsers.length; index += 1) {
67
+ const jid = normalizedUsers[index];
68
+ const deviceJids = parsedByUser.get(jid) ?? cachedByUser.get(jid) ?? [];
69
+ totalDevices += deviceJids.length;
70
+ merged[index] = {
71
+ jid,
72
+ deviceJids
73
+ };
74
+ }
51
75
  this.logger.debug('signal device sync success', {
52
76
  users: merged.length,
53
- devices: merged.reduce((total, entry) => total + entry.deviceJids.length, 0)
77
+ devices: totalDevices
54
78
  });
55
79
  return merged;
56
80
  }
81
+ async queryLidsByPhoneJids(phoneJids, timeoutMs = this.defaultTimeoutMs) {
82
+ const normalizedPhoneJids = this.normalizeUsers(phoneJids);
83
+ if (normalizedPhoneJids.length === 0) {
84
+ return [];
85
+ }
86
+ const sid = await this.generateSid();
87
+ const request = this.makeLidSyncRequest(normalizedPhoneJids, sid);
88
+ this.logger.debug('signal lid sync request', {
89
+ users: normalizedPhoneJids.length,
90
+ timeoutMs
91
+ });
92
+ const response = await this.query(request, timeoutMs);
93
+ const parsed = this.parseLidSyncResponse(response, normalizedPhoneJids);
94
+ const parsedByPhoneJid = new Map();
95
+ for (let index = 0; index < parsed.length; index += 1) {
96
+ const entry = parsed[index];
97
+ const phoneJid = entry.phoneJid ?? entry.jid;
98
+ parsedByPhoneJid.set(phoneJid, {
99
+ phoneJid,
100
+ lidJid: entry.lidJid,
101
+ exists: entry.exists
102
+ });
103
+ }
104
+ const result = new Array(normalizedPhoneJids.length);
105
+ let found = 0;
106
+ for (let index = 0; index < normalizedPhoneJids.length; index += 1) {
107
+ const phoneJid = normalizedPhoneJids[index];
108
+ const resolved = parsedByPhoneJid.get(phoneJid) ?? {
109
+ phoneJid,
110
+ lidJid: null,
111
+ exists: false
112
+ };
113
+ if (resolved.exists) {
114
+ found += 1;
115
+ }
116
+ result[index] = resolved;
117
+ }
118
+ this.logger.debug('signal lid sync success', {
119
+ users: result.length,
120
+ found
121
+ });
122
+ return result;
123
+ }
57
124
  async collectUsersToQuery(normalizedUsers, nowMs, cachedByUser, store) {
58
125
  const records = await store.getUserDevicesBatch(normalizedUsers, nowMs);
59
126
  const usersToQuery = [];
@@ -68,41 +135,59 @@ export class SignalDeviceSyncApi {
68
135
  }
69
136
  return usersToQuery;
70
137
  }
71
- makeDeviceSyncRequest(userJids) {
72
- return buildIqNode('get', this.hostDomain, WA_XMLNS.USYNC, [
73
- {
74
- tag: WA_NODE_TAGS.USYNC,
75
- attrs: {
76
- sid: this.makeSid(),
77
- index: '0',
78
- last: 'true',
79
- mode: WA_NODE_TAGS.QUERY,
80
- context: 'interactive'
81
- },
138
+ makeDeviceSyncRequest(userJids, sid) {
139
+ const users = new Array(userJids.length);
140
+ for (let index = 0; index < userJids.length; index += 1) {
141
+ users[index] = {
142
+ jid: userJids[index]
143
+ };
144
+ }
145
+ return buildUsyncIq({
146
+ sid,
147
+ hostDomain: this.hostDomain,
148
+ context: WA_USYNC_CONTEXTS.INTERACTIVE,
149
+ queryProtocolNodes: [
150
+ {
151
+ tag: WA_NODE_TAGS.DEVICES,
152
+ attrs: {
153
+ version: '2'
154
+ }
155
+ }
156
+ ],
157
+ users
158
+ });
159
+ }
160
+ makeLidSyncRequest(userJids, sid) {
161
+ const users = new Array(userJids.length);
162
+ for (let index = 0; index < userJids.length; index += 1) {
163
+ const jid = userJids[index];
164
+ users[index] = {
165
+ jid,
82
166
  content: [
83
167
  {
84
- tag: WA_NODE_TAGS.QUERY,
85
- attrs: {},
86
- content: [
87
- {
88
- tag: WA_NODE_TAGS.DEVICES,
89
- attrs: {
90
- version: '2'
91
- }
92
- }
93
- ]
94
- },
95
- {
96
- tag: WA_NODE_TAGS.LIST,
168
+ tag: WA_NODE_TAGS.CONTACT,
97
169
  attrs: {},
98
- content: userJids.map((jid) => ({
99
- tag: WA_NODE_TAGS.USER,
100
- attrs: { jid }
101
- }))
170
+ content: splitJid(jid).user
102
171
  }
103
172
  ]
104
- }
105
- ]);
173
+ };
174
+ }
175
+ return buildUsyncIq({
176
+ sid,
177
+ hostDomain: this.hostDomain,
178
+ context: WA_USYNC_CONTEXTS.INTERACTIVE,
179
+ queryProtocolNodes: [
180
+ {
181
+ tag: WA_NODE_TAGS.CONTACT,
182
+ attrs: {}
183
+ },
184
+ {
185
+ tag: WA_NODE_TAGS.LID,
186
+ attrs: {}
187
+ }
188
+ ],
189
+ users
190
+ });
106
191
  }
107
192
  parseDeviceSyncResponse(node, requestedUsers) {
108
193
  assertIqResult(node, 'signal device sync');
@@ -116,22 +201,95 @@ export class SignalDeviceSyncApi {
116
201
  }
117
202
  const requestedSet = new Set(requestedUsers);
118
203
  const userNodes = getNodeChildrenByTag(listNode, WA_NODE_TAGS.USER);
119
- return userNodes.flatMap((userNode) => {
204
+ const parsed = [];
205
+ for (let index = 0; index < userNodes.length; index += 1) {
206
+ const userNode = userNodes[index];
120
207
  const userJid = userNode.attrs.jid;
121
208
  if (!userJid) {
122
- return [];
209
+ continue;
123
210
  }
124
211
  const normalizedUserJid = this.normalizeUserJid(userJid);
125
212
  if (!requestedSet.has(normalizedUserJid)) {
126
- return [];
213
+ continue;
127
214
  }
128
- return [
129
- {
215
+ parsed.push({
216
+ jid: normalizedUserJid,
217
+ deviceJids: this.parseUserDeviceJids(userNode, normalizedUserJid)
218
+ });
219
+ }
220
+ return parsed;
221
+ }
222
+ parseLidSyncResponse(node, requestedUsers) {
223
+ assertIqResult(node, 'signal lid sync');
224
+ const usyncNode = findNodeChild(node, WA_NODE_TAGS.USYNC);
225
+ if (!usyncNode) {
226
+ throw new Error('signal lid sync response missing usync node');
227
+ }
228
+ const listNode = findNodeChild(usyncNode, WA_NODE_TAGS.LIST);
229
+ if (!listNode) {
230
+ throw new Error('signal lid sync response missing list node');
231
+ }
232
+ const requestedSet = new Set(requestedUsers);
233
+ const userNodes = getNodeChildrenByTag(listNode, WA_NODE_TAGS.USER);
234
+ const parsed = [];
235
+ for (let index = 0; index < userNodes.length; index += 1) {
236
+ const userNode = userNodes[index];
237
+ const userJid = userNode.attrs.jid;
238
+ if (!userJid) {
239
+ continue;
240
+ }
241
+ const normalizedUserJid = this.normalizeUserJid(userJid);
242
+ const normalizedPhoneJid = userNode.attrs.pn_jid
243
+ ? this.normalizeUserJid(userNode.attrs.pn_jid)
244
+ : null;
245
+ const wasRequested = requestedSet.has(normalizedUserJid) ||
246
+ (normalizedPhoneJid !== null && requestedSet.has(normalizedPhoneJid));
247
+ if (!wasRequested) {
248
+ continue;
249
+ }
250
+ const lidNode = findNodeChild(userNode, WA_NODE_TAGS.LID);
251
+ const contactNode = findNodeChild(userNode, WA_NODE_TAGS.CONTACT);
252
+ if (!lidNode) {
253
+ parsed.push(this.buildLidSyncResult(normalizedUserJid, normalizedPhoneJid, contactNode, null));
254
+ continue;
255
+ }
256
+ const errorNode = findNodeChild(lidNode, WA_NODE_TAGS.ERROR);
257
+ if (errorNode) {
258
+ this.logger.warn('signal lid sync user error', {
130
259
  jid: normalizedUserJid,
131
- deviceJids: this.parseUserDeviceJids(userNode, normalizedUserJid)
132
- }
133
- ];
134
- });
260
+ code: errorNode.attrs.code,
261
+ text: errorNode.attrs.text
262
+ });
263
+ parsed.push(this.buildLidSyncResult(normalizedUserJid, normalizedPhoneJid, contactNode, null));
264
+ continue;
265
+ }
266
+ const lidJid = lidNode.attrs.val ? this.normalizeUserJid(lidNode.attrs.val) : null;
267
+ parsed.push(this.buildLidSyncResult(normalizedUserJid, normalizedPhoneJid, contactNode, lidJid));
268
+ }
269
+ return parsed;
270
+ }
271
+ buildLidSyncResult(jid, phoneJid, contactNode, lidJid) {
272
+ return {
273
+ jid,
274
+ lidJid,
275
+ phoneJid,
276
+ exists: this.parseLidSyncContactExists(contactNode, jid, lidJid !== null)
277
+ };
278
+ }
279
+ parseLidSyncContactExists(contactNode, userJid, defaultExists) {
280
+ if (!contactNode) {
281
+ return defaultExists;
282
+ }
283
+ const errorNode = findNodeChild(contactNode, WA_NODE_TAGS.ERROR);
284
+ if (errorNode) {
285
+ this.logger.warn('signal lid sync contact error', {
286
+ jid: userJid,
287
+ code: errorNode.attrs.code,
288
+ text: errorNode.attrs.text
289
+ });
290
+ return false;
291
+ }
292
+ return contactNode.attrs.type === 'in';
135
293
  }
136
294
  parseUserDeviceJids(userNode, userJid) {
137
295
  const devicesNode = findNodeChild(userNode, WA_NODE_TAGS.DEVICES);
@@ -151,35 +309,44 @@ export class SignalDeviceSyncApi {
151
309
  if (!deviceListNode) {
152
310
  return [];
153
311
  }
154
- return [
155
- ...new Set(getNodeChildrenByTag(deviceListNode, 'device')
156
- .map((deviceNode) => {
157
- const parsedId = deviceNode.attrs.id
158
- ? Number.parseInt(deviceNode.attrs.id, 10)
159
- : Number.NaN;
160
- return Number.isSafeInteger(parsedId) && parsedId >= 0
161
- ? this.toDeviceJid(userJid, parsedId)
162
- : null;
163
- })
164
- .filter((jid) => jid !== null))
165
- ];
312
+ const parsedUser = splitJid(userJid);
313
+ const dedup = new Set();
314
+ for (const deviceNode of getNodeChildrenByTag(deviceListNode, 'device')) {
315
+ const parsedId = deviceNode.attrs.id
316
+ ? Number.parseInt(deviceNode.attrs.id, 10)
317
+ : Number.NaN;
318
+ if (!Number.isSafeInteger(parsedId) || parsedId < 0) {
319
+ continue;
320
+ }
321
+ dedup.add(this.toDeviceJid(parsedUser.user, parsedUser.server, parsedId));
322
+ }
323
+ const deviceJids = [];
324
+ for (const jid of dedup.values()) {
325
+ deviceJids.push(jid);
326
+ }
327
+ return deviceJids;
166
328
  }
167
329
  normalizeUsers(userJids) {
168
- return [...new Set(userJids.map((jid) => this.normalizeUserJid(jid)))];
330
+ const normalized = [];
331
+ const dedup = new Set();
332
+ for (let index = 0; index < userJids.length; index += 1) {
333
+ const normalizedJid = this.normalizeUserJid(userJids[index]);
334
+ if (dedup.has(normalizedJid)) {
335
+ continue;
336
+ }
337
+ dedup.add(normalizedJid);
338
+ normalized.push(normalizedJid);
339
+ }
340
+ return normalized;
169
341
  }
170
342
  normalizeUserJid(jid) {
171
- const { user } = parseSignalAddressFromJid(jid);
172
- const { server } = splitJid(jid);
173
- return `${user}@${server}`;
343
+ const address = parseSignalAddressFromJid(jid);
344
+ return `${address.user}@${address.server}`;
174
345
  }
175
- toDeviceJid(userJid, deviceId) {
176
- const parsed = splitJid(userJid);
346
+ toDeviceJid(user, server, deviceId) {
177
347
  if (deviceId === 0) {
178
- return `${parsed.user}@${parsed.server}`;
348
+ return `${user}@${server}`;
179
349
  }
180
- return `${parsed.user}:${deviceId}@${parsed.server}`;
181
- }
182
- makeSid() {
183
- return `${Date.now()}.${randomInt(1000000)}`;
350
+ return `${user}:${deviceId}@${server}`;
184
351
  }
185
352
  }
@@ -161,7 +161,12 @@ export class SignalDigestSyncApi {
161
161
  const signedKeyId = parseUint(decodeExactLength(signedKeyIdNode.content, 'signal digest skey.id', SIGNAL_KEY_ID_LENGTH), 'signal digest skey.id');
162
162
  const signedKeyPublicKey = decodeExactLength(signedKeyValueNode.content, 'signal digest skey.value', SIGNAL_KEY_DATA_LENGTH);
163
163
  const signedKeySignature = decodeExactLength(signedKeySignatureNode.content, 'signal digest skey.signature', SIGNAL_SIGNATURE_LENGTH);
164
- const preKeyIds = getNodeChildren(listNode).map((child, index) => parseUint(decodeExactLength(child.content, `signal digest list[${index}]`, SIGNAL_KEY_ID_LENGTH), `signal digest list[${index}]`));
164
+ const preKeyIds = [];
165
+ const listChildren = getNodeChildren(listNode);
166
+ for (let index = 0; index < listChildren.length; index += 1) {
167
+ const child = listChildren[index];
168
+ preKeyIds.push(parseUint(decodeExactLength(child.content, `signal digest list[${index}]`, SIGNAL_KEY_ID_LENGTH), `signal digest list[${index}]`));
169
+ }
165
170
  const hash = decodeNodeContentBase64OrBytes(hashNode.content, 'signal digest hash');
166
171
  return {
167
172
  registrationId,
@@ -4,6 +4,7 @@ import { normalizeDeviceJid, parseSignalAddressFromJid } from '../../protocol/ji
4
4
  import { decodeExactLength, parseUint } from '../api/codec.js';
5
5
  import { SIGNAL_KEY_BUNDLE_TYPE_LENGTH, SIGNAL_KEY_DATA_LENGTH } from '../api/constants.js';
6
6
  import { findNodeChild, getNodeChildrenByTag } from '../../transport/node/helpers.js';
7
+ import { assertIqResult } from '../../transport/node/query.js';
7
8
  export class SignalIdentitySyncApi {
8
9
  constructor(options) {
9
10
  this.logger = options.logger;
@@ -14,10 +15,28 @@ export class SignalIdentitySyncApi {
14
15
  this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
15
16
  }
16
17
  async syncIdentityKeys(targetJids, timeoutMs = this.defaultTimeoutMs) {
17
- const normalizedTargets = [...new Set(targetJids.map((jid) => normalizeDeviceJid(jid)))];
18
+ const normalizedTargets = [];
19
+ const dedup = new Set();
20
+ for (let index = 0; index < targetJids.length; index += 1) {
21
+ const normalized = normalizeDeviceJid(targetJids[index]);
22
+ if (dedup.has(normalized)) {
23
+ continue;
24
+ }
25
+ dedup.add(normalized);
26
+ normalizedTargets.push(normalized);
27
+ }
18
28
  if (normalizedTargets.length === 0) {
19
29
  return [];
20
30
  }
31
+ const users = new Array(normalizedTargets.length);
32
+ for (let index = 0; index < normalizedTargets.length; index += 1) {
33
+ users[index] = {
34
+ tag: WA_NODE_TAGS.USER,
35
+ attrs: {
36
+ jid: normalizedTargets[index]
37
+ }
38
+ };
39
+ }
21
40
  this.logger.debug('signal identity sync request', {
22
41
  targets: normalizedTargets.length,
23
42
  timeoutMs
@@ -33,20 +52,22 @@ export class SignalIdentitySyncApi {
33
52
  {
34
53
  tag: WA_NODE_TAGS.IDENTITY,
35
54
  attrs: {},
36
- content: normalizedTargets.map((jid) => ({
37
- tag: WA_NODE_TAGS.USER,
38
- attrs: { jid }
39
- }))
55
+ content: users
40
56
  }
41
57
  ]
42
58
  }, timeoutMs);
43
59
  const entries = this.parseIdentitySyncResponse(response, normalizedTargets);
44
60
  const { signalStore } = this;
45
61
  if (signalStore && entries.length > 0) {
46
- await signalStore.setRemoteIdentities(entries.map((entry) => ({
47
- address: parseSignalAddressFromJid(entry.jid),
48
- identityKey: toSerializedPubKey(entry.identity)
49
- })));
62
+ const identities = new Array(entries.length);
63
+ for (let index = 0; index < entries.length; index += 1) {
64
+ const entry = entries[index];
65
+ identities[index] = {
66
+ address: parseSignalAddressFromJid(entry.jid),
67
+ identityKey: toSerializedPubKey(entry.identity)
68
+ };
69
+ }
70
+ await signalStore.setRemoteIdentities(identities);
50
71
  }
51
72
  this.logger.debug('signal identity sync success', {
52
73
  requested: normalizedTargets.length,
@@ -55,31 +76,19 @@ export class SignalIdentitySyncApi {
55
76
  return entries;
56
77
  }
57
78
  parseIdentitySyncResponse(node, requestedJids) {
58
- if (node.tag !== WA_NODE_TAGS.IQ) {
59
- throw new Error(`invalid identity sync response tag: ${node.tag}`);
60
- }
61
- if (node.attrs.type === WA_IQ_TYPES.ERROR) {
62
- const errorNode = findNodeChild(node, WA_NODE_TAGS.ERROR);
63
- if (!errorNode) {
64
- throw new Error(`identity sync iq error for ${node.attrs.id ?? 'unknown id'}`);
65
- }
66
- const code = errorNode.attrs.code ?? 'unknown';
67
- const text = errorNode.attrs.text ?? errorNode.attrs.type ?? 'unknown';
68
- throw new Error(`identity sync iq error (${code} ${text})`);
69
- }
70
- if (node.attrs.type !== WA_IQ_TYPES.RESULT) {
71
- throw new Error(`invalid identity sync response type: ${node.attrs.type ?? 'unknown'}`);
72
- }
79
+ assertIqResult(node, 'identity sync');
73
80
  const listNode = findNodeChild(node, WA_NODE_TAGS.LIST);
74
81
  if (!listNode) {
75
82
  throw new Error('identity sync response missing list node');
76
83
  }
77
84
  const requested = new Set(requestedJids);
78
85
  const userNodes = getNodeChildrenByTag(listNode, WA_NODE_TAGS.USER);
79
- return userNodes.flatMap((userNode) => {
86
+ const parsed = [];
87
+ for (let index = 0; index < userNodes.length; index += 1) {
88
+ const userNode = userNodes[index];
80
89
  const jid = userNode.attrs.jid ? normalizeDeviceJid(userNode.attrs.jid) : '';
81
90
  if (!jid || !requested.has(jid)) {
82
- return [];
91
+ continue;
83
92
  }
84
93
  const errorNode = findNodeChild(userNode, WA_NODE_TAGS.ERROR);
85
94
  if (errorNode) {
@@ -88,7 +97,7 @@ export class SignalIdentitySyncApi {
88
97
  code: errorNode.attrs.code,
89
98
  text: errorNode.attrs.text
90
99
  });
91
- return [];
100
+ continue;
92
101
  }
93
102
  const identityNode = findNodeChild(userNode, WA_NODE_TAGS.IDENTITY);
94
103
  if (!identityNode) {
@@ -99,13 +108,19 @@ export class SignalIdentitySyncApi {
99
108
  const parsedType = typeNode
100
109
  ? parseUint(decodeExactLength(typeNode.content, 'identity sync type', SIGNAL_KEY_BUNDLE_TYPE_LENGTH), 'identity sync type')
101
110
  : undefined;
102
- return [
103
- {
111
+ if (parsedType === undefined) {
112
+ parsed.push({
104
113
  jid,
105
- identity,
106
- ...(parsedType !== undefined ? { type: parsedType } : {})
107
- }
108
- ];
109
- });
114
+ identity
115
+ });
116
+ continue;
117
+ }
118
+ parsed.push({
119
+ jid,
120
+ identity,
121
+ type: parsedType
122
+ });
123
+ }
124
+ return parsed;
110
125
  }
111
126
  }