zapo-js 0.1.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 (585) hide show
  1. package/README.md +235 -0
  2. package/dist/appstate/WaAppStateCrypto.js +202 -0
  3. package/dist/appstate/WaAppStateSyncClient.js +808 -0
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +71 -0
  5. package/dist/appstate/constants.js +23 -0
  6. package/dist/appstate/index.js +28 -0
  7. package/dist/appstate/store/sqlite.js +55 -0
  8. package/dist/appstate/types.js +2 -0
  9. package/dist/appstate/utils.js +84 -0
  10. package/dist/auth/WaAuthClient.js +266 -0
  11. package/dist/auth/flow/WaAuthCredentialsFlow.js +123 -0
  12. package/dist/auth/index.js +27 -0
  13. package/dist/auth/pairing/WaPairingCodeCrypto.js +75 -0
  14. package/dist/auth/pairing/WaPairingFlow.js +328 -0
  15. package/dist/auth/pairing/WaQrFlow.js +86 -0
  16. package/dist/auth/pairing/constants.js +5 -0
  17. package/dist/auth/types.js +2 -0
  18. package/dist/client/WaClient.js +749 -0
  19. package/dist/client/WaClientFactory.js +381 -0
  20. package/dist/client/coordinators/WaGroupCoordinator.js +191 -0
  21. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +315 -0
  22. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +1061 -0
  23. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +200 -0
  24. package/dist/client/coordinators/WaRetryCoordinator.js +494 -0
  25. package/dist/client/coordinators/WaStreamControlCoordinator.js +123 -0
  26. package/dist/client/dirty.js +254 -0
  27. package/dist/client/events/chat.js +226 -0
  28. package/dist/client/events/group.js +410 -0
  29. package/dist/client/history-sync.js +122 -0
  30. package/dist/client/incoming.js +236 -0
  31. package/dist/client/index.js +5 -0
  32. package/dist/client/mailbox.js +49 -0
  33. package/dist/client/messages.js +152 -0
  34. package/dist/client/types.js +2 -0
  35. package/dist/crypto/core/constants.js +4 -0
  36. package/dist/crypto/core/encoding.js +29 -0
  37. package/dist/crypto/core/hkdf.js +26 -0
  38. package/dist/crypto/core/index.js +43 -0
  39. package/dist/crypto/core/keys.js +73 -0
  40. package/dist/crypto/core/nonce.js +18 -0
  41. package/dist/crypto/core/primitives.js +121 -0
  42. package/dist/crypto/core/random.js +32 -0
  43. package/dist/crypto/curves/Ed25519.js +42 -0
  44. package/dist/crypto/curves/X25519.js +64 -0
  45. package/dist/crypto/curves/constants.js +6 -0
  46. package/dist/crypto/curves/types.js +9 -0
  47. package/dist/crypto/index.js +22 -0
  48. package/dist/crypto/math/constants.js +44 -0
  49. package/dist/crypto/math/edwards.js +64 -0
  50. package/dist/crypto/math/le.js +20 -0
  51. package/dist/crypto/math/mod.js +38 -0
  52. package/dist/crypto/math/types.js +2 -0
  53. package/dist/esm/appstate/WaAppStateCrypto.js +198 -0
  54. package/dist/esm/appstate/WaAppStateSyncClient.js +803 -0
  55. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +67 -0
  56. package/dist/esm/appstate/constants.js +20 -0
  57. package/dist/esm/appstate/index.js +6 -0
  58. package/dist/esm/appstate/store/sqlite.js +49 -0
  59. package/dist/esm/appstate/types.js +1 -0
  60. package/dist/esm/appstate/utils.js +75 -0
  61. package/dist/esm/auth/WaAuthClient.js +262 -0
  62. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +118 -0
  63. package/dist/esm/auth/index.js +5 -0
  64. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +71 -0
  65. package/dist/esm/auth/pairing/WaPairingFlow.js +324 -0
  66. package/dist/esm/auth/pairing/WaQrFlow.js +82 -0
  67. package/dist/esm/auth/pairing/constants.js +2 -0
  68. package/dist/esm/auth/types.js +1 -0
  69. package/dist/esm/client/WaClient.js +745 -0
  70. package/dist/esm/client/WaClientFactory.js +377 -0
  71. package/dist/esm/client/coordinators/WaGroupCoordinator.js +188 -0
  72. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +311 -0
  73. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +1057 -0
  74. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +196 -0
  75. package/dist/esm/client/coordinators/WaRetryCoordinator.js +490 -0
  76. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +120 -0
  77. package/dist/esm/client/dirty.js +250 -0
  78. package/dist/esm/client/events/chat.js +223 -0
  79. package/dist/esm/client/events/group.js +407 -0
  80. package/dist/esm/client/history-sync.js +119 -0
  81. package/dist/esm/client/incoming.js +227 -0
  82. package/dist/esm/client/index.js +1 -0
  83. package/dist/esm/client/mailbox.js +46 -0
  84. package/dist/esm/client/messages.js +148 -0
  85. package/dist/esm/client/types.js +1 -0
  86. package/dist/esm/crypto/core/constants.js +1 -0
  87. package/dist/esm/crypto/core/encoding.js +25 -0
  88. package/dist/esm/crypto/core/hkdf.js +22 -0
  89. package/dist/esm/crypto/core/index.js +11 -0
  90. package/dist/esm/crypto/core/keys.js +66 -0
  91. package/dist/esm/crypto/core/nonce.js +15 -0
  92. package/dist/esm/crypto/core/primitives.js +102 -0
  93. package/dist/esm/crypto/core/random.js +28 -0
  94. package/dist/esm/crypto/curves/Ed25519.js +38 -0
  95. package/dist/esm/crypto/curves/X25519.js +58 -0
  96. package/dist/esm/crypto/curves/constants.js +3 -0
  97. package/dist/esm/crypto/curves/types.js +6 -0
  98. package/dist/esm/crypto/index.js +3 -0
  99. package/dist/esm/crypto/math/constants.js +41 -0
  100. package/dist/esm/crypto/math/edwards.js +60 -0
  101. package/dist/esm/crypto/math/le.js +16 -0
  102. package/dist/esm/crypto/math/mod.js +31 -0
  103. package/dist/esm/crypto/math/types.js +1 -0
  104. package/dist/esm/index.js +6 -0
  105. package/dist/esm/infra/log/ConsoleLogger.js +40 -0
  106. package/dist/esm/infra/log/PinoLogger.js +73 -0
  107. package/dist/esm/infra/log/types.js +1 -0
  108. package/dist/esm/infra/perf/BoundedTaskQueue.js +62 -0
  109. package/dist/esm/media/WaMediaCrypto.js +224 -0
  110. package/dist/esm/media/WaMediaTransferClient.js +361 -0
  111. package/dist/esm/media/conn.js +33 -0
  112. package/dist/esm/media/constants.js +18 -0
  113. package/dist/esm/media/index.js +3 -0
  114. package/dist/esm/media/types.js +1 -0
  115. package/dist/esm/message/WaMessageClient.js +210 -0
  116. package/dist/esm/message/ack.js +46 -0
  117. package/dist/esm/message/content.js +20 -0
  118. package/dist/esm/message/device-sent.js +49 -0
  119. package/dist/esm/message/incoming.js +318 -0
  120. package/dist/esm/message/index.js +2 -0
  121. package/dist/esm/message/padding.js +20 -0
  122. package/dist/esm/message/phash.js +25 -0
  123. package/dist/esm/message/types.js +1 -0
  124. package/dist/esm/package.json +3 -0
  125. package/dist/esm/proto.js +3 -0
  126. package/dist/esm/protocol/appstate.js +34 -0
  127. package/dist/esm/protocol/auth.js +12 -0
  128. package/dist/esm/protocol/browser.js +41 -0
  129. package/dist/esm/protocol/constants.js +11 -0
  130. package/dist/esm/protocol/defaults.js +27 -0
  131. package/dist/esm/protocol/dirty.js +26 -0
  132. package/dist/esm/protocol/group.js +5 -0
  133. package/dist/esm/protocol/index.js +11 -0
  134. package/dist/esm/protocol/jid.js +94 -0
  135. package/dist/esm/protocol/media.js +20 -0
  136. package/dist/esm/protocol/message.js +16 -0
  137. package/dist/esm/protocol/nodes.js +83 -0
  138. package/dist/esm/protocol/notification.js +50 -0
  139. package/dist/esm/protocol/stream.js +60 -0
  140. package/dist/esm/retry/constants.js +20 -0
  141. package/dist/esm/retry/index.js +5 -0
  142. package/dist/esm/retry/outbound.js +83 -0
  143. package/dist/esm/retry/parse.js +130 -0
  144. package/dist/esm/retry/reason.js +50 -0
  145. package/dist/esm/retry/replay.js +177 -0
  146. package/dist/esm/retry/types.js +1 -0
  147. package/dist/esm/signal/api/SignalDeviceSyncApi.js +185 -0
  148. package/dist/esm/signal/api/SignalDigestSyncApi.js +179 -0
  149. package/dist/esm/signal/api/SignalIdentitySyncApi.js +111 -0
  150. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +141 -0
  151. package/dist/esm/signal/api/SignalRotateKeyApi.js +59 -0
  152. package/dist/esm/signal/api/SignalSessionSyncApi.js +187 -0
  153. package/dist/esm/signal/api/codec.js +23 -0
  154. package/dist/esm/signal/api/constants.js +9 -0
  155. package/dist/esm/signal/api/prekeys.js +9 -0
  156. package/dist/esm/signal/constants.js +16 -0
  157. package/dist/esm/signal/crypto/WaAdvSignature.js +60 -0
  158. package/dist/esm/signal/crypto/constants.js +8 -0
  159. package/dist/esm/signal/group/SenderKeyChain.js +97 -0
  160. package/dist/esm/signal/group/SenderKeyCodec.js +46 -0
  161. package/dist/esm/signal/group/SenderKeyManager.js +176 -0
  162. package/dist/esm/signal/index.js +11 -0
  163. package/dist/esm/signal/registration/keygen.js +31 -0
  164. package/dist/esm/signal/registration/utils.js +16 -0
  165. package/dist/esm/signal/session/SignalProtocol.js +122 -0
  166. package/dist/esm/signal/session/SignalRatchet.js +260 -0
  167. package/dist/esm/signal/session/SignalSerializer.js +63 -0
  168. package/dist/esm/signal/session/SignalSession.js +153 -0
  169. package/dist/esm/signal/store/sqlite.js +310 -0
  170. package/dist/esm/signal/types.js +1 -0
  171. package/dist/esm/store/contracts/appstate.store.js +1 -0
  172. package/dist/esm/store/contracts/auth.store.js +1 -0
  173. package/dist/esm/store/contracts/contact.store.js +1 -0
  174. package/dist/esm/store/contracts/device-list.store.js +1 -0
  175. package/dist/esm/store/contracts/message.store.js +1 -0
  176. package/dist/esm/store/contracts/participants.store.js +1 -0
  177. package/dist/esm/store/contracts/retry.store.js +1 -0
  178. package/dist/esm/store/contracts/sender-key.store.js +1 -0
  179. package/dist/esm/store/contracts/signal.store.js +1 -0
  180. package/dist/esm/store/contracts/thread.store.js +1 -0
  181. package/dist/esm/store/createStore.js +278 -0
  182. package/dist/esm/store/index.js +20 -0
  183. package/dist/esm/store/noop.store.js +43 -0
  184. package/dist/esm/store/providers/memory/appstate.store.js +101 -0
  185. package/dist/esm/store/providers/memory/contact.store.js +23 -0
  186. package/dist/esm/store/providers/memory/device-list.store.js +86 -0
  187. package/dist/esm/store/providers/memory/message.store.js +40 -0
  188. package/dist/esm/store/providers/memory/participants.store.js +61 -0
  189. package/dist/esm/store/providers/memory/retry.store.js +71 -0
  190. package/dist/esm/store/providers/memory/sender-key.store.js +88 -0
  191. package/dist/esm/store/providers/memory/signal.store.js +170 -0
  192. package/dist/esm/store/providers/memory/thread.store.js +34 -0
  193. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +37 -0
  194. package/dist/esm/store/providers/sqlite/appstate.store.js +169 -0
  195. package/dist/esm/store/providers/sqlite/auth.store.js +176 -0
  196. package/dist/esm/store/providers/sqlite/connection.js +240 -0
  197. package/dist/esm/store/providers/sqlite/contact.store.js +61 -0
  198. package/dist/esm/store/providers/sqlite/device-list.store.js +155 -0
  199. package/dist/esm/store/providers/sqlite/message.store.js +119 -0
  200. package/dist/esm/store/providers/sqlite/migrations.js +347 -0
  201. package/dist/esm/store/providers/sqlite/participants.store.js +85 -0
  202. package/dist/esm/store/providers/sqlite/retry.store.js +144 -0
  203. package/dist/esm/store/providers/sqlite/sender-key.store.js +203 -0
  204. package/dist/esm/store/providers/sqlite/signal.store.js +353 -0
  205. package/dist/esm/store/providers/sqlite/thread.store.js +72 -0
  206. package/dist/esm/store/types.js +1 -0
  207. package/dist/esm/transport/WaComms.js +527 -0
  208. package/dist/esm/transport/WaWebSocket.js +361 -0
  209. package/dist/esm/transport/binary/constants.js +96 -0
  210. package/dist/esm/transport/binary/decoder.js +275 -0
  211. package/dist/esm/transport/binary/encoder.js +210 -0
  212. package/dist/esm/transport/binary/index.js +4 -0
  213. package/dist/esm/transport/binary/tokens.js +1280 -0
  214. package/dist/esm/transport/index.js +6 -0
  215. package/dist/esm/transport/keepalive/WaKeepAlive.js +141 -0
  216. package/dist/esm/transport/node/WaNodeOrchestrator.js +143 -0
  217. package/dist/esm/transport/node/WaNodeTransport.js +64 -0
  218. package/dist/esm/transport/node/builders/accountSync.js +101 -0
  219. package/dist/esm/transport/node/builders/group.js +47 -0
  220. package/dist/esm/transport/node/builders/index.js +7 -0
  221. package/dist/esm/transport/node/builders/media.js +10 -0
  222. package/dist/esm/transport/node/builders/message.js +317 -0
  223. package/dist/esm/transport/node/builders/pairing.js +130 -0
  224. package/dist/esm/transport/node/builders/prekeys.js +102 -0
  225. package/dist/esm/transport/node/builders/retry.js +116 -0
  226. package/dist/esm/transport/node/helpers.js +37 -0
  227. package/dist/esm/transport/node/query.js +53 -0
  228. package/dist/esm/transport/node/xml.js +39 -0
  229. package/dist/esm/transport/noise/WaClientPayload.js +162 -0
  230. package/dist/esm/transport/noise/WaFrameCodec.js +121 -0
  231. package/dist/esm/transport/noise/WaNoiseCert.js +74 -0
  232. package/dist/esm/transport/noise/WaNoiseHandshake.js +57 -0
  233. package/dist/esm/transport/noise/WaNoiseSession.js +322 -0
  234. package/dist/esm/transport/noise/WaNoiseSocket.js +17 -0
  235. package/dist/esm/transport/noise/constants.js +8 -0
  236. package/dist/esm/transport/noise/types.js +1 -0
  237. package/dist/esm/transport/stream/parse.js +91 -0
  238. package/dist/esm/transport/types.js +1 -0
  239. package/dist/esm/util/async.js +5 -0
  240. package/dist/esm/util/base64.js +18 -0
  241. package/dist/esm/util/bytes.js +275 -0
  242. package/dist/esm/util/coercion.js +56 -0
  243. package/dist/esm/util/collections.js +27 -0
  244. package/dist/esm/util/primitives.js +32 -0
  245. package/dist/esm/util/runtime.js +15 -0
  246. package/dist/esm/util/signal-address.js +5 -0
  247. package/dist/index.js +52 -0
  248. package/dist/infra/log/ConsoleLogger.js +44 -0
  249. package/dist/infra/log/PinoLogger.js +111 -0
  250. package/dist/infra/log/types.js +2 -0
  251. package/dist/infra/perf/BoundedTaskQueue.js +67 -0
  252. package/dist/media/WaMediaCrypto.js +228 -0
  253. package/dist/media/WaMediaTransferClient.js +365 -0
  254. package/dist/media/conn.js +36 -0
  255. package/dist/media/constants.js +21 -0
  256. package/dist/media/index.js +9 -0
  257. package/dist/media/types.js +2 -0
  258. package/dist/message/WaMessageClient.js +214 -0
  259. package/dist/message/ack.js +52 -0
  260. package/dist/message/content.js +24 -0
  261. package/dist/message/device-sent.js +53 -0
  262. package/dist/message/incoming.js +321 -0
  263. package/dist/message/index.js +20 -0
  264. package/dist/message/padding.js +24 -0
  265. package/dist/message/phash.js +28 -0
  266. package/dist/message/types.js +2 -0
  267. package/dist/proto.js +5 -0
  268. package/dist/protocol/appstate.js +37 -0
  269. package/dist/protocol/auth.js +15 -0
  270. package/dist/protocol/browser.js +45 -0
  271. package/dist/protocol/constants.js +46 -0
  272. package/dist/protocol/defaults.js +30 -0
  273. package/dist/protocol/dirty.js +29 -0
  274. package/dist/protocol/group.js +8 -0
  275. package/dist/protocol/index.js +53 -0
  276. package/dist/protocol/jid.js +107 -0
  277. package/dist/protocol/media.js +24 -0
  278. package/dist/protocol/message.js +19 -0
  279. package/dist/protocol/nodes.js +86 -0
  280. package/dist/protocol/notification.js +53 -0
  281. package/dist/protocol/stream.js +63 -0
  282. package/dist/retry/constants.js +23 -0
  283. package/dist/retry/index.js +19 -0
  284. package/dist/retry/outbound.js +88 -0
  285. package/dist/retry/parse.js +133 -0
  286. package/dist/retry/reason.js +53 -0
  287. package/dist/retry/replay.js +181 -0
  288. package/dist/retry/types.js +2 -0
  289. package/dist/signal/api/SignalDeviceSyncApi.js +189 -0
  290. package/dist/signal/api/SignalDigestSyncApi.js +183 -0
  291. package/dist/signal/api/SignalIdentitySyncApi.js +115 -0
  292. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +145 -0
  293. package/dist/signal/api/SignalRotateKeyApi.js +63 -0
  294. package/dist/signal/api/SignalSessionSyncApi.js +191 -0
  295. package/dist/signal/api/codec.js +27 -0
  296. package/dist/signal/api/constants.js +12 -0
  297. package/dist/signal/api/prekeys.js +16 -0
  298. package/dist/signal/constants.js +19 -0
  299. package/dist/signal/crypto/WaAdvSignature.js +72 -0
  300. package/dist/signal/crypto/constants.js +11 -0
  301. package/dist/signal/group/SenderKeyChain.js +101 -0
  302. package/dist/signal/group/SenderKeyCodec.js +50 -0
  303. package/dist/signal/group/SenderKeyManager.js +180 -0
  304. package/dist/signal/index.js +29 -0
  305. package/dist/signal/registration/keygen.js +37 -0
  306. package/dist/signal/registration/utils.js +19 -0
  307. package/dist/signal/session/SignalProtocol.js +126 -0
  308. package/dist/signal/session/SignalRatchet.js +268 -0
  309. package/dist/signal/session/SignalSerializer.js +69 -0
  310. package/dist/signal/session/SignalSession.js +165 -0
  311. package/dist/signal/store/sqlite.js +324 -0
  312. package/dist/signal/types.js +2 -0
  313. package/dist/store/contracts/appstate.store.js +2 -0
  314. package/dist/store/contracts/auth.store.js +2 -0
  315. package/dist/store/contracts/contact.store.js +2 -0
  316. package/dist/store/contracts/device-list.store.js +2 -0
  317. package/dist/store/contracts/message.store.js +2 -0
  318. package/dist/store/contracts/participants.store.js +2 -0
  319. package/dist/store/contracts/retry.store.js +2 -0
  320. package/dist/store/contracts/sender-key.store.js +2 -0
  321. package/dist/store/contracts/signal.store.js +2 -0
  322. package/dist/store/contracts/thread.store.js +2 -0
  323. package/dist/store/createStore.js +281 -0
  324. package/dist/store/index.js +43 -0
  325. package/dist/store/noop.store.js +46 -0
  326. package/dist/store/providers/memory/appstate.store.js +105 -0
  327. package/dist/store/providers/memory/contact.store.js +27 -0
  328. package/dist/store/providers/memory/device-list.store.js +90 -0
  329. package/dist/store/providers/memory/message.store.js +44 -0
  330. package/dist/store/providers/memory/participants.store.js +65 -0
  331. package/dist/store/providers/memory/retry.store.js +75 -0
  332. package/dist/store/providers/memory/sender-key.store.js +92 -0
  333. package/dist/store/providers/memory/signal.store.js +174 -0
  334. package/dist/store/providers/memory/thread.store.js +38 -0
  335. package/dist/store/providers/sqlite/BaseSqliteStore.js +41 -0
  336. package/dist/store/providers/sqlite/appstate.store.js +173 -0
  337. package/dist/store/providers/sqlite/auth.store.js +180 -0
  338. package/dist/store/providers/sqlite/connection.js +276 -0
  339. package/dist/store/providers/sqlite/contact.store.js +65 -0
  340. package/dist/store/providers/sqlite/device-list.store.js +159 -0
  341. package/dist/store/providers/sqlite/message.store.js +123 -0
  342. package/dist/store/providers/sqlite/migrations.js +350 -0
  343. package/dist/store/providers/sqlite/participants.store.js +89 -0
  344. package/dist/store/providers/sqlite/retry.store.js +148 -0
  345. package/dist/store/providers/sqlite/sender-key.store.js +207 -0
  346. package/dist/store/providers/sqlite/signal.store.js +357 -0
  347. package/dist/store/providers/sqlite/thread.store.js +76 -0
  348. package/dist/store/types.js +2 -0
  349. package/dist/transport/WaComms.js +531 -0
  350. package/dist/transport/WaWebSocket.js +365 -0
  351. package/dist/transport/binary/constants.js +99 -0
  352. package/dist/transport/binary/decoder.js +279 -0
  353. package/dist/transport/binary/encoder.js +214 -0
  354. package/dist/transport/binary/index.js +23 -0
  355. package/dist/transport/binary/tokens.js +1283 -0
  356. package/dist/transport/index.js +18 -0
  357. package/dist/transport/keepalive/WaKeepAlive.js +145 -0
  358. package/dist/transport/node/WaNodeOrchestrator.js +147 -0
  359. package/dist/transport/node/WaNodeTransport.js +68 -0
  360. package/dist/transport/node/builders/accountSync.js +110 -0
  361. package/dist/transport/node/builders/group.js +52 -0
  362. package/dist/transport/node/builders/index.js +39 -0
  363. package/dist/transport/node/builders/media.js +13 -0
  364. package/dist/transport/node/builders/message.js +328 -0
  365. package/dist/transport/node/builders/pairing.js +137 -0
  366. package/dist/transport/node/builders/prekeys.js +107 -0
  367. package/dist/transport/node/builders/retry.js +119 -0
  368. package/dist/transport/node/helpers.js +46 -0
  369. package/dist/transport/node/query.js +59 -0
  370. package/dist/transport/node/xml.js +42 -0
  371. package/dist/transport/noise/WaClientPayload.js +166 -0
  372. package/dist/transport/noise/WaFrameCodec.js +125 -0
  373. package/dist/transport/noise/WaNoiseCert.js +77 -0
  374. package/dist/transport/noise/WaNoiseHandshake.js +61 -0
  375. package/dist/transport/noise/WaNoiseSession.js +326 -0
  376. package/dist/transport/noise/WaNoiseSocket.js +21 -0
  377. package/dist/transport/noise/constants.js +11 -0
  378. package/dist/transport/noise/types.js +2 -0
  379. package/dist/transport/stream/parse.js +97 -0
  380. package/dist/transport/types.js +2 -0
  381. package/dist/types/appstate/WaAppStateCrypto.d.ts +59 -0
  382. package/dist/types/appstate/WaAppStateSyncClient.d.ts +63 -0
  383. package/dist/types/appstate/WaAppStateSyncResponseParser.d.ts +12 -0
  384. package/dist/types/appstate/constants.d.ts +14 -0
  385. package/dist/types/appstate/index.d.ts +7 -0
  386. package/dist/types/appstate/store/sqlite.d.ts +21 -0
  387. package/dist/types/appstate/types.d.ts +66 -0
  388. package/dist/types/appstate/utils.d.ts +10 -0
  389. package/dist/types/auth/WaAuthClient.d.ts +61 -0
  390. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +14 -0
  391. package/dist/types/auth/index.d.ts +6 -0
  392. package/dist/types/auth/pairing/WaPairingCodeCrypto.d.ts +17 -0
  393. package/dist/types/auth/pairing/WaPairingFlow.d.ts +48 -0
  394. package/dist/types/auth/pairing/WaQrFlow.d.ts +23 -0
  395. package/dist/types/auth/pairing/constants.d.ts +2 -0
  396. package/dist/types/auth/types.d.ts +48 -0
  397. package/dist/types/client/WaClient.d.ts +97 -0
  398. package/dist/types/client/WaClientFactory.d.ts +83 -0
  399. package/dist/types/client/coordinators/WaGroupCoordinator.d.ts +48 -0
  400. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +60 -0
  401. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +90 -0
  402. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +43 -0
  403. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +61 -0
  404. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +17 -0
  405. package/dist/types/client/dirty.d.ts +17 -0
  406. package/dist/types/client/events/chat.d.ts +3 -0
  407. package/dist/types/client/events/group.d.ts +7 -0
  408. package/dist/types/client/history-sync.d.ts +17 -0
  409. package/dist/types/client/incoming.d.ts +35 -0
  410. package/dist/types/client/index.d.ts +2 -0
  411. package/dist/types/client/mailbox.d.ts +12 -0
  412. package/dist/types/client/messages.d.ts +17 -0
  413. package/dist/types/client/types.d.ts +235 -0
  414. package/dist/types/crypto/core/constants.d.ts +1 -0
  415. package/dist/types/crypto/core/encoding.d.ts +11 -0
  416. package/dist/types/crypto/core/hkdf.d.ts +8 -0
  417. package/dist/types/crypto/core/index.d.ts +11 -0
  418. package/dist/types/crypto/core/keys.d.ts +20 -0
  419. package/dist/types/crypto/core/nonce.d.ts +5 -0
  420. package/dist/types/crypto/core/primitives.d.ts +25 -0
  421. package/dist/types/crypto/core/random.d.ts +8 -0
  422. package/dist/types/crypto/curves/Ed25519.d.ts +7 -0
  423. package/dist/types/crypto/curves/X25519.d.ts +8 -0
  424. package/dist/types/crypto/curves/constants.d.ts +2 -0
  425. package/dist/types/crypto/curves/types.d.ts +10 -0
  426. package/dist/types/crypto/index.d.ts +3 -0
  427. package/dist/types/crypto/math/constants.d.ts +7 -0
  428. package/dist/types/crypto/math/edwards.d.ts +3 -0
  429. package/dist/types/crypto/math/le.d.ts +2 -0
  430. package/dist/types/crypto/math/mod.d.ts +5 -0
  431. package/dist/types/crypto/math/types.d.ts +6 -0
  432. package/dist/types/index.d.ts +10 -0
  433. package/dist/types/infra/log/ConsoleLogger.d.ts +11 -0
  434. package/dist/types/infra/log/PinoLogger.d.ts +30 -0
  435. package/dist/types/infra/log/types.d.ts +9 -0
  436. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +19 -0
  437. package/dist/types/media/WaMediaCrypto.d.ts +12 -0
  438. package/dist/types/media/WaMediaTransferClient.d.ts +81 -0
  439. package/dist/types/media/conn.d.ts +3 -0
  440. package/dist/types/media/constants.d.ts +10 -0
  441. package/dist/types/media/index.d.ts +4 -0
  442. package/dist/types/media/types.d.ts +56 -0
  443. package/dist/types/message/WaMessageClient.d.ts +29 -0
  444. package/dist/types/message/ack.d.ts +5 -0
  445. package/dist/types/message/content.d.ts +4 -0
  446. package/dist/types/message/device-sent.d.ts +3 -0
  447. package/dist/types/message/incoming.d.ts +18 -0
  448. package/dist/types/message/index.d.ts +2 -0
  449. package/dist/types/message/padding.d.ts +2 -0
  450. package/dist/types/message/phash.d.ts +1 -0
  451. package/dist/types/message/types.d.ts +58 -0
  452. package/dist/types/proto.d.ts +2 -0
  453. package/dist/types/protocol/appstate.d.ts +34 -0
  454. package/dist/types/protocol/auth.d.ts +12 -0
  455. package/dist/types/protocol/browser.d.ts +22 -0
  456. package/dist/types/protocol/constants.d.ts +11 -0
  457. package/dist/types/protocol/defaults.d.ts +26 -0
  458. package/dist/types/protocol/dirty.d.ts +15 -0
  459. package/dist/types/protocol/group.d.ts +6 -0
  460. package/dist/types/protocol/index.d.ts +11 -0
  461. package/dist/types/protocol/jid.d.ts +19 -0
  462. package/dist/types/protocol/media.d.ts +15 -0
  463. package/dist/types/protocol/message.d.ts +16 -0
  464. package/dist/types/protocol/nodes.d.ts +83 -0
  465. package/dist/types/protocol/notification.d.ts +50 -0
  466. package/dist/types/protocol/stream.d.ts +60 -0
  467. package/dist/types/retry/constants.d.ts +21 -0
  468. package/dist/types/retry/index.d.ts +7 -0
  469. package/dist/types/retry/outbound.d.ts +4 -0
  470. package/dist/types/retry/parse.d.ts +3 -0
  471. package/dist/types/retry/reason.d.ts +2 -0
  472. package/dist/types/retry/replay.d.ts +30 -0
  473. package/dist/types/retry/types.d.ts +70 -0
  474. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +31 -0
  475. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +27 -0
  476. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +26 -0
  477. package/dist/types/signal/api/SignalMissingPreKeysSyncApi.d.ts +39 -0
  478. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +22 -0
  479. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +38 -0
  480. package/dist/types/signal/api/codec.d.ts +3 -0
  481. package/dist/types/signal/api/constants.d.ts +9 -0
  482. package/dist/types/signal/api/prekeys.d.ts +6 -0
  483. package/dist/types/signal/constants.d.ts +14 -0
  484. package/dist/types/signal/crypto/WaAdvSignature.d.ts +7 -0
  485. package/dist/types/signal/crypto/constants.d.ts +5 -0
  486. package/dist/types/signal/group/SenderKeyChain.d.ts +11 -0
  487. package/dist/types/signal/group/SenderKeyCodec.d.ts +14 -0
  488. package/dist/types/signal/group/SenderKeyManager.d.ts +22 -0
  489. package/dist/types/signal/index.d.ts +12 -0
  490. package/dist/types/signal/registration/keygen.d.ts +5 -0
  491. package/dist/types/signal/registration/utils.d.ts +9 -0
  492. package/dist/types/signal/session/SignalProtocol.d.ts +22 -0
  493. package/dist/types/signal/session/SignalRatchet.d.ts +25 -0
  494. package/dist/types/signal/session/SignalSerializer.d.ts +6 -0
  495. package/dist/types/signal/session/SignalSession.d.ts +43 -0
  496. package/dist/types/signal/store/sqlite.d.ts +72 -0
  497. package/dist/types/signal/types.d.ts +110 -0
  498. package/dist/types/store/contracts/appstate.store.d.ts +22 -0
  499. package/dist/types/store/contracts/auth.store.d.ts +6 -0
  500. package/dist/types/store/contracts/contact.store.d.ts +14 -0
  501. package/dist/types/store/contracts/device-list.store.d.ts +16 -0
  502. package/dist/types/store/contracts/message.store.d.ts +18 -0
  503. package/dist/types/store/contracts/participants.store.d.ts +14 -0
  504. package/dist/types/store/contracts/retry.store.d.ts +11 -0
  505. package/dist/types/store/contracts/sender-key.store.d.ts +16 -0
  506. package/dist/types/store/contracts/signal.store.d.ts +31 -0
  507. package/dist/types/store/contracts/thread.store.d.ts +17 -0
  508. package/dist/types/store/createStore.d.ts +2 -0
  509. package/dist/types/store/index.d.ts +31 -0
  510. package/dist/types/store/noop.store.d.ts +10 -0
  511. package/dist/types/store/providers/memory/appstate.store.d.ts +21 -0
  512. package/dist/types/store/providers/memory/contact.store.d.ts +13 -0
  513. package/dist/types/store/providers/memory/device-list.store.d.ts +20 -0
  514. package/dist/types/store/providers/memory/message.store.d.ts +14 -0
  515. package/dist/types/store/providers/memory/participants.store.d.ts +18 -0
  516. package/dist/types/store/providers/memory/retry.store.d.ts +18 -0
  517. package/dist/types/store/providers/memory/sender-key.store.d.ts +28 -0
  518. package/dist/types/store/providers/memory/signal.store.d.ts +51 -0
  519. package/dist/types/store/providers/memory/thread.store.d.ts +14 -0
  520. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +12 -0
  521. package/dist/types/store/providers/sqlite/appstate.store.d.ts +15 -0
  522. package/dist/types/store/providers/sqlite/auth.store.d.ts +10 -0
  523. package/dist/types/store/providers/sqlite/connection.d.ts +10 -0
  524. package/dist/types/store/providers/sqlite/contact.store.d.ts +10 -0
  525. package/dist/types/store/providers/sqlite/device-list.store.d.ts +18 -0
  526. package/dist/types/store/providers/sqlite/message.store.d.ts +11 -0
  527. package/dist/types/store/providers/sqlite/migrations.d.ts +3 -0
  528. package/dist/types/store/providers/sqlite/participants.store.d.ts +13 -0
  529. package/dist/types/store/providers/sqlite/retry.store.d.ts +16 -0
  530. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +25 -0
  531. package/dist/types/store/providers/sqlite/signal.store.d.ts +46 -0
  532. package/dist/types/store/providers/sqlite/thread.store.d.ts +11 -0
  533. package/dist/types/store/types.d.ts +103 -0
  534. package/dist/types/transport/WaComms.d.ts +61 -0
  535. package/dist/types/transport/WaWebSocket.d.ts +36 -0
  536. package/dist/types/transport/binary/constants.d.ts +49 -0
  537. package/dist/types/transport/binary/decoder.d.ts +3 -0
  538. package/dist/types/transport/binary/encoder.d.ts +3 -0
  539. package/dist/types/transport/binary/index.d.ts +4 -0
  540. package/dist/types/transport/binary/tokens.d.ts +11 -0
  541. package/dist/types/transport/index.d.ts +7 -0
  542. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +39 -0
  543. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +28 -0
  544. package/dist/types/transport/node/WaNodeTransport.d.ts +22 -0
  545. package/dist/types/transport/node/builders/accountSync.d.ts +11 -0
  546. package/dist/types/transport/node/builders/group.d.ts +16 -0
  547. package/dist/types/transport/node/builders/index.d.ts +7 -0
  548. package/dist/types/transport/node/builders/media.d.ts +2 -0
  549. package/dist/types/transport/node/builders/message.d.ts +52 -0
  550. package/dist/types/transport/node/builders/pairing.d.ts +18 -0
  551. package/dist/types/transport/node/builders/prekeys.d.ts +5 -0
  552. package/dist/types/transport/node/builders/retry.d.ts +18 -0
  553. package/dist/types/transport/node/helpers.d.ts +8 -0
  554. package/dist/types/transport/node/query.d.ts +10 -0
  555. package/dist/types/transport/node/xml.d.ts +2 -0
  556. package/dist/types/transport/noise/WaClientPayload.d.ts +3 -0
  557. package/dist/types/transport/noise/WaFrameCodec.d.ts +9 -0
  558. package/dist/types/transport/noise/WaNoiseCert.d.ts +1 -0
  559. package/dist/types/transport/noise/WaNoiseHandshake.d.ts +14 -0
  560. package/dist/types/transport/noise/WaNoiseSession.d.ts +33 -0
  561. package/dist/types/transport/noise/WaNoiseSocket.d.ts +10 -0
  562. package/dist/types/transport/noise/constants.d.ts +7 -0
  563. package/dist/types/transport/noise/types.d.ts +23 -0
  564. package/dist/types/transport/stream/parse.d.ts +23 -0
  565. package/dist/types/transport/types.d.ts +71 -0
  566. package/dist/types/util/async.d.ts +1 -0
  567. package/dist/types/util/base64.d.ts +4 -0
  568. package/dist/types/util/bytes.d.ts +28 -0
  569. package/dist/types/util/coercion.d.ts +8 -0
  570. package/dist/types/util/collections.d.ts +3 -0
  571. package/dist/types/util/primitives.d.ts +7 -0
  572. package/dist/types/util/runtime.d.ts +2 -0
  573. package/dist/types/util/signal-address.d.ts +2 -0
  574. package/dist/util/async.js +8 -0
  575. package/dist/util/base64.js +24 -0
  576. package/dist/util/bytes.js +291 -0
  577. package/dist/util/coercion.js +66 -0
  578. package/dist/util/collections.js +32 -0
  579. package/dist/util/primitives.js +37 -0
  580. package/dist/util/runtime.js +19 -0
  581. package/dist/util/signal-address.js +8 -0
  582. package/package.json +150 -0
  583. package/proto/index.d.ts +10861 -0
  584. package/proto/index.js +1 -0
  585. package/scripts/check-node-version.cjs +55 -0
