zapo-js 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. package/README.md +20 -4
  2. package/dist/appstate/WaAppStateCrypto.js +19 -26
  3. package/dist/appstate/WaAppStateSyncClient.js +293 -181
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  7. package/dist/appstate/index.js +8 -6
  8. package/dist/appstate/utils.js +9 -34
  9. package/dist/auth/WaAuthClient.js +43 -61
  10. package/dist/auth/flow/WaAuthCredentialsFlow.js +22 -15
  11. package/dist/auth/index.js +1 -8
  12. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  13. package/dist/auth/pairing/WaPairingFlow.js +34 -26
  14. package/dist/auth/pairing/WaQrFlow.js +37 -24
  15. package/dist/client/WaClient.js +275 -324
  16. package/dist/client/WaClientFactory.js +500 -133
  17. package/dist/client/connection/WaConnectionManager.js +301 -0
  18. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  19. package/dist/client/connection/WaReceiptQueue.js +51 -0
  20. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  21. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  22. package/dist/client/coordinators/WaGroupCoordinator.js +30 -16
  23. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  24. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +439 -701
  25. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  26. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  27. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  28. package/dist/client/coordinators/WaRetryCoordinator.js +242 -57
  29. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  30. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  31. package/dist/client/dirty.js +74 -48
  32. package/dist/client/events/chat.js +4 -3
  33. package/dist/client/events/devices.js +72 -0
  34. package/dist/client/events/group.js +62 -47
  35. package/dist/client/events/identity.js +22 -0
  36. package/dist/client/events/privacy-token.js +39 -0
  37. package/dist/client/history-sync.js +94 -63
  38. package/dist/client/incoming.js +60 -27
  39. package/dist/client/mailbox.js +24 -23
  40. package/dist/client/messages.js +107 -31
  41. package/dist/client/messaging/fanout.js +199 -0
  42. package/dist/client/messaging/key-protocol.js +130 -0
  43. package/dist/client/messaging/participants.js +193 -0
  44. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  45. package/dist/client/tokens/cs-token.js +50 -0
  46. package/dist/client/tokens/tc-token.js +25 -0
  47. package/dist/crypto/core/hkdf.js +3 -8
  48. package/dist/crypto/core/index.js +2 -5
  49. package/dist/crypto/core/keys.js +6 -7
  50. package/dist/crypto/core/nonce.js +2 -0
  51. package/dist/crypto/core/primitives.js +12 -23
  52. package/dist/crypto/core/random.js +26 -23
  53. package/dist/crypto/curves/Ed25519.js +7 -8
  54. package/dist/crypto/curves/X25519.js +38 -22
  55. package/dist/crypto/index.js +1 -3
  56. package/dist/crypto/math/constants.js +13 -36
  57. package/dist/crypto/math/edwards.js +171 -44
  58. package/dist/crypto/math/fe.js +706 -0
  59. package/dist/crypto/math/mod.js +10 -3
  60. package/dist/esm/appstate/WaAppStateCrypto.js +7 -14
  61. package/dist/esm/appstate/WaAppStateSyncClient.js +284 -172
  62. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  63. package/dist/esm/appstate/constants.js +3 -2
  64. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  65. package/dist/esm/appstate/index.js +2 -2
  66. package/dist/esm/appstate/utils.js +8 -30
  67. package/dist/esm/auth/WaAuthClient.js +43 -61
  68. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +22 -15
  69. package/dist/esm/auth/index.js +0 -3
  70. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  71. package/dist/esm/auth/pairing/WaPairingFlow.js +28 -20
  72. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  73. package/dist/esm/client/WaClient.js +275 -324
  74. package/dist/esm/client/WaClientFactory.js +501 -134
  75. package/dist/esm/client/connection/WaConnectionManager.js +297 -0
  76. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  77. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  78. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  79. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  80. package/dist/esm/client/coordinators/WaGroupCoordinator.js +23 -9
  81. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  82. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +443 -705
  83. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  84. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  85. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  86. package/dist/esm/client/coordinators/WaRetryCoordinator.js +244 -59
  87. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  88. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  89. package/dist/esm/client/dirty.js +69 -43
  90. package/dist/esm/client/events/chat.js +4 -3
  91. package/dist/esm/client/events/devices.js +68 -0
  92. package/dist/esm/client/events/group.js +53 -39
  93. package/dist/esm/client/events/identity.js +19 -0
  94. package/dist/esm/client/events/privacy-token.js +36 -0
  95. package/dist/esm/client/history-sync.js +91 -60
  96. package/dist/esm/client/incoming.js +61 -28
  97. package/dist/esm/client/mailbox.js +24 -23
  98. package/dist/esm/client/messages.js +108 -32
  99. package/dist/esm/client/messaging/fanout.js +196 -0
  100. package/dist/esm/client/messaging/key-protocol.js +127 -0
  101. package/dist/esm/client/messaging/participants.js +190 -0
  102. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  103. package/dist/esm/client/tokens/cs-token.js +46 -0
  104. package/dist/esm/client/tokens/tc-token.js +18 -0
  105. package/dist/esm/crypto/core/hkdf.js +3 -8
  106. package/dist/esm/crypto/core/index.js +2 -3
  107. package/dist/esm/crypto/core/keys.js +3 -4
  108. package/dist/esm/crypto/core/nonce.js +2 -0
  109. package/dist/esm/crypto/core/primitives.js +12 -22
  110. package/dist/esm/crypto/core/random.js +25 -23
  111. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  112. package/dist/esm/crypto/curves/X25519.js +35 -19
  113. package/dist/esm/crypto/index.js +0 -1
  114. package/dist/esm/crypto/math/constants.js +12 -35
  115. package/dist/esm/crypto/math/edwards.js +174 -47
  116. package/dist/esm/crypto/math/fe.js +691 -0
  117. package/dist/esm/crypto/math/mod.js +10 -1
  118. package/dist/esm/index.js +1 -1
  119. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  120. package/dist/esm/infra/log/PinoLogger.js +15 -9
  121. package/dist/esm/infra/log/types.js +11 -1
  122. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  123. package/dist/esm/infra/perf/BoundedTaskQueue.js +16 -18
  124. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  125. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  126. package/dist/esm/infra/perf/StoreLock.js +77 -0
  127. package/dist/esm/media/WaMediaCrypto.js +96 -16
  128. package/dist/esm/media/WaMediaTransferClient.js +251 -91
  129. package/dist/esm/media/conn.js +10 -6
  130. package/dist/esm/media/constants.js +6 -2
  131. package/dist/esm/message/WaMessageClient.js +30 -32
  132. package/dist/esm/message/ack.js +6 -6
  133. package/dist/esm/message/addon-crypto.js +59 -0
  134. package/dist/esm/message/content.js +195 -9
  135. package/dist/esm/message/icdc.js +76 -0
  136. package/dist/esm/message/incoming.js +129 -122
  137. package/dist/esm/message/index.js +2 -0
  138. package/dist/esm/message/phash.js +3 -1
  139. package/dist/esm/message/reporting-token.js +425 -0
  140. package/dist/esm/message/use-case-secret.js +49 -0
  141. package/dist/esm/protocol/appstate.js +27 -0
  142. package/dist/esm/protocol/browser.js +10 -18
  143. package/dist/esm/protocol/constants.js +6 -3
  144. package/dist/esm/protocol/defaults.js +6 -0
  145. package/dist/esm/protocol/index.js +2 -11
  146. package/dist/esm/protocol/jid.js +133 -52
  147. package/dist/esm/protocol/media.js +3 -3
  148. package/dist/esm/protocol/message.js +61 -1
  149. package/dist/esm/protocol/nodes.js +4 -0
  150. package/dist/esm/protocol/notification.js +3 -1
  151. package/dist/esm/protocol/privacy-token.js +17 -0
  152. package/dist/esm/protocol/privacy.js +55 -0
  153. package/dist/esm/protocol/stream.js +26 -1
  154. package/dist/esm/protocol/usync.js +11 -0
  155. package/dist/esm/retry/codec.js +216 -0
  156. package/dist/esm/retry/constants.js +1 -1
  157. package/dist/esm/retry/index.js +3 -2
  158. package/dist/esm/retry/parse.js +88 -86
  159. package/dist/esm/retry/replay.js +54 -51
  160. package/dist/esm/retry/tracker.js +94 -0
  161. package/dist/esm/signal/api/SignalDeviceSyncApi.js +276 -92
  162. package/dist/esm/signal/api/SignalDigestSyncApi.js +17 -8
  163. package/dist/esm/signal/api/SignalIdentitySyncApi.js +67 -37
  164. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +86 -67
  165. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  166. package/dist/esm/signal/api/SignalSessionSyncApi.js +36 -34
  167. package/dist/esm/signal/api/result-map.js +10 -0
  168. package/dist/esm/signal/constants.js +0 -4
  169. package/dist/esm/signal/crypto/WaAdvSignature.js +13 -9
  170. package/dist/esm/signal/{store/sqlite.js → encoding.js} +93 -60
  171. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  172. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  173. package/dist/esm/signal/group/SenderKeyManager.js +144 -115
  174. package/dist/esm/signal/index.js +2 -0
  175. package/dist/esm/signal/registration/keygen.js +6 -2
  176. package/dist/esm/signal/registration/utils.js +1 -0
  177. package/dist/esm/signal/session/SignalProtocol.js +164 -53
  178. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  179. package/dist/esm/signal/session/SignalSession.js +14 -9
  180. package/dist/esm/signal/session/resolver.js +221 -0
  181. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  182. package/dist/esm/store/createStore.js +100 -188
  183. package/dist/esm/store/index.js +1 -10
  184. package/dist/esm/store/locks/appstate.lock.js +26 -0
  185. package/dist/esm/store/locks/auth.lock.js +15 -0
  186. package/dist/esm/store/locks/contact.lock.js +20 -0
  187. package/dist/esm/store/locks/device-list.lock.js +20 -0
  188. package/dist/esm/store/locks/message.lock.js +21 -0
  189. package/dist/esm/store/locks/participants.lock.js +20 -0
  190. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  191. package/dist/esm/store/locks/retry.lock.js +29 -0
  192. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  193. package/dist/esm/store/locks/signal.lock.js +63 -0
  194. package/dist/esm/store/locks/thread.lock.js +21 -0
  195. package/dist/esm/store/noop.store.js +4 -7
  196. package/dist/esm/store/providers/memory/appstate.store.js +38 -16
  197. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  198. package/dist/esm/store/providers/memory/device-list.store.js +12 -34
  199. package/dist/esm/store/providers/memory/message.store.js +11 -5
  200. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  201. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  202. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  203. package/dist/esm/store/providers/memory/sender-key.store.js +11 -8
  204. package/dist/esm/store/providers/memory/signal.store.js +47 -18
  205. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  206. package/dist/esm/transport/WaComms.js +28 -24
  207. package/dist/esm/transport/WaWebSocket.js +115 -18
  208. package/dist/esm/transport/binary/constants.js +0 -30
  209. package/dist/esm/transport/binary/decoder.js +8 -8
  210. package/dist/esm/transport/binary/encoder.js +10 -9
  211. package/dist/esm/transport/binary/index.js +0 -1
  212. package/dist/esm/transport/index.js +1 -0
  213. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  214. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -21
  215. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  216. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  217. package/dist/esm/transport/node/builders/business.js +129 -0
  218. package/dist/esm/transport/node/builders/global.js +370 -0
  219. package/dist/esm/transport/node/builders/index.js +7 -3
  220. package/dist/esm/transport/node/builders/message.js +63 -230
  221. package/dist/esm/transport/node/builders/pairing.js +2 -27
  222. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  223. package/dist/esm/transport/node/builders/privacy.js +48 -0
  224. package/dist/esm/transport/node/builders/profile.js +70 -0
  225. package/dist/esm/transport/node/builders/retry.js +10 -22
  226. package/dist/esm/transport/node/builders/usync.js +45 -0
  227. package/dist/esm/transport/node/helpers.js +125 -5
  228. package/dist/esm/transport/node/usync.js +5 -0
  229. package/dist/esm/transport/node/xml.js +35 -14
  230. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  231. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  232. package/dist/esm/transport/noise/WaNoiseCert.js +4 -7
  233. package/dist/esm/transport/noise/WaNoiseSession.js +77 -29
  234. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  235. package/dist/esm/transport/proxy.js +27 -0
  236. package/dist/esm/transport/stream/parse.js +17 -48
  237. package/dist/esm/util/bytes.js +67 -45
  238. package/dist/esm/util/coercion.js +6 -14
  239. package/dist/esm/util/index.js +5 -0
  240. package/dist/esm/util/primitives.js +40 -14
  241. package/dist/index.js +7 -1
  242. package/dist/infra/log/ConsoleLogger.js +18 -17
  243. package/dist/infra/log/PinoLogger.js +15 -9
  244. package/dist/infra/log/types.js +12 -0
  245. package/dist/infra/perf/BackgroundQueue.js +482 -0
  246. package/dist/infra/perf/BoundedTaskQueue.js +16 -18
  247. package/dist/infra/perf/PromiseDedup.js +24 -0
  248. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  249. package/dist/infra/perf/StoreLock.js +81 -0
  250. package/dist/media/WaMediaCrypto.js +95 -15
  251. package/dist/media/WaMediaTransferClient.js +284 -91
  252. package/dist/media/conn.js +10 -6
  253. package/dist/media/constants.js +6 -2
  254. package/dist/message/WaMessageClient.js +31 -33
  255. package/dist/message/ack.js +6 -6
  256. package/dist/message/addon-crypto.js +65 -0
  257. package/dist/message/content.js +198 -9
  258. package/dist/message/icdc.js +81 -0
  259. package/dist/message/incoming.js +127 -120
  260. package/dist/message/index.js +2 -0
  261. package/dist/message/phash.js +3 -1
  262. package/dist/message/reporting-token.js +429 -0
  263. package/dist/message/use-case-secret.js +55 -0
  264. package/dist/protocol/appstate.js +28 -1
  265. package/dist/protocol/browser.js +10 -18
  266. package/dist/protocol/constants.js +26 -1
  267. package/dist/protocol/defaults.js +6 -0
  268. package/dist/protocol/index.js +23 -42
  269. package/dist/protocol/jid.js +140 -52
  270. package/dist/protocol/media.js +3 -3
  271. package/dist/protocol/message.js +62 -2
  272. package/dist/protocol/nodes.js +4 -0
  273. package/dist/protocol/notification.js +3 -1
  274. package/dist/protocol/privacy-token.js +20 -0
  275. package/dist/protocol/privacy.js +58 -0
  276. package/dist/protocol/stream.js +27 -2
  277. package/dist/protocol/usync.js +14 -0
  278. package/dist/retry/codec.js +220 -0
  279. package/dist/retry/constants.js +1 -1
  280. package/dist/retry/index.js +7 -5
  281. package/dist/retry/parse.js +88 -85
  282. package/dist/retry/replay.js +52 -49
  283. package/dist/retry/tracker.js +97 -0
  284. package/dist/signal/api/SignalDeviceSyncApi.js +273 -89
  285. package/dist/signal/api/SignalDigestSyncApi.js +17 -8
  286. package/dist/signal/api/SignalIdentitySyncApi.js +66 -36
  287. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +82 -63
  288. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  289. package/dist/signal/api/SignalSessionSyncApi.js +36 -34
  290. package/dist/signal/api/result-map.js +13 -0
  291. package/dist/signal/constants.js +1 -5
  292. package/dist/signal/crypto/WaAdvSignature.js +11 -7
  293. package/dist/signal/{store/sqlite.js → encoding.js} +94 -61
  294. package/dist/signal/group/SenderKeyChain.js +27 -22
  295. package/dist/signal/group/SenderKeyCodec.js +5 -6
  296. package/dist/signal/group/SenderKeyManager.js +144 -115
  297. package/dist/signal/index.js +15 -1
  298. package/dist/signal/registration/keygen.js +6 -2
  299. package/dist/signal/registration/utils.js +1 -0
  300. package/dist/signal/session/SignalProtocol.js +164 -53
  301. package/dist/signal/session/SignalRatchet.js +24 -15
  302. package/dist/signal/session/SignalSession.js +14 -9
  303. package/dist/signal/session/resolver.js +224 -0
  304. package/dist/store/contracts/privacy-token.store.js +2 -0
  305. package/dist/store/createStore.js +100 -188
  306. package/dist/store/index.js +15 -33
  307. package/dist/store/locks/appstate.lock.js +29 -0
  308. package/dist/store/locks/auth.lock.js +18 -0
  309. package/dist/store/locks/contact.lock.js +23 -0
  310. package/dist/store/locks/device-list.lock.js +23 -0
  311. package/dist/store/locks/message.lock.js +24 -0
  312. package/dist/store/locks/participants.lock.js +23 -0
  313. package/dist/store/locks/privacy-token.lock.js +21 -0
  314. package/dist/store/locks/retry.lock.js +32 -0
  315. package/dist/store/locks/sender-key.lock.js +55 -0
  316. package/dist/store/locks/signal.lock.js +66 -0
  317. package/dist/store/locks/thread.lock.js +24 -0
  318. package/dist/store/noop.store.js +4 -7
  319. package/dist/store/providers/memory/appstate.store.js +36 -14
  320. package/dist/store/providers/memory/contact.store.js +5 -0
  321. package/dist/store/providers/memory/device-list.store.js +12 -34
  322. package/dist/store/providers/memory/message.store.js +11 -5
  323. package/dist/store/providers/memory/participants.store.js +1 -8
  324. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  325. package/dist/store/providers/memory/retry.store.js +77 -2
  326. package/dist/store/providers/memory/sender-key.store.js +14 -11
  327. package/dist/store/providers/memory/signal.store.js +54 -25
  328. package/dist/store/providers/memory/thread.store.js +5 -0
  329. package/dist/transport/WaComms.js +30 -26
  330. package/dist/transport/WaWebSocket.js +148 -18
  331. package/dist/transport/binary/constants.js +1 -31
  332. package/dist/transport/binary/decoder.js +8 -8
  333. package/dist/transport/binary/encoder.js +10 -9
  334. package/dist/transport/binary/index.js +0 -4
  335. package/dist/transport/index.js +7 -1
  336. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  337. package/dist/transport/node/WaNodeOrchestrator.js +25 -21
  338. package/dist/transport/node/WaNodeTransport.js +0 -3
  339. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  340. package/dist/transport/node/builders/business.js +137 -0
  341. package/dist/transport/node/builders/global.js +375 -0
  342. package/dist/transport/node/builders/index.js +29 -17
  343. package/dist/transport/node/builders/message.js +64 -236
  344. package/dist/transport/node/builders/pairing.js +2 -29
  345. package/dist/transport/node/builders/privacy-token.js +46 -0
  346. package/dist/transport/node/builders/privacy.js +55 -0
  347. package/dist/transport/node/builders/profile.js +78 -0
  348. package/dist/transport/node/builders/retry.js +9 -21
  349. package/dist/transport/node/builders/usync.js +49 -0
  350. package/dist/transport/node/helpers.js +131 -4
  351. package/dist/transport/node/usync.js +8 -0
  352. package/dist/transport/node/xml.js +35 -14
  353. package/dist/transport/noise/WaClientPayload.js +13 -13
  354. package/dist/transport/noise/WaFrameCodec.js +47 -32
  355. package/dist/transport/noise/WaNoiseCert.js +5 -8
  356. package/dist/transport/noise/WaNoiseSession.js +77 -29
  357. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  358. package/dist/transport/proxy.js +34 -0
  359. package/dist/transport/stream/parse.js +20 -52
  360. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  361. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  362. package/dist/types/appstate/constants.d.ts +1 -0
  363. package/dist/types/appstate/encoding.d.ts +7 -0
  364. package/dist/types/appstate/index.d.ts +3 -3
  365. package/dist/types/appstate/utils.d.ts +0 -3
  366. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  367. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  368. package/dist/types/auth/index.d.ts +0 -4
  369. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  370. package/dist/types/auth/types.d.ts +7 -9
  371. package/dist/types/client/WaClient.d.ts +42 -25
  372. package/dist/types/client/WaClientFactory.d.ts +33 -26
  373. package/dist/types/client/connection/WaConnectionManager.d.ts +66 -0
  374. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  375. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  376. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  377. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  378. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -2
  379. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -38
  380. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  381. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  382. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  383. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +8 -0
  384. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  385. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  386. package/dist/types/client/dirty.d.ts +1 -0
  387. package/dist/types/client/events/devices.d.ts +20 -0
  388. package/dist/types/client/events/group.d.ts +2 -1
  389. package/dist/types/client/events/identity.d.ts +9 -0
  390. package/dist/types/client/events/privacy-token.d.ts +7 -0
  391. package/dist/types/client/history-sync.d.ts +9 -6
  392. package/dist/types/client/incoming.d.ts +3 -1
  393. package/dist/types/client/index.d.ts +1 -1
  394. package/dist/types/client/mailbox.d.ts +3 -5
  395. package/dist/types/client/messages.d.ts +1 -2
  396. package/dist/types/client/messaging/fanout.d.ts +14 -0
  397. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  398. package/dist/types/client/messaging/participants.d.ts +13 -0
  399. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  400. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  401. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  402. package/dist/types/client/types.d.ts +75 -4
  403. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  404. package/dist/types/crypto/core/index.d.ts +2 -3
  405. package/dist/types/crypto/core/nonce.d.ts +2 -0
  406. package/dist/types/crypto/core/primitives.d.ts +0 -1
  407. package/dist/types/crypto/core/random.d.ts +2 -7
  408. package/dist/types/crypto/index.d.ts +0 -1
  409. package/dist/types/crypto/math/constants.d.ts +4 -2
  410. package/dist/types/crypto/math/fe.d.ts +30 -0
  411. package/dist/types/crypto/math/mod.d.ts +0 -2
  412. package/dist/types/crypto/math/types.d.ts +11 -4
  413. package/dist/types/index.d.ts +5 -3
  414. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  415. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  416. package/dist/types/infra/log/types.d.ts +1 -0
  417. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  418. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  419. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  420. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  421. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  422. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  423. package/dist/types/media/WaMediaTransferClient.d.ts +16 -15
  424. package/dist/types/media/constants.d.ts +1 -1
  425. package/dist/types/media/index.d.ts +1 -1
  426. package/dist/types/media/types.d.ts +15 -2
  427. package/dist/types/message/addon-crypto.d.ts +25 -0
  428. package/dist/types/message/content.d.ts +8 -0
  429. package/dist/types/message/icdc.d.ts +13 -0
  430. package/dist/types/message/index.d.ts +2 -0
  431. package/dist/types/message/reporting-token.d.ts +18 -0
  432. package/dist/types/message/types.d.ts +45 -6
  433. package/dist/types/message/use-case-secret.d.ts +20 -0
  434. package/dist/types/protocol/appstate.d.ts +47 -0
  435. package/dist/types/protocol/constants.d.ts +8 -3
  436. package/dist/types/protocol/defaults.d.ts +6 -0
  437. package/dist/types/protocol/index.d.ts +2 -11
  438. package/dist/types/protocol/jid.d.ts +22 -5
  439. package/dist/types/protocol/message.d.ts +60 -0
  440. package/dist/types/protocol/nodes.d.ts +4 -0
  441. package/dist/types/protocol/notification.d.ts +2 -0
  442. package/dist/types/protocol/privacy-token.d.ts +17 -0
  443. package/dist/types/protocol/privacy.d.ts +75 -0
  444. package/dist/types/protocol/stream.d.ts +30 -0
  445. package/dist/types/protocol/usync.d.ts +11 -0
  446. package/dist/types/retry/codec.d.ts +3 -0
  447. package/dist/types/retry/index.d.ts +4 -3
  448. package/dist/types/retry/parse.d.ts +5 -2
  449. package/dist/types/retry/replay.d.ts +0 -4
  450. package/dist/types/retry/tracker.d.ts +20 -0
  451. package/dist/types/retry/types.d.ts +10 -4
  452. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +15 -2
  453. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  454. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  455. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  456. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  457. package/dist/types/signal/api/result-map.d.ts +1 -0
  458. package/dist/types/signal/constants.d.ts +0 -3
  459. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  460. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  461. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  462. package/dist/types/signal/index.d.ts +3 -0
  463. package/dist/types/signal/session/SignalProtocol.d.ts +19 -4
  464. package/dist/types/signal/session/resolver.d.ts +22 -0
  465. package/dist/types/store/contracts/appstate.store.d.ts +4 -1
  466. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  467. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  468. package/dist/types/store/contracts/message.store.d.ts +1 -0
  469. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  470. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  471. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  472. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  473. package/dist/types/store/contracts/signal.store.d.ts +13 -0
  474. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  475. package/dist/types/store/createStore.d.ts +1 -1
  476. package/dist/types/store/index.d.ts +5 -13
  477. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  478. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  479. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  480. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  481. package/dist/types/store/locks/message.lock.d.ts +3 -0
  482. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  483. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  484. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  485. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  486. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  487. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  488. package/dist/types/store/providers/memory/appstate.store.d.ts +3 -1
  489. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  490. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  491. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  492. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  493. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  494. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  495. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  496. package/dist/types/store/providers/memory/signal.store.d.ts +8 -1
  497. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  498. package/dist/types/store/types.d.ts +49 -58
  499. package/dist/types/transport/WaWebSocket.d.ts +3 -1
  500. package/dist/types/transport/binary/constants.d.ts +0 -30
  501. package/dist/types/transport/binary/index.d.ts +0 -1
  502. package/dist/types/transport/index.d.ts +2 -1
  503. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  504. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  505. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  506. package/dist/types/transport/node/builders/business.d.ts +29 -0
  507. package/dist/types/transport/node/builders/global.d.ts +102 -0
  508. package/dist/types/transport/node/builders/group.d.ts +4 -6
  509. package/dist/types/transport/node/builders/index.d.ts +7 -3
  510. package/dist/types/transport/node/builders/message.d.ts +20 -30
  511. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  512. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  513. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  514. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  515. package/dist/types/transport/node/builders/retry.d.ts +2 -5
  516. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  517. package/dist/types/transport/node/helpers.d.ts +13 -0
  518. package/dist/types/transport/node/usync.d.ts +2 -0
  519. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  520. package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
  521. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  522. package/dist/types/transport/proxy.d.ts +6 -0
  523. package/dist/types/transport/stream/parse.d.ts +0 -1
  524. package/dist/types/transport/types.d.ts +18 -1
  525. package/dist/types/util/bytes.d.ts +5 -0
  526. package/dist/types/util/index.d.ts +5 -0
  527. package/dist/types/util/primitives.d.ts +2 -0
  528. package/dist/util/bytes.js +72 -46
  529. package/dist/util/coercion.js +6 -14
  530. package/dist/util/index.js +23 -0
  531. package/dist/util/primitives.js +42 -14
  532. package/package.json +52 -9
  533. package/proto/index.js +1 -1
  534. package/dist/crypto/core/constants.js +0 -4
  535. package/dist/crypto/core/encoding.js +0 -29
  536. package/dist/esm/crypto/core/constants.js +0 -1
  537. package/dist/esm/crypto/core/encoding.js +0 -25
  538. package/dist/esm/retry/outbound.js +0 -83
  539. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  540. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -169
  541. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  542. package/dist/esm/store/providers/sqlite/connection.js +0 -240
  543. package/dist/esm/store/providers/sqlite/contact.store.js +0 -61
  544. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -155
  545. package/dist/esm/store/providers/sqlite/message.store.js +0 -119
  546. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  547. package/dist/esm/store/providers/sqlite/participants.store.js +0 -85
  548. package/dist/esm/store/providers/sqlite/retry.store.js +0 -144
  549. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -203
  550. package/dist/esm/store/providers/sqlite/signal.store.js +0 -353
  551. package/dist/esm/store/providers/sqlite/thread.store.js +0 -72
  552. package/dist/esm/util/base64.js +0 -18
  553. package/dist/esm/util/signal-address.js +0 -5
  554. package/dist/retry/outbound.js +0 -88
  555. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  556. package/dist/store/providers/sqlite/appstate.store.js +0 -173
  557. package/dist/store/providers/sqlite/auth.store.js +0 -180
  558. package/dist/store/providers/sqlite/connection.js +0 -276
  559. package/dist/store/providers/sqlite/contact.store.js +0 -65
  560. package/dist/store/providers/sqlite/device-list.store.js +0 -159
  561. package/dist/store/providers/sqlite/message.store.js +0 -123
  562. package/dist/store/providers/sqlite/migrations.js +0 -350
  563. package/dist/store/providers/sqlite/participants.store.js +0 -89
  564. package/dist/store/providers/sqlite/retry.store.js +0 -148
  565. package/dist/store/providers/sqlite/sender-key.store.js +0 -207
  566. package/dist/store/providers/sqlite/signal.store.js +0 -357
  567. package/dist/store/providers/sqlite/thread.store.js +0 -76
  568. package/dist/types/appstate/store/sqlite.d.ts +0 -21
  569. package/dist/types/crypto/core/constants.d.ts +0 -1
  570. package/dist/types/crypto/core/encoding.d.ts +0 -11
  571. package/dist/types/retry/outbound.d.ts +0 -4
  572. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  573. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -15
  574. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  575. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  576. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -10
  577. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -18
  578. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -11
  579. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  580. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -13
  581. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -16
  582. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -25
  583. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -46
  584. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -11
  585. package/dist/types/util/base64.d.ts +0 -4
  586. package/dist/types/util/signal-address.d.ts +0 -2
  587. package/dist/util/base64.js +0 -24
  588. package/dist/util/signal-address.js +0 -8
  589. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -2,8 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SenderKeyManager = void 0;