@@ -0,0 +1,23 @@
1
+ import { decodeNodeContentBase64OrBytes } from '../../transport/node/helpers.js';
2
+ export function decodeExactLength(value, field, expectedLength) {
3
+ const bytes = decodeNodeContentBase64OrBytes(value, field);
4
+ if (bytes.byteLength !== expectedLength) {
5
+ throw new Error(`${field} must be ${expectedLength} bytes`);
6
+ }
7
+ return bytes;
8
+ }
9
+ export function parseUint(bytes, field) {
10
+ if (bytes.byteLength === 1) {
11
+ return bytes[0];
12
+ }
13
+ if (bytes.byteLength === 2) {
14
+ return (bytes[0] << 8) | bytes[1];
15
+ }
16
+ if (bytes.byteLength === 3) {
17
+ return (bytes[0] << 16) | (bytes[1] << 8) | bytes[2];
18
+ }
19
+ if (bytes.byteLength === 4) {
20
+ return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0, false);
21
+ }
22
+ throw new Error(`${field} has invalid byte length`);
23
+ }
@@ -0,0 +1,9 @@
1
+ export const SIGNAL_UPLOAD_PREKEYS_COUNT = 812;
2
+ export const SIGNAL_SIGNED_PREKEY_ROTATION_INTERVAL_MS = 27 * 24 * 60 * 60 * 1000;
3
+ export const SIGNAL_SIGNED_PREKEY_SERVER_ERROR_BACKOFF_MS = 24 * 60 * 60 * 1000;
4
+ export const SIGNAL_KEY_BUNDLE_TYPE_BYTES = new Uint8Array([5]);
5
+ export const SIGNAL_KEY_BUNDLE_TYPE_LENGTH = 1;
6
+ export const SIGNAL_REGISTRATION_ID_LENGTH = 4;
7
+ export const SIGNAL_KEY_ID_LENGTH = 3;
8
+ export const SIGNAL_KEY_DATA_LENGTH = 32;
9
+ export const SIGNAL_SIGNATURE_LENGTH = 64;
@@ -0,0 +1,9 @@
1
+ import { parseIqError } from '../../transport/node/query.js';
2
+ export { buildMissingPreKeysFetchIq, buildPreKeyUploadIq, buildSignedPreKeyRotateIq } from '../../transport/node/builders/prekeys.js';
3
+ export function parsePreKeyUploadFailure(node) {
4
+ const error = parseIqError(node);
5
+ return {
6
+ ...(error.numericCode !== undefined ? { errorCode: error.numericCode } : {}),
7
+ errorText: error.text
8
+ };
9
+ }
@@ -0,0 +1,16 @@
1
+ import { SERIALIZED_PUB_KEY_PREFIX as CORE_SERIALIZED_PUB_KEY_PREFIX } from '../crypto/core/constants.js';
2
+ import { TEXT_ENCODER } from '../util/bytes.js';
3
+ export const SIGNAL_VERSION = 3;
4
+ export const SIGNAL_GROUP_VERSION = 3;
5
+ export const SERIALIZED_PUB_KEY_PREFIX = CORE_SERIALIZED_PUB_KEY_PREFIX;
6
+ export const KEY_TYPE_CURVE25519 = 5;
7
+ export const SIGNAL_MAC_SIZE = 8;
8
+ export const SIGNATURE_SIZE = 64;
9
+ export const MAX_PREV_SESSIONS = 40;
10
+ export const MAX_UNUSED_KEYS = 2000;
11
+ export const FUTURE_MESSAGES_MAX = 2000;
12
+ export const SENDER_KEY_FUTURE_MESSAGES_MAX = 20000;
13
+ export const MESSAGE_KEY_LABEL = new Uint8Array([1]);
14
+ export const CHAIN_KEY_LABEL = new Uint8Array([2]);
15
+ export const WHISPER_GROUP_INFO = TEXT_ENCODER.encode('WhisperGroup');
16
+ export const SIGNAL_PREFIX = new Uint8Array(32).fill(0xff);
@@ -0,0 +1,60 @@
1
+ import { ed25519VerifyRaw, importHmacKey, hmacSign, randomBytesAsync, sha512, toRawPubKey } from '../../crypto/index.js';
2
+ import { clampCurvePrivateKeyInPlace, montgomeryToEdwardsPublic } from '../../crypto/curves/X25519.js';
3
+ import { encodeExtendedPoint, scalarMultBase } from '../../crypto/math/edwards.js';
4
+ import { bytesToBigIntLE, bigIntToBytesLE } from '../../crypto/math/le.js';
5
+ import { modGroup } from '../../crypto/math/mod.js';
6
+ import { ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE, ADV_PREFIX_HOSTED_DEVICE_SIGNATURE, SIGNAL_PREFIX_SIGNATURE_RANDOM } from '../crypto/constants.js';
7
+ import { concatBytes } from '../../util/bytes.js';
8
+ export { ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE, ADV_PREFIX_HOSTED_DEVICE_SIGNATURE } from '../crypto/constants.js';
9
+ export async function verifySignalSignature(publicKey, message, signature) {
10
+ if (signature.length !== 64) {
11
+ return false;
12
+ }
13
+ if ((signature[63] & 0x60) !== 0) {
14
+ return false;
15
+ }
16
+ const signalSignature = new Uint8Array(signature);
17
+ const signBit = signalSignature[63] & 0x80;
18
+ signalSignature[63] &= 0x7f;
19
+ const curvePublic = toRawPubKey(publicKey);
20
+ const edPublic = montgomeryToEdwardsPublic(curvePublic, signBit);
21
+ return ed25519VerifyRaw(edPublic, signalSignature, message);
22
+ }
23
+ export async function signSignalMessage(privateKey, message) {
24
+ if (privateKey.length !== 32) {
25
+ throw new Error(`invalid curve25519 private key length ${privateKey.length}`);
26
+ }
27
+ const clampedPrivateKey = clampCurvePrivateKeyInPlace(privateKey);
28
+ const privateScalar = bytesToBigIntLE(clampedPrivateKey);
29
+ const encodedPublic = encodeExtendedPoint(scalarMultBase(privateScalar));
30
+ const pubKeySignBit = encodedPublic[31] & 0x80;
31
+ const randomSuffix = await randomBytesAsync(64);
32
+ const hashInput = concatBytes([
33
+ SIGNAL_PREFIX_SIGNATURE_RANDOM,
34
+ clampedPrivateKey,
35
+ message,
36
+ randomSuffix
37
+ ]);
38
+ const r = modGroup(bytesToBigIntLE(await sha512(hashInput)));
39
+ const encodedR = encodeExtendedPoint(scalarMultBase(r));
40
+ const hInput = concatBytes([encodedR, encodedPublic, message]);
41
+ const h = modGroup(bytesToBigIntLE(await sha512(hInput)));
42
+ const s = modGroup(r + h * privateScalar);
43
+ const encodedS = bigIntToBytesLE(s, 32);
44
+ encodedS[31] = (encodedS[31] & 0x7f) | pubKeySignBit;
45
+ return concatBytes([encodedR, encodedS]);
46
+ }
47
+ export async function verifyDeviceIdentityAccountSignature(details, accountSignature, identityPublicKey, accountSignatureKey, isHosted = false) {
48
+ const prefix = isHosted ? ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE : ADV_PREFIX_ACCOUNT_SIGNATURE;
49
+ const message = concatBytes([prefix, details, identityPublicKey]);
50
+ return verifySignalSignature(accountSignatureKey, message, accountSignature);
51
+ }
52
+ export async function generateDeviceSignature(details, identityKeyPair, accountSignatureKey, isHosted = false) {
53
+ const prefix = isHosted ? ADV_PREFIX_HOSTED_DEVICE_SIGNATURE : ADV_PREFIX_DEVICE_SIGNATURE;
54
+ const message = concatBytes([prefix, details, identityKeyPair.pubKey, accountSignatureKey]);
55
+ return signSignalMessage(identityKeyPair.privKey, message);
56
+ }
57
+ export async function computeAdvIdentityHmac(secretKey, details) {
58
+ const key = await importHmacKey(secretKey);
59
+ return hmacSign(key, details);
60
+ }
@@ -0,0 +1,8 @@
1
+ export const SIGNAL_PREFIX_SIGNATURE_RANDOM = new Uint8Array([
2
+ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
4
+ ]);
5
+ export const ADV_PREFIX_ACCOUNT_SIGNATURE = new Uint8Array([6, 0]);
6
+ export const ADV_PREFIX_DEVICE_SIGNATURE = new Uint8Array([6, 1]);
7
+ export const ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = new Uint8Array([6, 5]);
8
+ export const ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = new Uint8Array([6, 6]);
@@ -0,0 +1,97 @@
1
+ import { hkdf, importHmacKey, hmacSign } from '../../crypto/index.js';
2
+ import { CHAIN_KEY_LABEL, MAX_UNUSED_KEYS, MESSAGE_KEY_LABEL, SENDER_KEY_FUTURE_MESSAGES_MAX, WHISPER_GROUP_INFO } from '../constants.js';
3
+ import { removeAt } from '../../util/bytes.js';
4
+ export async function selectMessageKey(senderKey, targetIteration) {
5
+ const delta = targetIteration - senderKey.iteration;
6
+ if (delta > SENDER_KEY_FUTURE_MESSAGES_MAX) {
7
+ throw new Error('sender key message is too far in future');
8
+ }
9
+ const currentUnused = senderKey.unusedMessageKeys ?? [];
10
+ if (delta < 0) {
11
+ const foundIndex = currentUnused.findIndex((entry) => entry.iteration === targetIteration);
12
+ if (foundIndex === -1) {
13
+ throw new Error('sender key message iteration is stale');
14
+ }
15
+ const messageKey = currentUnused[foundIndex];
16
+ const nextUnused = removeAt(currentUnused, foundIndex);
17
+ return {
18
+ messageKey,
19
+ updatedRecord: {
20
+ ...senderKey,
21
+ unusedMessageKeys: nextUnused
22
+ }
23
+ };
24
+ }
25
+ let chainState = await createSenderChainState(senderKey.chainKey);
26
+ const firstDerived = await deriveSenderKeyMsgKeyFromState(senderKey.iteration, chainState);
27
+ chainState = firstDerived.nextState;
28
+ let messageKey = firstDerived.messageKey;
29
+ let nextUnused = currentUnused.slice();
30
+ if (delta > 0) {
31
+ let overflow = delta + currentUnused.length - MAX_UNUSED_KEYS;
32
+ if (overflow > 0) {
33
+ nextUnused = nextUnused.slice(overflow);
34
+ overflow -= currentUnused.length;
35
+ }
36
+ for (let iteration = senderKey.iteration + 1; iteration <= targetIteration; iteration += 1) {
37
+ if (overflow > 0) {
38
+ overflow -= 1;
39
+ }
40
+ else {
41
+ nextUnused.push(messageKey);
42
+ }
43
+ const derived = await deriveSenderKeyMsgKeyFromState(iteration, chainState);
44
+ chainState = derived.nextState;
45
+ messageKey = derived.messageKey;
46
+ }
47
+ }
48
+ return {
49
+ messageKey,
50
+ updatedRecord: {
51
+ ...senderKey,
52
+ iteration: targetIteration + 1,
53
+ chainKey: chainState.chainKey,
54
+ unusedMessageKeys: nextUnused
55
+ }
56
+ };
57
+ }
58
+ export async function deriveSenderKeyMsgKey(iteration, chainKey) {
59
+ const state = await createSenderChainState(chainKey);
60
+ const derived = await deriveSenderKeyMsgKeyFromState(iteration, state);
61
+ return {
62
+ nextChainKey: derived.nextState.chainKey,
63
+ messageKey: derived.messageKey
64
+ };
65
+ }
66
+ async function createSenderChainState(chainKey) {
67
+ if (chainKey.length !== 32) {
68
+ throw new Error('sender key chainKey must be 32 bytes');
69
+ }
70
+ return {
71
+ chainKey,
72
+ hmacKey: await importHmacKey(chainKey)
73
+ };
74
+ }
75
+ async function deriveSenderKeyMsgKeyFromState(iteration, state) {
76
+ const nextChainRawPromise = hmacSign(state.hmacKey, CHAIN_KEY_LABEL);
77
+ const messageInputKeyPromise = hmacSign(state.hmacKey, MESSAGE_KEY_LABEL);
78
+ const [nextChainRaw, messageInputKey] = await Promise.all([
79
+ nextChainRawPromise,
80
+ messageInputKeyPromise
81
+ ]);
82
+ const nextChainKey = nextChainRaw.subarray(0, 32);
83
+ const [nextHmacKey, messageSeed] = await Promise.all([
84
+ importHmacKey(nextChainKey),
85
+ hkdf(messageInputKey, null, WHISPER_GROUP_INFO, 50)
86
+ ]);
87
+ return {
88
+ nextState: {
89
+ chainKey: nextChainKey,
90
+ hmacKey: nextHmacKey
91
+ },
92
+ messageKey: {
93
+ iteration,
94
+ seed: messageSeed
95
+ }
96
+ };
97
+ }
@@ -0,0 +1,46 @@
1
+ import { readVersionedContent, toSerializedPubKey } from '../../crypto/index.js';
2
+ import { proto } from '../../proto.js';
3
+ import { SIGNATURE_SIZE, SIGNAL_GROUP_VERSION } from '../constants.js';
4
+ import { toBytesView } from '../../util/bytes.js';
5
+ export function parseDistributionPayload(payload) {
6
+ const body = readVersionedContent(payload, SIGNAL_GROUP_VERSION, 0);
7
+ const decoded = proto.SenderKeyDistributionMessage.decode(body);
8
+ if (decoded.id === null ||
9
+ decoded.id === undefined ||
10
+ decoded.iteration === null ||
11
+ decoded.iteration === undefined ||
12
+ decoded.chainKey === null ||
13
+ decoded.chainKey === undefined ||
14
+ decoded.signingKey === null ||
15
+ decoded.signingKey === undefined) {
16
+ throw new Error('invalid sender key distribution message');
17
+ }
18
+ const chainKey = toBytesView(decoded.chainKey);
19
+ if (chainKey.length !== 32) {
20
+ throw new Error('sender key distribution chainKey must be 32 bytes');
21
+ }
22
+ return {
23
+ keyId: decoded.id,
24
+ iteration: decoded.iteration,
25
+ chainKey,
26
+ signingPublicKey: toSerializedPubKey(toBytesView(decoded.signingKey))
27
+ };
28
+ }
29
+ export function parseSenderKeyMessage(versionContentMac) {
30
+ const body = readVersionedContent(versionContentMac, SIGNAL_GROUP_VERSION, SIGNATURE_SIZE);
31
+ const decoded = proto.SenderKeyMessage.decode(body);
32
+ if (decoded.id === null ||
33
+ decoded.id === undefined ||
34
+ decoded.iteration === null ||
35
+ decoded.iteration === undefined ||
36
+ decoded.ciphertext === null ||
37
+ decoded.ciphertext === undefined) {
38
+ throw new Error('invalid sender key message');
39
+ }
40
+ return {
41
+ keyId: decoded.id,
42
+ iteration: decoded.iteration,
43
+ ciphertext: toBytesView(decoded.ciphertext),
44
+ versionContentMac
45
+ };
46
+ }
@@ -0,0 +1,176 @@
1
+ import { aesCbcDecrypt, aesCbcEncrypt, importAesCbcKey, toSerializedPubKey, prependVersion, randomBytesAsync, randomIntAsync, X25519 } from '../../crypto/index.js';
2
+ import { proto } from '../../proto.js';
3
+ import { SIGNAL_GROUP_VERSION, SIGNATURE_SIZE } from '../constants.js';
4
+ import { signSignalMessage, verifySignalSignature } from '../crypto/WaAdvSignature.js';
5
+ import { deriveSenderKeyMsgKey, selectMessageKey } from '../group/SenderKeyChain.js';
6
+ import { parseDistributionPayload, parseSenderKeyMessage } from '../group/SenderKeyCodec.js';
7
+ import { concatBytes } from '../../util/bytes.js';
8
+ function extractAesCbcParams(seed) {
9
+ if (seed.length < 48) {
10
+ throw new Error('sender key message seed must be at least 48 bytes');
11
+ }
12
+ return {
13
+ iv: seed.subarray(0, 16),
14
+ keyBytes: seed.subarray(16, 48)
15
+ };
16
+ }
17
+ async function aesCbcEncryptFromSeed(seed, plaintext) {
18
+ const { keyBytes, iv } = extractAesCbcParams(seed);
19
+ return aesCbcEncrypt(await importAesCbcKey(keyBytes), iv, plaintext);
20
+ }
21
+ async function aesCbcDecryptFromSeed(seed, ciphertext) {
22
+ const { keyBytes, iv } = extractAesCbcParams(seed);
23
+ return aesCbcDecrypt(await importAesCbcKey(keyBytes), iv, ciphertext);
24
+ }
25
+ export class SenderKeyManager {
26
+ constructor(store) {
27
+ this.store = store;
28
+ }
29
+ async createSenderKeyDistributionMessage(groupId, sender) {
30
+ const senderKey = await this.ensureSenderKey(groupId, sender);
31
+ const distributionProto = proto.SenderKeyDistributionMessage.encode({
32
+ id: senderKey.keyId,
33
+ iteration: senderKey.iteration,
34
+ chainKey: senderKey.chainKey,
35
+ signingKey: senderKey.signingPublicKey
36
+ }).finish();
37
+ const payload = prependVersion(distributionProto, SIGNAL_GROUP_VERSION);
38
+ await this.store.upsertSenderKeyDistribution({
39
+ groupId,
40
+ sender,
41
+ keyId: senderKey.keyId,
42
+ timestampMs: Date.now()
43
+ });
44
+ return {
45
+ groupId,
46
+ axolotlSenderKeyDistributionMessage: payload
47
+ };
48
+ }
49
+ async filterParticipantsNeedingDistribution(groupId, sender, participants) {
50
+ if (participants.length === 0) {
51
+ return [];
52
+ }
53
+ const senderKey = await this.ensureSenderKey(groupId, sender);
54
+ const distributed = await this.store.getDeviceSenderKeyDistributions(groupId, participants);
55
+ return participants.filter((_, index) => {
56
+ const record = distributed[index];
57
+ return !record || record.keyId !== senderKey.keyId;
58
+ });
59
+ }
60
+ async markSenderKeyDistributed(groupId, sender, participants) {
61
+ if (participants.length === 0) {
62
+ return;
63
+ }
64
+ const senderKey = await this.ensureSenderKey(groupId, sender);
65
+ const timestampMs = Date.now();
66
+ await this.store.upsertSenderKeyDistributions(participants.map((participant) => ({
67
+ groupId,
68
+ sender: participant,
69
+ keyId: senderKey.keyId,
70
+ timestampMs
71
+ })));
72
+ }
73
+ async processSenderKeyDistributionPayload(groupId, sender, payload) {
74
+ if (groupId.length === 0) {
75
+ throw new Error('sender key distribution missing groupId');
76
+ }
77
+ const parsed = parseDistributionPayload(payload);
78
+ const record = {
79
+ groupId,
80
+ sender,
81
+ keyId: parsed.keyId,
82
+ iteration: parsed.iteration,
83
+ chainKey: parsed.chainKey,
84
+ signingPublicKey: parsed.signingPublicKey,
85
+ unusedMessageKeys: []
86
+ };
87
+ await this.store.upsertSenderKey(record);
88
+ await this.store.upsertSenderKeyDistribution({
89
+ groupId,
90
+ sender,
91
+ keyId: parsed.keyId,
92
+ timestampMs: Date.now()
93
+ });
94
+ return record;
95
+ }
96
+ async encryptGroupMessage(groupId, sender, plaintext) {
97
+ const senderKey = await this.ensureSenderKey(groupId, sender);
98
+ if (!senderKey.signingPrivateKey) {
99
+ throw new Error('sender private signing key is missing');
100
+ }
101
+ const derived = await deriveSenderKeyMsgKey(senderKey.iteration, senderKey.chainKey);
102
+ const messagePayload = await aesCbcEncryptFromSeed(derived.messageKey.seed, plaintext);
103
+ const senderKeyMessage = proto.SenderKeyMessage.encode({
104
+ id: senderKey.keyId,
105
+ iteration: derived.messageKey.iteration,
106
+ ciphertext: messagePayload
107
+ }).finish();
108
+ const versionedContent = prependVersion(senderKeyMessage, SIGNAL_GROUP_VERSION);
109
+ const signature = await signSignalMessage(senderKey.signingPrivateKey, versionedContent);
110
+ if (signature.length !== SIGNATURE_SIZE) {
111
+ throw new Error(`invalid sender key signature length ${signature.length}`);
112
+ }
113
+ const ciphertext = concatBytes([versionedContent, signature]);
114
+ await this.store.upsertSenderKey({
115
+ ...senderKey,
116
+ chainKey: derived.nextChainKey,
117
+ iteration: derived.messageKey.iteration + 1
118
+ });
119
+ return {
120
+ groupId,
121
+ sender,
122
+ keyId: senderKey.keyId,
123
+ iteration: derived.messageKey.iteration,
124
+ ciphertext
125
+ };
126
+ }
127
+ async decryptGroupMessage(payload) {
128
+ const parsed = parseSenderKeyMessage(payload.ciphertext);
129
+ const senderKey = await this.store.getDeviceSenderKey(payload.groupId, payload.sender);
130
+ if (!senderKey) {
131
+ throw new Error('missing sender key');
132
+ }
133
+ if (senderKey.keyId !== parsed.keyId) {
134
+ throw new Error('sender key id mismatch');
135
+ }
136
+ if (payload.keyId !== undefined &&
137
+ payload.keyId !== null &&
138
+ parsed.keyId !== payload.keyId) {
139
+ throw new Error('sender key id mismatch');
140
+ }
141
+ if (payload.iteration !== undefined &&
142
+ payload.iteration !== null &&
143
+ parsed.iteration !== payload.iteration) {
144
+ throw new Error('sender key iteration mismatch');
145
+ }
146
+ const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - SIGNATURE_SIZE);
147
+ const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - SIGNATURE_SIZE);
148
+ const validSignature = await verifySignalSignature(senderKey.signingPublicKey, signedContent, signature);
149
+ if (!validSignature) {
150
+ throw new Error('invalid sender key signature');
151
+ }
152
+ const selected = await selectMessageKey(senderKey, parsed.iteration);
153
+ const plaintext = await aesCbcDecryptFromSeed(selected.messageKey.seed, parsed.ciphertext);
154
+ await this.store.upsertSenderKey(selected.updatedRecord);
155
+ return plaintext;
156
+ }
157
+ async ensureSenderKey(groupId, sender) {
158
+ const existing = await this.store.getDeviceSenderKey(groupId, sender);
159
+ if (existing) {
160
+ return existing;
161
+ }
162
+ const signingKeyPair = await X25519.generateKeyPair();
163
+ const created = {
164
+ groupId,
165
+ sender,
166
+ keyId: await randomIntAsync(1, 2147483647),
167
+ iteration: 0,
168
+ chainKey: await randomBytesAsync(32),
169
+ signingPublicKey: toSerializedPubKey(signingKeyPair.pubKey),
170
+ signingPrivateKey: signingKeyPair.privKey,
171
+ unusedMessageKeys: []
172
+ };
173
+ await this.store.upsertSenderKey(created);
174
+ return created;
175
+ }
176
+ }
@@ -0,0 +1,11 @@
1
+ export { generatePreKeyPair, generateRegistrationId, generateRegistrationInfo, generateSignedPreKey } from './registration/keygen.js';
2
+ export { buildPreKeyUploadIq, parsePreKeyUploadFailure } from './api/prekeys.js';
3
+ export { SignalDigestSyncApi } from './api/SignalDigestSyncApi.js';
4
+ export { SignalDeviceSyncApi } from './api/SignalDeviceSyncApi.js';
5
+ export { SignalIdentitySyncApi } from './api/SignalIdentitySyncApi.js';
6
+ export { SignalMissingPreKeysSyncApi } from './api/SignalMissingPreKeysSyncApi.js';
7
+ export { SignalRotateKeyApi } from './api/SignalRotateKeyApi.js';
8
+ export { SignalSessionSyncApi } from './api/SignalSessionSyncApi.js';
9
+ export { SenderKeyManager } from './group/SenderKeyManager.js';
10
+ export { createAndStoreInitialKeys } from './registration/utils.js';
11
+ export { SignalProtocol } from './session/SignalProtocol.js';
@@ -0,0 +1,31 @@
1
+ import { randomIntAsync } from '../../crypto/index.js';
2
+ import { toSerializedPubKey } from '../../crypto/core/keys.js';
3
+ import { X25519 } from '../../crypto/curves/X25519.js';
4
+ import { signSignalMessage } from '../crypto/WaAdvSignature.js';
5
+ export async function generateRegistrationInfo() {
6
+ return {
7
+ registrationId: await generateRegistrationId(),
8
+ identityKeyPair: await X25519.generateKeyPair()
9
+ };
10
+ }
11
+ export async function generatePreKeyPair(keyId) {
12
+ return {
13
+ keyId,
14
+ keyPair: await X25519.generateKeyPair(),
15
+ uploaded: false
16
+ };
17
+ }
18
+ export async function generateSignedPreKey(keyId, signingPrivateKey) {
19
+ const keyPair = await X25519.generateKeyPair();
20
+ const serializedPubKey = toSerializedPubKey(keyPair.pubKey);
21
+ const signature = await signSignalMessage(signingPrivateKey, serializedPubKey);
22
+ return {
23
+ keyId,
24
+ keyPair,
25
+ signature,
26
+ uploaded: false
27
+ };
28
+ }
29
+ export async function generateRegistrationId() {
30
+ return await randomIntAsync(1, 16381);
31
+ }
@@ -0,0 +1,16 @@
1
+ import { generatePreKeyPair, generateRegistrationInfo, generateSignedPreKey } from '../registration/keygen.js';
2
+ export async function createAndStoreInitialKeys(store) {
3
+ const [registrationInfo, firstPreKey] = await Promise.all([
4
+ generateRegistrationInfo(),
5
+ generatePreKeyPair(1)
6
+ ]);
7
+ const signedPreKey = await generateSignedPreKey(1, registrationInfo.identityKeyPair.privKey);
8
+ await store.setRegistrationInfo(registrationInfo);
9
+ await store.setSignedPreKey(signedPreKey);
10
+ await store.getOrGenSinglePreKey(async () => firstPreKey);
11
+ return {
12
+ registrationInfo,
13
+ signedPreKey,
14
+ firstPreKey
15
+ };
16
+ }
@@ -0,0 +1,122 @@
1
+ import { toSerializedPubKey } from '../../crypto/index.js';
2
+ import { ConsoleLogger } from '../../infra/log/ConsoleLogger.js';
3
+ import { MAX_PREV_SESSIONS } from '../constants.js';
4
+ import { decryptMsg, decryptMsgFromSession, encryptMsg } from '../session/SignalRatchet.js';
5
+ import { deserializeMsg, deserializePkMsg, requirePreKey, requireSignedPreKey } from '../session/SignalSerializer.js';
6
+ import { detachSession, findMatchingSession, generateSerializedKeyPair, initiateSessionIncoming, initiateSessionOutgoing, requireLocalIdentity, toSerializedKeyPair } from '../session/SignalSession.js';
7
+ import { uint8Equal } from '../../util/bytes.js';
8
+ export class SignalProtocol {
9
+ constructor(store, logger = new ConsoleLogger('info')) {
10
+ this.store = store;
11
+ this.logger = logger;
12
+ }
13
+ async hasSession(address) {
14
+ return this.store.hasSession(address);
15
+ }
16
+ async hasSessions(addresses) {
17
+ return this.store.hasSessions(addresses);
18
+ }
19
+ async establishOutgoingSession(address, remoteBundle) {
20
+ const [local, localOneTimeBase] = await Promise.all([
21
+ requireLocalIdentity(this.store),
22
+ generateSerializedKeyPair()
23
+ ]);
24
+ const session = await initiateSessionOutgoing(local, remoteBundle, localOneTimeBase);
25
+ await this.store.setRemoteIdentity(address, session.remote.pubKey);
26
+ await this.store.setSession(address, session);
27
+ return session;
28
+ }
29
+ async encryptMessage(address, plaintext, expectedIdentity) {
30
+ const session = await this.store.getSession(address);
31
+ if (!session) {
32
+ throw new Error('signal session not found');
33
+ }
34
+ if (expectedIdentity &&
35
+ !uint8Equal(toSerializedPubKey(expectedIdentity), session.remote.pubKey)) {
36
+ throw new Error('identity mismatch');
37
+ }
38
+ const [updatedSession, encrypted] = await encryptMsg(session, plaintext);
39
+ await this.store.setSession(address, updatedSession);
40
+ if (!uint8Equal(updatedSession.remote.pubKey, session.remote.pubKey)) {
41
+ await this.store.setRemoteIdentity(address, updatedSession.remote.pubKey);
42
+ }
43
+ return {
44
+ ...encrypted,
45
+ baseKey: updatedSession.aliceBaseKey
46
+ };
47
+ }
48
+ async decryptMessage(address, envelope) {
49
+ const currentSession = await this.store.getSession(address);
50
+ let outcome;
51
+ if (envelope.type === 'pkmsg') {
52
+ const parsedPk = deserializePkMsg(envelope.ciphertext);
53
+ outcome = await this.decryptPkMsg(currentSession, parsedPk);
54
+ }
55
+ else {
56
+ const parsed = deserializeMsg(envelope.ciphertext);
57
+ outcome = await this.decryptMsgInternal(currentSession, parsed);
58
+ }
59
+ const nextRemoteIdentity = outcome.newSessionInfo?.newIdentity ?? outcome.updatedSession.remote.pubKey;
60
+ if (!currentSession || !uint8Equal(currentSession.remote.pubKey, nextRemoteIdentity)) {
61
+ await this.store.setRemoteIdentity(address, nextRemoteIdentity);
62
+ }
63
+ await this.store.setSession(address, outcome.updatedSession);
64
+ return outcome.plaintext;
65
+ }
66
+ async decryptMsgInternal(session, parsed) {
67
+ return decryptMsg(session, parsed, (error, previousSessionIndex) => {
68
+ this.logger.debug('signal decrypt fallback session failed', {
69
+ previousSessionIndex,
70
+ message: error.message
71
+ });
72
+ });
73
+ }
74
+ async decryptPkMsg(currentSession, parsed) {
75
+ const matchingSession = findMatchingSession(currentSession, parsed.sessionBaseKey);
76
+ if (matchingSession) {
77
+ const [updatedSession, plaintext] = await decryptMsgFromSession(matchingSession, parsed);
78
+ return {
79
+ updatedSession,
80
+ plaintext,
81
+ newSessionInfo: null
82
+ };
83
+ }
84
+ const [local, signedPreKey, oneTimePreKey] = await Promise.all([
85
+ requireLocalIdentity(this.store),
86
+ requireSignedPreKey(this.store, parsed.localSignedPreKeyId),
87
+ parsed.localOneTimeKeyId === null || parsed.localOneTimeKeyId === undefined
88
+ ? Promise.resolve(null)
89
+ : requirePreKey(this.store, parsed.localOneTimeKeyId)
90
+ ]);
91
+ const incoming = await initiateSessionIncoming(local, parsed.remote, parsed.sessionBaseKey, {
92
+ signed: toSerializedKeyPair(signedPreKey.keyPair),
93
+ oneTime: oneTimePreKey ? toSerializedKeyPair(oneTimePreKey.keyPair) : undefined,
94
+ ratchet: toSerializedKeyPair(signedPreKey.keyPair)
95
+ });
96
+ const newIdentity = !currentSession || !uint8Equal(incoming.remote.pubKey, currentSession.remote.pubKey)
97
+ ? incoming.remote.pubKey
98
+ : null;
99
+ const baseSession = currentSession
100
+ ? {
101
+ ...incoming,
102
+ prevSessions: [
103
+ detachSession(currentSession),
104
+ ...currentSession.prevSessions.slice(0, MAX_PREV_SESSIONS - 1)
105
+ ]
106
+ }
107
+ : incoming;
108
+ const [updatedSession, plaintext] = await decryptMsgFromSession(baseSession, parsed);
109
+ if (parsed.localOneTimeKeyId !== null && parsed.localOneTimeKeyId !== undefined) {
110
+ await this.store.consumePreKeyById(parsed.localOneTimeKeyId);
111
+ }
112
+ return {
113
+ updatedSession,
114
+ plaintext,
115
+ newSessionInfo: {
116
+ newIdentity,
117
+ baseSession,
118
+ usedPreKey: parsed.localOneTimeKeyId
119
+ }
120
+ };
121
+ }
122
+ }