4
4
  const _crypto_1 = require("../../crypto/index.js");
5
+ const StoreLock_1 = require("../../infra/perf/StoreLock");
5
6
  const _proto_1 = require("../../proto.js");
6
- const constants_1 = require("../constants");
7
+ const jid_1 = require("../../protocol/jid");
8
+ const constants_1 = require("../api/constants");
9
+ const constants_2 = require("../constants");
7
10
  const WaAdvSignature_1 = require("../crypto/WaAdvSignature");
8
11
  const SenderKeyChain_1 = require("../group/SenderKeyChain");
9
12
  const SenderKeyCodec_1 = require("../group/SenderKeyCodec");
@@ -27,148 +30,171 @@ async function aesCbcDecryptFromSeed(seed, ciphertext) {
27
30
  }
28
31
  class SenderKeyManager {
29
32
  constructor(store) {
33
+ this.senderLock = new StoreLock_1.StoreLock();
30
34
  this.store = store;
31
35
  }
32
- async createSenderKeyDistributionMessage(groupId, sender) {
33
- const senderKey = await this.ensureSenderKey(groupId, sender);
34
- const distributionProto = _proto_1.proto.SenderKeyDistributionMessage.encode({
35
- id: senderKey.keyId,
36
- iteration: senderKey.iteration,
37
- chainKey: senderKey.chainKey,
38
- signingKey: senderKey.signingPublicKey
39
- }).finish();
40
- const payload = (0, _crypto_1.prependVersion)(distributionProto, constants_1.SIGNAL_GROUP_VERSION);
41
- await this.store.upsertSenderKeyDistribution({
42
- groupId,
43
- sender,
44
- keyId: senderKey.keyId,
45
- timestampMs: Date.now()
36
+ async prepareGroupEncryption(groupId, sender, plaintext) {
37
+ return this.runWithSenderLock(groupId, sender, async () => {
38
+ const senderKey = await this.ensureSenderKeyInternal(groupId, sender);
39
+ if (!senderKey.signingPrivateKey) {
40
+ throw new Error('sender private signing key is missing');
41
+ }
42
+ const derived = await (0, SenderKeyChain_1.deriveSenderKeyMsgKey)(senderKey.iteration, senderKey.chainKey);
43
+ await this.store.upsertSenderKey({
44
+ ...senderKey,
45
+ chainKey: derived.nextChainKey,
46
+ iteration: derived.messageKey.iteration + 1
47
+ });
48
+ const distributionProto = _proto_1.proto.SenderKeyDistributionMessage.encode({
49
+ id: senderKey.keyId,
50
+ iteration: senderKey.iteration,
51
+ chainKey: senderKey.chainKey,
52
+ signingKey: senderKey.signingPublicKey
53
+ }).finish();
54
+ const distributionMessage = {
55
+ groupId,
56
+ axolotlSenderKeyDistributionMessage: (0, _crypto_1.prependVersion)(distributionProto, constants_2.SIGNAL_GROUP_VERSION)
57
+ };
58
+ const messagePayload = await aesCbcEncryptFromSeed(derived.messageKey.seed, plaintext);
59
+ const senderKeyMessage = _proto_1.proto.SenderKeyMessage.encode({
60
+ id: senderKey.keyId,
61
+ iteration: derived.messageKey.iteration,
62
+ ciphertext: messagePayload
63
+ }).finish();
64
+ const versionedContent = (0, _crypto_1.prependVersion)(senderKeyMessage, constants_2.SIGNAL_GROUP_VERSION);
65
+ const signature = await (0, WaAdvSignature_1.signSignalMessage)(senderKey.signingPrivateKey, versionedContent);
66
+ if (signature.length !== constants_1.SIGNAL_SIGNATURE_LENGTH) {
67
+ throw new Error(`invalid sender key signature length ${signature.length}`);
68
+ }
69
+ const ciphertext = {
70
+ groupId,
71
+ sender,
72
+ keyId: senderKey.keyId,
73
+ iteration: derived.messageKey.iteration,
74
+ ciphertext: (0, bytes_1.concatBytes)([versionedContent, signature])
75
+ };
76
+ await this.store.upsertSenderKeyDistribution({
77
+ groupId,
78
+ sender,
79
+ keyId: senderKey.keyId,
80
+ timestampMs: Date.now()
81
+ });
82
+ return {
83
+ distributionMessage,
84
+ ciphertext,
85
+ keyId: senderKey.keyId
86
+ };
46
87
  });
47
- return {
48
- groupId,
49
- axolotlSenderKeyDistributionMessage: payload
50
- };
51
88
  }
52
- async filterParticipantsNeedingDistribution(groupId, sender, participants) {
89
+ async filterParticipantsNeedingDistribution(groupId, senderKeyId, participants) {
53
90
  if (participants.length === 0) {
54
91
  return [];
55
92
  }
56
- const senderKey = await this.ensureSenderKey(groupId, sender);
57
93
  const distributed = await this.store.getDeviceSenderKeyDistributions(groupId, participants);
58
- return participants.filter((_, index) => {
94
+ const pendingParticipants = new Array(participants.length);
95
+ let pendingCount = 0;
96
+ for (let index = 0; index < participants.length; index += 1) {
59
97
  const record = distributed[index];
60
- return !record || record.keyId !== senderKey.keyId;
61
- });
98
+ if (!record || record.keyId !== senderKeyId) {
99
+ pendingParticipants[pendingCount] = participants[index];
100
+ pendingCount += 1;
101
+ }
102
+ }
103
+ pendingParticipants.length = pendingCount;
104
+ return pendingParticipants;
62
105
  }
63
- async markSenderKeyDistributed(groupId, sender, participants) {
106
+ async markSenderKeyDistributed(groupId, senderKeyId, participants) {
64
107
  if (participants.length === 0) {
65
108
  return;
66
109
  }
67
- const senderKey = await this.ensureSenderKey(groupId, sender);
68
110
  const timestampMs = Date.now();
69
- await this.store.upsertSenderKeyDistributions(participants.map((participant) => ({
70
- groupId,
71
- sender: participant,
72
- keyId: senderKey.keyId,
73
- timestampMs
74
- })));
75
- }
76
- async processSenderKeyDistributionPayload(groupId, sender, payload) {
77
- if (groupId.length === 0) {
78
- throw new Error('sender key distribution missing groupId');
111
+ const distributions = new Array(participants.length);
112
+ for (let index = 0; index < participants.length; index += 1) {
113
+ distributions[index] = {
114
+ groupId,
115
+ sender: participants[index],
116
+ keyId: senderKeyId,
117
+ timestampMs
118
+ };
79
119
  }
80
- const parsed = (0, SenderKeyCodec_1.parseDistributionPayload)(payload);
81
- const record = {
82
- groupId,
83
- sender,
84
- keyId: parsed.keyId,
85
- iteration: parsed.iteration,
86
- chainKey: parsed.chainKey,
87
- signingPublicKey: parsed.signingPublicKey,
88
- unusedMessageKeys: []
89
- };
90
- await this.store.upsertSenderKey(record);
91
- await this.store.upsertSenderKeyDistribution({
92
- groupId,
93
- sender,
94
- keyId: parsed.keyId,
95
- timestampMs: Date.now()
96
- });
97
- return record;
120
+ await this.store.upsertSenderKeyDistributions(distributions);
98
121
  }
99
- async encryptGroupMessage(groupId, sender, plaintext) {
100
- const senderKey = await this.ensureSenderKey(groupId, sender);
101
- if (!senderKey.signingPrivateKey) {
102
- throw new Error('sender private signing key is missing');
103
- }
104
- const derived = await (0, SenderKeyChain_1.deriveSenderKeyMsgKey)(senderKey.iteration, senderKey.chainKey);
105
- const messagePayload = await aesCbcEncryptFromSeed(derived.messageKey.seed, plaintext);
106
- const senderKeyMessage = _proto_1.proto.SenderKeyMessage.encode({
107
- id: senderKey.keyId,
108
- iteration: derived.messageKey.iteration,
109
- ciphertext: messagePayload
110
- }).finish();
111
- const versionedContent = (0, _crypto_1.prependVersion)(senderKeyMessage, constants_1.SIGNAL_GROUP_VERSION);
112
- const signature = await (0, WaAdvSignature_1.signSignalMessage)(senderKey.signingPrivateKey, versionedContent);
113
- if (signature.length !== constants_1.SIGNATURE_SIZE) {
114
- throw new Error(`invalid sender key signature length ${signature.length}`);
115
- }
116
- const ciphertext = (0, bytes_1.concatBytes)([versionedContent, signature]);
117
- await this.store.upsertSenderKey({
118
- ...senderKey,
119
- chainKey: derived.nextChainKey,
120
- iteration: derived.messageKey.iteration + 1
122
+ async processSenderKeyDistributionPayload(groupId, sender, payload) {
123
+ return this.runWithSenderLock(groupId, sender, async () => {
124
+ if (groupId.length === 0) {
125
+ throw new Error('sender key distribution missing groupId');
126
+ }
127
+ const parsed = (0, SenderKeyCodec_1.parseDistributionPayload)(payload);
128
+ const record = {
129
+ groupId,
130
+ sender,
131
+ keyId: parsed.keyId,
132
+ iteration: parsed.iteration,
133
+ chainKey: parsed.chainKey,
134
+ signingPublicKey: parsed.signingPublicKey,
135
+ unusedMessageKeys: []
136
+ };
137
+ await Promise.all([
138
+ this.store.upsertSenderKey(record),
139
+ this.store.upsertSenderKeyDistribution({
140
+ groupId,
141
+ sender,
142
+ keyId: parsed.keyId,
143
+ timestampMs: Date.now()
144
+ })
145
+ ]);
146
+ return record;
121
147
  });
122
- return {
123
- groupId,
124
- sender,
125
- keyId: senderKey.keyId,
126
- iteration: derived.messageKey.iteration,
127
- ciphertext
128
- };
129
148
  }
130
149
  async decryptGroupMessage(payload) {
131
- const parsed = (0, SenderKeyCodec_1.parseSenderKeyMessage)(payload.ciphertext);
132
- const senderKey = await this.store.getDeviceSenderKey(payload.groupId, payload.sender);
133
- if (!senderKey) {
134
- throw new Error('missing sender key');
135
- }
136
- if (senderKey.keyId !== parsed.keyId) {
137
- throw new Error('sender key id mismatch');
138
- }
139
- if (payload.keyId !== undefined &&
140
- payload.keyId !== null &&
141
- parsed.keyId !== payload.keyId) {
142
- throw new Error('sender key id mismatch');
143
- }
144
- if (payload.iteration !== undefined &&
145
- payload.iteration !== null &&
146
- parsed.iteration !== payload.iteration) {
147
- throw new Error('sender key iteration mismatch');
148
- }
149
- const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - constants_1.SIGNATURE_SIZE);
150
- const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - constants_1.SIGNATURE_SIZE);
151
- const validSignature = await (0, WaAdvSignature_1.verifySignalSignature)(senderKey.signingPublicKey, signedContent, signature);
152
- if (!validSignature) {
153
- throw new Error('invalid sender key signature');
154
- }
155
- const selected = await (0, SenderKeyChain_1.selectMessageKey)(senderKey, parsed.iteration);
156
- const plaintext = await aesCbcDecryptFromSeed(selected.messageKey.seed, parsed.ciphertext);
157
- await this.store.upsertSenderKey(selected.updatedRecord);
158
- return plaintext;
150
+ return this.runWithSenderLock(payload.groupId, payload.sender, async () => {
151
+ const parsed = (0, SenderKeyCodec_1.parseSenderKeyMessage)(payload.ciphertext);
152
+ const senderKey = await this.store.getDeviceSenderKey(payload.groupId, payload.sender);
153
+ if (!senderKey) {
154
+ throw new Error('missing sender key');
155
+ }
156
+ if (senderKey.keyId !== parsed.keyId) {
157
+ throw new Error('sender key id mismatch');
158
+ }
159
+ if (payload.keyId !== undefined &&
160
+ payload.keyId !== null &&
161
+ parsed.keyId !== payload.keyId) {
162
+ throw new Error('sender key id mismatch');
163
+ }
164
+ if (payload.iteration !== undefined &&
165
+ payload.iteration !== null &&
166
+ parsed.iteration !== payload.iteration) {
167
+ throw new Error('sender key iteration mismatch');
168
+ }
169
+ const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - constants_1.SIGNAL_SIGNATURE_LENGTH);
170
+ const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - constants_1.SIGNAL_SIGNATURE_LENGTH);
171
+ const validSignature = await (0, WaAdvSignature_1.verifySignalSignature)(senderKey.signingPublicKey, signedContent, signature);
172
+ if (!validSignature) {
173
+ throw new Error('invalid sender key signature');
174
+ }
175
+ const selected = await (0, SenderKeyChain_1.selectMessageKey)(senderKey, parsed.iteration);
176
+ // Keep decrypt + persist ordered: failed decrypt must not advance sender-key state.
177
+ const plaintext = await aesCbcDecryptFromSeed(selected.messageKey.seed, parsed.ciphertext);
178
+ await this.store.upsertSenderKey(selected.updatedRecord);
179
+ return plaintext;
180
+ });
159
181
  }
160
- async ensureSenderKey(groupId, sender) {
182
+ async ensureSenderKeyInternal(groupId, sender) {
161
183
  const existing = await this.store.getDeviceSenderKey(groupId, sender);
162
184
  if (existing) {
163
185
  return existing;
164
186
  }
165
- const signingKeyPair = await _crypto_1.X25519.generateKeyPair();
187
+ const [signingKeyPair, keyId, chainKey] = await Promise.all([
188
+ _crypto_1.X25519.generateKeyPair(),
189
+ (0, _crypto_1.randomIntAsync)(1, 2147483647),
190
+ (0, _crypto_1.randomBytesAsync)(32)
191
+ ]);
166
192
  const created = {
167
193
  groupId,
168
194
  sender,
169
- keyId: await (0, _crypto_1.randomIntAsync)(1, 2147483647),
195
+ keyId,
170
196
  iteration: 0,
171
- chainKey: await (0, _crypto_1.randomBytesAsync)(32),
197
+ chainKey,
172
198
  signingPublicKey: (0, _crypto_1.toSerializedPubKey)(signingKeyPair.pubKey),
173
199
  signingPrivateKey: signingKeyPair.privKey,
174
200
  unusedMessageKeys: []
@@ -176,5 +202,8 @@ class SenderKeyManager {
176
202
  await this.store.upsertSenderKey(created);
177
203
  return created;
178
204
  }
205
+ runWithSenderLock(groupId, sender, task) {
206
+ return this.senderLock.run(`senderKey:${groupId}:${(0, jid_1.signalAddressKey)(sender)}`, task);
207
+ }
179
208
  }
180
209
  exports.SenderKeyManager = SenderKeyManager;
@@ -1,6 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SignalProtocol = exports.createAndStoreInitialKeys = exports.SenderKeyManager = exports.SignalSessionSyncApi = exports.SignalRotateKeyApi = exports.SignalMissingPreKeysSyncApi = exports.SignalIdentitySyncApi = exports.SignalDeviceSyncApi = exports.SignalDigestSyncApi = exports.parsePreKeyUploadFailure = exports.buildPreKeyUploadIq = exports.generateSignedPreKey = exports.generateRegistrationInfo = exports.generateRegistrationId = exports.generatePreKeyPair = void 0;
3
+ exports.createSignalSessionResolver = exports.SignalProtocol = exports.createAndStoreInitialKeys = exports.SenderKeyManager = exports.SignalSessionSyncApi = exports.SignalRotateKeyApi = exports.SignalMissingPreKeysSyncApi = exports.SignalIdentitySyncApi = exports.SignalDeviceSyncApi = exports.SignalDigestSyncApi = exports.parsePreKeyUploadFailure = exports.buildPreKeyUploadIq = exports.generateSignedPreKey = exports.generateRegistrationInfo = exports.generateRegistrationId = exports.generatePreKeyPair = exports.toSignalAddressParts = exports.encodeSignalSessionRecord = exports.encodeSenderKeyRecord = exports.decodeStoreCount = exports.decodeSenderKeyRecord = exports.decodeSenderKeyDistributionRow = exports.decodeSignalSignedPreKeyRow = exports.decodeSignalSessionRecord = exports.decodeSignalRemoteIdentity = exports.decodeSignalRegistrationRow = exports.decodeSignalPreKeyRow = void 0;
4
+ var encoding_1 = require("./encoding");
5
+ Object.defineProperty(exports, "decodeSignalPreKeyRow", { enumerable: true, get: function () { return encoding_1.decodeSignalPreKeyRow; } });
6
+ Object.defineProperty(exports, "decodeSignalRegistrationRow", { enumerable: true, get: function () { return encoding_1.decodeSignalRegistrationRow; } });
7
+ Object.defineProperty(exports, "decodeSignalRemoteIdentity", { enumerable: true, get: function () { return encoding_1.decodeSignalRemoteIdentity; } });
8
+ Object.defineProperty(exports, "decodeSignalSessionRecord", { enumerable: true, get: function () { return encoding_1.decodeSignalSessionRecord; } });
9
+ Object.defineProperty(exports, "decodeSignalSignedPreKeyRow", { enumerable: true, get: function () { return encoding_1.decodeSignalSignedPreKeyRow; } });
10
+ Object.defineProperty(exports, "decodeSenderKeyDistributionRow", { enumerable: true, get: function () { return encoding_1.decodeSenderKeyDistributionRow; } });
11
+ Object.defineProperty(exports, "decodeSenderKeyRecord", { enumerable: true, get: function () { return encoding_1.decodeSenderKeyRecord; } });
12
+ Object.defineProperty(exports, "decodeStoreCount", { enumerable: true, get: function () { return encoding_1.decodeStoreCount; } });
13
+ Object.defineProperty(exports, "encodeSenderKeyRecord", { enumerable: true, get: function () { return encoding_1.encodeSenderKeyRecord; } });
14
+ Object.defineProperty(exports, "encodeSignalSessionRecord", { enumerable: true, get: function () { return encoding_1.encodeSignalSessionRecord; } });
15
+ Object.defineProperty(exports, "toSignalAddressParts", { enumerable: true, get: function () { return encoding_1.toSignalAddressParts; } });
4
16
  var keygen_1 = require("./registration/keygen");
5
17
  Object.defineProperty(exports, "generatePreKeyPair", { enumerable: true, get: function () { return keygen_1.generatePreKeyPair; } });
6
18
  Object.defineProperty(exports, "generateRegistrationId", { enumerable: true, get: function () { return keygen_1.generateRegistrationId; } });
@@ -27,3 +39,5 @@ var utils_1 = require("./registration/utils");
27
39
  Object.defineProperty(exports, "createAndStoreInitialKeys", { enumerable: true, get: function () { return utils_1.createAndStoreInitialKeys; } });
28
40
  var SignalProtocol_1 = require("./session/SignalProtocol");
29
41
  Object.defineProperty(exports, "SignalProtocol", { enumerable: true, get: function () { return SignalProtocol_1.SignalProtocol; } });
42
+ var resolver_1 = require("./session/resolver");
43
+ Object.defineProperty(exports, "createSignalSessionResolver", { enumerable: true, get: function () { return resolver_1.createSignalSessionResolver; } });
@@ -9,9 +9,13 @@ const keys_1 = require("../../crypto/core/keys");
9
9
  const X25519_1 = require("../../crypto/curves/X25519");
10
10
  const WaAdvSignature_1 = require("../crypto/WaAdvSignature");
11
11
  async function generateRegistrationInfo() {
12
+ const [registrationId, identityKeyPair] = await Promise.all([
13
+ generateRegistrationId(),
14
+ X25519_1.X25519.generateKeyPair()
15
+ ]);
12
16
  return {
13
- registrationId: await generateRegistrationId(),
14
- identityKeyPair: await X25519_1.X25519.generateKeyPair()
17
+ registrationId,
18
+ identityKeyPair
15
19
  };
16
20
  }
17
21
  async function generatePreKeyPair(keyId) {
@@ -8,6 +8,7 @@ async function createAndStoreInitialKeys(store) {
8
8
  (0, keygen_1.generatePreKeyPair)(1)
9
9
  ]);
10
10
  const signedPreKey = await (0, keygen_1.generateSignedPreKey)(1, registrationInfo.identityKeyPair.privKey);
11
+ // Keep writes ordered so partial commit failures don't leave split registration bootstrap state.
11
12
  await store.setRegistrationInfo(registrationInfo);
12
13
  await store.setSignedPreKey(signedPreKey);
13
14
  await store.getOrGenSinglePreKey(async () => firstPreKey);
@@ -3,77 +3,187 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SignalProtocol = void 0;
4
4
  const _crypto_1 = require("../../crypto/index.js");
5
5
  const ConsoleLogger_1 = require("../../infra/log/ConsoleLogger");
6
+ const StoreLock_1 = require("../../infra/perf/StoreLock");
6
7
  const constants_1 = require("../constants");
7
8
  const SignalRatchet_1 = require("../session/SignalRatchet");
8
9
  const SignalSerializer_1 = require("../session/SignalSerializer");
9
10
  const SignalSession_1 = require("../session/SignalSession");
10
11
  const bytes_1 = require("../../util/bytes");
12
+ function signalAddressMapKey(address) {
13
+ return `${address.user}\u0001${address.server ?? ''}\u0001${address.device}`;
14
+ }
15
+ function signalAddressLockKey(address) {
16
+ return `signal:${signalAddressMapKey(address)}`;
17
+ }
11
18
  class SignalProtocol {
12
19
  constructor(store, logger = new ConsoleLogger_1.ConsoleLogger('info')) {
13
20
  this.store = store;
14
21
  this.logger = logger;
22
+ this.sessionMutationLock = new StoreLock_1.StoreLock();
15
23
  }
16
- async hasSession(address) {
17
- return this.store.hasSession(address);
18
- }
19
- async hasSessions(addresses) {
20
- return this.store.hasSessions(addresses);
24
+ async establishOutgoingSession(address, remoteBundle, options = {}) {
25
+ return this.runWithAddressLock(address, async () => {
26
+ if (options.reuseExisting) {
27
+ const existing = await this.store.getSession(address);
28
+ if (existing) {
29
+ const remoteIdentity = (0, _crypto_1.toSerializedPubKey)(remoteBundle.identity);
30
+ if (!(0, bytes_1.uint8Equal)(existing.remote.pubKey, remoteIdentity)) {
31
+ throw new Error('identity mismatch');
32
+ }
33
+ return existing;
34
+ }
35
+ }
36
+ const [local, localOneTimeBase] = await Promise.all([
37
+ (0, SignalSession_1.requireLocalIdentity)(this.store),
38
+ (0, SignalSession_1.generateSerializedKeyPair)()
39
+ ]);
40
+ const session = await (0, SignalSession_1.initiateSessionOutgoing)(local, remoteBundle, localOneTimeBase);
41
+ // Keep writes ordered: a stored session without matching remote identity causes false mismatch checks.
42
+ await this.store.setRemoteIdentity(address, session.remote.pubKey);
43
+ await this.store.setSession(address, session);
44
+ return session;
45
+ });
21
46
  }
22
- async establishOutgoingSession(address, remoteBundle) {
23
- const [local, localOneTimeBase] = await Promise.all([
24
- (0, SignalSession_1.requireLocalIdentity)(this.store),
25
- (0, SignalSession_1.generateSerializedKeyPair)()
47
+ async encryptMessage(address, plaintext, expectedIdentity) {
48
+ const [encrypted] = await this.encryptMessagesBatch([
49
+ { address, plaintext, expectedIdentity }
26
50
  ]);
27
- const session = await (0, SignalSession_1.initiateSessionOutgoing)(local, remoteBundle, localOneTimeBase);
28
- await this.store.setRemoteIdentity(address, session.remote.pubKey);
29
- await this.store.setSession(address, session);
30
- return session;
51
+ return encrypted;
31
52
  }
32
- async encryptMessage(address, plaintext, expectedIdentity) {
33
- const session = await this.store.getSession(address);
34
- if (!session) {
35
- throw new Error('signal session not found');
36
- }
37
- if (expectedIdentity &&
38
- !(0, bytes_1.uint8Equal)((0, _crypto_1.toSerializedPubKey)(expectedIdentity), session.remote.pubKey)) {
39
- throw new Error('identity mismatch');
53
+ async encryptMessagesBatch(requests, prefetchedSessions) {
54
+ if (requests.length === 0) {
55
+ return [];
40
56
  }
41
- const [updatedSession, encrypted] = await (0, SignalRatchet_1.encryptMsg)(session, plaintext);
42
- await this.store.setSession(address, updatedSession);
43
- if (!(0, bytes_1.uint8Equal)(updatedSession.remote.pubKey, session.remote.pubKey)) {
44
- await this.store.setRemoteIdentity(address, updatedSession.remote.pubKey);
45
- }
46
- return {
47
- ...encrypted,
48
- baseKey: updatedSession.aliceBaseKey
49
- };
57
+ const lockKeySet = new Set();
58
+ for (let i = 0; i < requests.length; i += 1)
59
+ lockKeySet.add(signalAddressLockKey(requests[i].address));
60
+ const lockKeys = [...lockKeySet];
61
+ return this.sessionMutationLock.runMany(lockKeys, async () => {
62
+ const prefetchedByAddress = new Map();
63
+ if (prefetchedSessions && prefetchedSessions.length > 0) {
64
+ for (let index = 0; index < prefetchedSessions.length; index += 1) {
65
+ const entry = prefetchedSessions[index];
66
+ prefetchedByAddress.set(signalAddressMapKey(entry.address), entry.session);
67
+ }
68
+ }
69
+ const uniqueAddressKeys = new Array(requests.length);
70
+ const uniqueAddresses = new Array(requests.length);
71
+ let uniqueAddressCount = 0;
72
+ for (let index = 0; index < requests.length; index += 1) {
73
+ const address = requests[index].address;
74
+ const addressKey = signalAddressMapKey(address);
75
+ let isDuplicate = false;
76
+ for (let dedupIndex = 0; dedupIndex < uniqueAddressCount; dedupIndex += 1) {
77
+ if (uniqueAddressKeys[dedupIndex] === addressKey) {
78
+ isDuplicate = true;
79
+ break;
80
+ }
81
+ }
82
+ if (isDuplicate) {
83
+ continue;
84
+ }
85
+ uniqueAddressKeys[uniqueAddressCount] = addressKey;
86
+ uniqueAddresses[uniqueAddressCount] = address;
87
+ uniqueAddressCount += 1;
88
+ }
89
+ uniqueAddressKeys.length = uniqueAddressCount;
90
+ uniqueAddresses.length = uniqueAddressCount;
91
+ const currentSessions = await this.store.getSessionsBatch(uniqueAddresses);
92
+ const latestSessionByAddress = new Map();
93
+ for (let index = 0; index < uniqueAddressCount; index += 1) {
94
+ const addressKey = uniqueAddressKeys[index];
95
+ const current = currentSessions[index];
96
+ if (current) {
97
+ latestSessionByAddress.set(addressKey, current);
98
+ continue;
99
+ }
100
+ const prefetched = prefetchedByAddress.get(addressKey);
101
+ if (prefetched) {
102
+ latestSessionByAddress.set(addressKey, prefetched);
103
+ }
104
+ }
105
+ const sessionUpdatesByAddress = new Map();
106
+ const identityUpdatesByAddress = new Map();
107
+ const results = new Array(requests.length);
108
+ for (let index = 0; index < requests.length; index += 1) {
109
+ const request = requests[index];
110
+ const address = request.address;
111
+ const addressKey = signalAddressMapKey(address);
112
+ const session = latestSessionByAddress.get(addressKey);
113
+ if (!session) {
114
+ throw new Error('signal session not found');
115
+ }
116
+ if (request.expectedIdentity &&
117
+ !(0, bytes_1.uint8Equal)((0, _crypto_1.toSerializedPubKey)(request.expectedIdentity), session.remote.pubKey)) {
118
+ throw new Error('identity mismatch');
119
+ }
120
+ const [updatedSession, encrypted] = await (0, SignalRatchet_1.encryptMsg)(session, request.plaintext);
121
+ latestSessionByAddress.set(addressKey, updatedSession);
122
+ sessionUpdatesByAddress.set(addressKey, {
123
+ address,
124
+ session: updatedSession
125
+ });
126
+ if (!(0, bytes_1.uint8Equal)(updatedSession.remote.pubKey, session.remote.pubKey)) {
127
+ identityUpdatesByAddress.set(addressKey, {
128
+ address,
129
+ identityKey: updatedSession.remote.pubKey
130
+ });
131
+ }
132
+ results[index] = {
133
+ ...encrypted,
134
+ baseKey: updatedSession.aliceBaseKey
135
+ };
136
+ }
137
+ // Persist remote identities first when needed so session writes never commit ahead of identity data.
138
+ if (identityUpdatesByAddress.size > 0) {
139
+ const identityUpdates = new Array(identityUpdatesByAddress.size);
140
+ let identityIndex = 0;
141
+ for (const update of identityUpdatesByAddress.values()) {
142
+ identityUpdates[identityIndex] = update;
143
+ identityIndex += 1;
144
+ }
145
+ await this.store.setRemoteIdentities(identityUpdates);
146
+ }
147
+ const sessionUpdates = new Array(sessionUpdatesByAddress.size);
148
+ let sessionIndex = 0;
149
+ for (const update of sessionUpdatesByAddress.values()) {
150
+ sessionUpdates[sessionIndex] = update;
151
+ sessionIndex += 1;
152
+ }
153
+ await this.store.setSessionsBatch(sessionUpdates);
154
+ return results;
155
+ });
50
156
  }
51
157
  async decryptMessage(address, envelope) {
52
- const currentSession = await this.store.getSession(address);
53
- let outcome;
54
- if (envelope.type === 'pkmsg') {
55
- const parsedPk = (0, SignalSerializer_1.deserializePkMsg)(envelope.ciphertext);
56
- outcome = await this.decryptPkMsg(currentSession, parsedPk);
57
- }
58
- else {
59
- const parsed = (0, SignalSerializer_1.deserializeMsg)(envelope.ciphertext);
60
- outcome = await this.decryptMsgInternal(currentSession, parsed);
61
- }
62
- const nextRemoteIdentity = outcome.newSessionInfo?.newIdentity ?? outcome.updatedSession.remote.pubKey;
63
- if (!currentSession || !(0, bytes_1.uint8Equal)(currentSession.remote.pubKey, nextRemoteIdentity)) {
64
- await this.store.setRemoteIdentity(address, nextRemoteIdentity);
65
- }
66
- await this.store.setSession(address, outcome.updatedSession);
67
- return outcome.plaintext;
68
- }
69
- async decryptMsgInternal(session, parsed) {
70
- return (0, SignalRatchet_1.decryptMsg)(session, parsed, (error, previousSessionIndex) => {
71
- this.logger.debug('signal decrypt fallback session failed', {
72
- previousSessionIndex,
73
- message: error.message
74
- });
158
+ return this.runWithAddressLock(address, async () => {
159
+ const currentSession = await this.store.getSession(address);
160
+ let outcome;
161
+ if (envelope.type === 'pkmsg') {
162
+ const parsedPk = (0, SignalSerializer_1.deserializePkMsg)(envelope.ciphertext);
163
+ outcome = await this.decryptPkMsg(currentSession, parsedPk);
164
+ }
165
+ else {
166
+ const parsed = (0, SignalSerializer_1.deserializeMsg)(envelope.ciphertext);
167
+ outcome = await (0, SignalRatchet_1.decryptMsg)(currentSession, parsed, (error, previousSessionIndex) => {
168
+ this.logger.debug('signal decrypt fallback session failed', {
169
+ previousSessionIndex,
170
+ message: error.message
171
+ });
172
+ });
173
+ }
174
+ const nextRemoteIdentity = outcome.newSessionInfo?.newIdentity ?? outcome.updatedSession.remote.pubKey;
175
+ const identityChanged = !currentSession || !(0, bytes_1.uint8Equal)(currentSession.remote.pubKey, nextRemoteIdentity);
176
+ // Keep writes ordered for consistency with resolver identity checks.
177
+ if (identityChanged) {
178
+ await this.store.setRemoteIdentity(address, nextRemoteIdentity);
179
+ }
180
+ await this.store.setSession(address, outcome.updatedSession);
181
+ return outcome.plaintext;
75
182
  });
76
183
  }
184
+ runWithAddressLock(address, task) {
185
+ return this.sessionMutationLock.run(signalAddressLockKey(address), task);
186
+ }
77
187
  async decryptPkMsg(currentSession, parsed) {
78
188
  const matchingSession = (0, SignalSession_1.findMatchingSession)(currentSession, parsed.sessionBaseKey);
79
189
  if (matchingSession) {
@@ -109,6 +219,7 @@ class SignalProtocol {
109
219
  }
110
220
  : incoming;
111
221
  const [updatedSession, plaintext] = await (0, SignalRatchet_1.decryptMsgFromSession)(baseSession, parsed);
222
+ // Only consume one-time prekeys after successful decrypt/session materialization.
112
223
  if (parsed.localOneTimeKeyId !== null && parsed.localOneTimeKeyId !== undefined) {
113
224
  await this.store.consumePreKeyById(parsed.localOneTimeKeyId);
114
225
  }