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,179 @@
1
+ import { sha1 } from '../../crypto/index.js';
2
+ import { WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../../protocol/constants.js';
3
+ import { decodeExactLength, parseUint } from '../api/codec.js';
4
+ import { SIGNAL_KEY_BUNDLE_TYPE_BYTES, SIGNAL_KEY_BUNDLE_TYPE_LENGTH, SIGNAL_KEY_DATA_LENGTH, SIGNAL_KEY_ID_LENGTH, SIGNAL_REGISTRATION_ID_LENGTH, SIGNAL_SIGNATURE_LENGTH } from '../api/constants.js';
5
+ import { decodeNodeContentBase64OrBytes, findNodeChild, getNodeChildren } from '../../transport/node/helpers.js';
6
+ import { parseIqError } from '../../transport/node/query.js';
7
+ import { concatBytes, uint8Equal } from '../../util/bytes.js';
8
+ export class SignalDigestSyncApi {
9
+ constructor(options) {
10
+ this.logger = options.logger;
11
+ this.query = options.query;
12
+ this.signalStore = options.signalStore;
13
+ this.defaultTimeoutMs =
14
+ options.defaultTimeoutMs ?? WA_DEFAULTS.SIGNAL_FETCH_KEY_BUNDLES_TIMEOUT_MS;
15
+ this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
16
+ }
17
+ async validateLocalKeyBundle(timeoutMs = this.defaultTimeoutMs) {
18
+ this.logger.debug('signal digest query request', { timeoutMs });
19
+ const response = await this.query({
20
+ tag: WA_NODE_TAGS.IQ,
21
+ attrs: {
22
+ type: WA_IQ_TYPES.GET,
23
+ xmlns: WA_XMLNS.SIGNAL,
24
+ to: this.hostDomain
25
+ },
26
+ content: [
27
+ {
28
+ tag: WA_NODE_TAGS.DIGEST,
29
+ attrs: {}
30
+ }
31
+ ]
32
+ }, timeoutMs);
33
+ if (response.tag !== WA_NODE_TAGS.IQ) {
34
+ throw new Error(`invalid signal digest response tag: ${response.tag}`);
35
+ }
36
+ if (response.attrs.type === WA_IQ_TYPES.ERROR) {
37
+ const error = parseIqError(response);
38
+ if (error.numericCode === 404 || error.code === '404') {
39
+ return {
40
+ valid: false,
41
+ shouldReupload: true,
42
+ reason: 'missing_remote_digest',
43
+ preKeyCount: 0
44
+ };
45
+ }
46
+ throw new Error(`signal digest iq failed (${error.code}: ${error.text})`);
47
+ }
48
+ if (response.attrs.type !== WA_IQ_TYPES.RESULT) {
49
+ throw new Error(`invalid signal digest response type: ${response.attrs.type ?? 'unknown'}`);
50
+ }
51
+ const digest = this.parseDigestPayload(response);
52
+ const expectedType = SIGNAL_KEY_BUNDLE_TYPE_BYTES[0];
53
+ if (digest.keyBundleType !== expectedType) {
54
+ return {
55
+ valid: false,
56
+ shouldReupload: false,
57
+ reason: 'unsupported_key_bundle_type',
58
+ preKeyCount: digest.preKeyIds.length
59
+ };
60
+ }
61
+ const [registrationInfo, signedPreKey] = await Promise.all([
62
+ this.signalStore.getRegistrationInfo(),
63
+ this.signalStore.getSignedPreKey()
64
+ ]);
65
+ if (!registrationInfo || !signedPreKey) {
66
+ return {
67
+ valid: false,
68
+ shouldReupload: false,
69
+ reason: 'missing_local_state',
70
+ preKeyCount: digest.preKeyIds.length
71
+ };
72
+ }
73
+ if (registrationInfo.registrationId !== digest.registrationId) {
74
+ return {
75
+ valid: false,
76
+ shouldReupload: true,
77
+ reason: 'registration_mismatch',
78
+ preKeyCount: digest.preKeyIds.length
79
+ };
80
+ }
81
+ if (!uint8Equal(registrationInfo.identityKeyPair.pubKey, digest.identity)) {
82
+ return {
83
+ valid: false,
84
+ shouldReupload: true,
85
+ reason: 'identity_mismatch',
86
+ preKeyCount: digest.preKeyIds.length
87
+ };
88
+ }
89
+ if (signedPreKey.keyId !== digest.signedKey.id ||
90
+ !uint8Equal(signedPreKey.keyPair.pubKey, digest.signedKey.publicKey) ||
91
+ !uint8Equal(signedPreKey.signature, digest.signedKey.signature)) {
92
+ return {
93
+ valid: false,
94
+ shouldReupload: true,
95
+ reason: 'signed_prekey_mismatch',
96
+ preKeyCount: digest.preKeyIds.length
97
+ };
98
+ }
99
+ const preKeys = await this.signalStore.getPreKeysById(digest.preKeyIds);
100
+ const bytesToHash = [
101
+ registrationInfo.identityKeyPair.pubKey,
102
+ signedPreKey.keyPair.pubKey,
103
+ signedPreKey.signature
104
+ ];
105
+ for (let index = 0; index < preKeys.length; index += 1) {
106
+ const preKey = preKeys[index];
107
+ if (!preKey) {
108
+ return {
109
+ valid: false,
110
+ shouldReupload: true,
111
+ reason: 'missing_local_prekey',
112
+ preKeyCount: digest.preKeyIds.length
113
+ };
114
+ }
115
+ bytesToHash.push(preKey.keyPair.pubKey);
116
+ }
117
+ const localHash = (await sha1(concatBytes(bytesToHash))).subarray(0, digest.hash.byteLength);
118
+ if (!uint8Equal(localHash, digest.hash)) {
119
+ return {
120
+ valid: false,
121
+ shouldReupload: true,
122
+ reason: 'hash_mismatch',
123
+ preKeyCount: digest.preKeyIds.length
124
+ };
125
+ }
126
+ return {
127
+ valid: true,
128
+ shouldReupload: false,
129
+ reason: 'ok',
130
+ preKeyCount: digest.preKeyIds.length
131
+ };
132
+ }
133
+ parseDigestPayload(node) {
134
+ const digestNode = findNodeChild(node, WA_NODE_TAGS.DIGEST);
135
+ if (!digestNode) {
136
+ throw new Error('signal digest response missing digest node');
137
+ }
138
+ const registrationNode = findNodeChild(digestNode, WA_NODE_TAGS.REGISTRATION);
139
+ const typeNode = findNodeChild(digestNode, WA_NODE_TAGS.TYPE);
140
+ const identityNode = findNodeChild(digestNode, WA_NODE_TAGS.IDENTITY);
141
+ const signedKeyNode = findNodeChild(digestNode, WA_NODE_TAGS.SKEY);
142
+ const listNode = findNodeChild(digestNode, WA_NODE_TAGS.LIST);
143
+ const hashNode = findNodeChild(digestNode, WA_NODE_TAGS.HASH);
144
+ if (!registrationNode ||
145
+ !typeNode ||
146
+ !identityNode ||
147
+ !signedKeyNode ||
148
+ !listNode ||
149
+ !hashNode) {
150
+ throw new Error('signal digest response is incomplete');
151
+ }
152
+ const signedKeyIdNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.ID);
153
+ const signedKeyValueNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.VALUE);
154
+ const signedKeySignatureNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.SIGNATURE);
155
+ if (!signedKeyIdNode || !signedKeyValueNode || !signedKeySignatureNode) {
156
+ throw new Error('signal digest response signed pre-key is incomplete');
157
+ }
158
+ const registrationId = parseUint(decodeExactLength(registrationNode.content, 'signal digest registration', SIGNAL_REGISTRATION_ID_LENGTH), 'signal digest registration');
159
+ const keyBundleType = parseUint(decodeExactLength(typeNode.content, 'signal digest type', SIGNAL_KEY_BUNDLE_TYPE_LENGTH), 'signal digest type');
160
+ const identity = decodeExactLength(identityNode.content, 'signal digest identity', SIGNAL_KEY_DATA_LENGTH);
161
+ const signedKeyId = parseUint(decodeExactLength(signedKeyIdNode.content, 'signal digest skey.id', SIGNAL_KEY_ID_LENGTH), 'signal digest skey.id');
162
+ const signedKeyPublicKey = decodeExactLength(signedKeyValueNode.content, 'signal digest skey.value', SIGNAL_KEY_DATA_LENGTH);
163
+ const signedKeySignature = decodeExactLength(signedKeySignatureNode.content, 'signal digest skey.signature', SIGNAL_SIGNATURE_LENGTH);
164
+ const preKeyIds = getNodeChildren(listNode).map((child, index) => parseUint(decodeExactLength(child.content, `signal digest list[${index}]`, SIGNAL_KEY_ID_LENGTH), `signal digest list[${index}]`));
165
+ const hash = decodeNodeContentBase64OrBytes(hashNode.content, 'signal digest hash');
166
+ return {
167
+ registrationId,
168
+ keyBundleType,
169
+ identity,
170
+ signedKey: {
171
+ id: signedKeyId,
172
+ publicKey: signedKeyPublicKey,
173
+ signature: signedKeySignature
174
+ },
175
+ preKeyIds,
176
+ hash
177
+ };
178
+ }
179
+ }
@@ -0,0 +1,111 @@
1
+ import { toSerializedPubKey } from '../../crypto/core/keys.js';
2
+ import { WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../../protocol/constants.js';
3
+ import { normalizeDeviceJid, parseSignalAddressFromJid } from '../../protocol/jid.js';
4
+ import { decodeExactLength, parseUint } from '../api/codec.js';
5
+ import { SIGNAL_KEY_BUNDLE_TYPE_LENGTH, SIGNAL_KEY_DATA_LENGTH } from '../api/constants.js';
6
+ import { findNodeChild, getNodeChildrenByTag } from '../../transport/node/helpers.js';
7
+ export class SignalIdentitySyncApi {
8
+ constructor(options) {
9
+ this.logger = options.logger;
10
+ this.query = options.query;
11
+ this.signalStore = options.signalStore;
12
+ this.defaultTimeoutMs =
13
+ options.defaultTimeoutMs ?? WA_DEFAULTS.SIGNAL_FETCH_KEY_BUNDLES_TIMEOUT_MS;
14
+ this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
15
+ }
16
+ async syncIdentityKeys(targetJids, timeoutMs = this.defaultTimeoutMs) {
17
+ const normalizedTargets = [...new Set(targetJids.map((jid) => normalizeDeviceJid(jid)))];
18
+ if (normalizedTargets.length === 0) {
19
+ return [];
20
+ }
21
+ this.logger.debug('signal identity sync request', {
22
+ targets: normalizedTargets.length,
23
+ timeoutMs
24
+ });
25
+ const response = await this.query({
26
+ tag: WA_NODE_TAGS.IQ,
27
+ attrs: {
28
+ type: WA_IQ_TYPES.GET,
29
+ xmlns: WA_XMLNS.SIGNAL,
30
+ to: this.hostDomain
31
+ },
32
+ content: [
33
+ {
34
+ tag: WA_NODE_TAGS.IDENTITY,
35
+ attrs: {},
36
+ content: normalizedTargets.map((jid) => ({
37
+ tag: WA_NODE_TAGS.USER,
38
+ attrs: { jid }
39
+ }))
40
+ }
41
+ ]
42
+ }, timeoutMs);
43
+ const entries = this.parseIdentitySyncResponse(response, normalizedTargets);
44
+ const { signalStore } = this;
45
+ if (signalStore && entries.length > 0) {
46
+ await signalStore.setRemoteIdentities(entries.map((entry) => ({
47
+ address: parseSignalAddressFromJid(entry.jid),
48
+ identityKey: toSerializedPubKey(entry.identity)
49
+ })));
50
+ }
51
+ this.logger.debug('signal identity sync success', {
52
+ requested: normalizedTargets.length,
53
+ synced: entries.length
54
+ });
55
+ return entries;
56
+ }
57
+ parseIdentitySyncResponse(node, requestedJids) {
58
+ if (node.tag !== WA_NODE_TAGS.IQ) {
59
+ throw new Error(`invalid identity sync response tag: ${node.tag}`);
60
+ }
61
+ if (node.attrs.type === WA_IQ_TYPES.ERROR) {
62
+ const errorNode = findNodeChild(node, WA_NODE_TAGS.ERROR);
63
+ if (!errorNode) {
64
+ throw new Error(`identity sync iq error for ${node.attrs.id ?? 'unknown id'}`);
65
+ }
66
+ const code = errorNode.attrs.code ?? 'unknown';
67
+ const text = errorNode.attrs.text ?? errorNode.attrs.type ?? 'unknown';
68
+ throw new Error(`identity sync iq error (${code} ${text})`);
69
+ }
70
+ if (node.attrs.type !== WA_IQ_TYPES.RESULT) {
71
+ throw new Error(`invalid identity sync response type: ${node.attrs.type ?? 'unknown'}`);
72
+ }
73
+ const listNode = findNodeChild(node, WA_NODE_TAGS.LIST);
74
+ if (!listNode) {
75
+ throw new Error('identity sync response missing list node');
76
+ }
77
+ const requested = new Set(requestedJids);
78
+ const userNodes = getNodeChildrenByTag(listNode, WA_NODE_TAGS.USER);
79
+ return userNodes.flatMap((userNode) => {
80
+ const jid = userNode.attrs.jid ? normalizeDeviceJid(userNode.attrs.jid) : '';
81
+ if (!jid || !requested.has(jid)) {
82
+ return [];
83
+ }
84
+ const errorNode = findNodeChild(userNode, WA_NODE_TAGS.ERROR);
85
+ if (errorNode) {
86
+ this.logger.warn('signal identity sync user error', {
87
+ jid,
88
+ code: errorNode.attrs.code,
89
+ text: errorNode.attrs.text
90
+ });
91
+ return [];
92
+ }
93
+ const identityNode = findNodeChild(userNode, WA_NODE_TAGS.IDENTITY);
94
+ if (!identityNode) {
95
+ throw new Error(`identity sync user missing identity node for ${jid}`);
96
+ }
97
+ const typeNode = findNodeChild(userNode, WA_NODE_TAGS.TYPE);
98
+ const identity = decodeExactLength(identityNode.content, 'identity sync identity', SIGNAL_KEY_DATA_LENGTH);
99
+ const parsedType = typeNode
100
+ ? parseUint(decodeExactLength(typeNode.content, 'identity sync type', SIGNAL_KEY_BUNDLE_TYPE_LENGTH), 'identity sync type')
101
+ : undefined;
102
+ return [
103
+ {
104
+ jid,
105
+ identity,
106
+ ...(parsedType !== undefined ? { type: parsedType } : {})
107
+ }
108
+ ];
109
+ });
110
+ }
111
+ }
@@ -0,0 +1,141 @@
1
+ import { WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS } from '../../protocol/constants.js';
2
+ import { splitJid } from '../../protocol/jid.js';
3
+ import { decodeExactLength, parseUint } from '../api/codec.js';
4
+ import { SIGNAL_KEY_DATA_LENGTH, SIGNAL_KEY_ID_LENGTH, SIGNAL_REGISTRATION_ID_LENGTH, SIGNAL_SIGNATURE_LENGTH } from '../api/constants.js';
5
+ import { buildMissingPreKeysFetchIq } from '../api/prekeys.js';
6
+ import { decodeNodeContentBase64OrBytes, findNodeChild, getNodeChildrenByTag } from '../../transport/node/helpers.js';
7
+ import { parseIqError } from '../../transport/node/query.js';
8
+ function parseDeviceId(value, field) {
9
+ if (!value) {
10
+ throw new Error(`${field} is missing`);
11
+ }
12
+ const parsed = Number.parseInt(value, 10);
13
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
14
+ throw new Error(`${field} is invalid`);
15
+ }
16
+ return parsed;
17
+ }
18
+ export class SignalMissingPreKeysSyncApi {
19
+ constructor(options) {
20
+ this.logger = options.logger;
21
+ this.query = options.query;
22
+ this.defaultTimeoutMs =
23
+ options.defaultTimeoutMs ?? WA_DEFAULTS.SIGNAL_FETCH_KEY_BUNDLES_TIMEOUT_MS;
24
+ }
25
+ async fetchMissingPreKeys(targets, timeoutMs = this.defaultTimeoutMs) {
26
+ if (targets.length === 0) {
27
+ return [];
28
+ }
29
+ this.logger.debug('signal fetch missing prekeys request', {
30
+ users: targets.length,
31
+ timeoutMs
32
+ });
33
+ const response = await this.query(buildMissingPreKeysFetchIq(targets), timeoutMs);
34
+ const parsed = this.parseFetchMissingPreKeysResponse(response, targets);
35
+ this.logger.debug('signal fetch missing prekeys success', {
36
+ users: parsed.length
37
+ });
38
+ return parsed;
39
+ }
40
+ parseFetchMissingPreKeysResponse(node, requestedTargets) {
41
+ if (node.tag !== WA_NODE_TAGS.IQ) {
42
+ throw new Error(`invalid missing prekeys response tag: ${node.tag}`);
43
+ }
44
+ if (node.attrs.type === WA_IQ_TYPES.ERROR) {
45
+ const error = parseIqError(node);
46
+ throw new Error(`missing prekeys iq failed (${error.code}: ${error.text})`);
47
+ }
48
+ if (node.attrs.type !== WA_IQ_TYPES.RESULT) {
49
+ throw new Error(`invalid missing prekeys response type: ${node.attrs.type ?? 'unknown'}`);
50
+ }
51
+ const listNode = findNodeChild(node, WA_NODE_TAGS.LIST);
52
+ if (!listNode) {
53
+ throw new Error('missing prekeys response missing list node');
54
+ }
55
+ const users = getNodeChildrenByTag(listNode, WA_NODE_TAGS.USER);
56
+ const parsedByJid = new Map();
57
+ for (let index = 0; index < users.length; index += 1) {
58
+ const userNode = users[index];
59
+ const userJid = userNode.attrs.jid;
60
+ if (!userJid) {
61
+ continue;
62
+ }
63
+ const userErrorNode = findNodeChild(userNode, WA_NODE_TAGS.ERROR);
64
+ if (userErrorNode) {
65
+ const parsedCode = Number.parseInt(userErrorNode.attrs.code ?? '', 10);
66
+ parsedByJid.set(userJid, {
67
+ userJid,
68
+ errorCode: Number.isSafeInteger(parsedCode) ? parsedCode : undefined,
69
+ errorText: userErrorNode.attrs.text ?? userErrorNode.attrs.type ?? 'unknown'
70
+ });
71
+ continue;
72
+ }
73
+ parsedByJid.set(userJid, {
74
+ userJid,
75
+ devices: this.parseUserDevices(userNode, userJid)
76
+ });
77
+ }
78
+ return requestedTargets.map((target) => {
79
+ return (parsedByJid.get(target.userJid) ?? {
80
+ userJid: target.userJid,
81
+ errorText: 'missing user in key_fetch response'
82
+ });
83
+ });
84
+ }
85
+ parseUserDevices(node, userJid) {
86
+ const { user, server } = splitJid(userJid);
87
+ const devices = getNodeChildrenByTag(node, WA_NODE_TAGS.DEVICE);
88
+ return devices.map((deviceNode, index) => {
89
+ const deviceId = parseDeviceId(deviceNode.attrs.id, `missing prekeys user[${userJid}] device[${index}].id`);
90
+ const registrationNode = findNodeChild(deviceNode, WA_NODE_TAGS.REGISTRATION);
91
+ const identityNode = findNodeChild(deviceNode, WA_NODE_TAGS.IDENTITY);
92
+ const signedKeyNode = findNodeChild(deviceNode, WA_NODE_TAGS.SKEY);
93
+ if (!registrationNode || !identityNode || !signedKeyNode) {
94
+ throw new Error(`missing prekeys device payload is incomplete for ${userJid}`);
95
+ }
96
+ const signedKeyIdNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.ID);
97
+ const signedKeyValueNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.VALUE);
98
+ const signedKeySignatureNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.SIGNATURE);
99
+ if (!signedKeyIdNode || !signedKeyValueNode || !signedKeySignatureNode) {
100
+ throw new Error(`missing prekeys signed pre-key is incomplete for ${userJid}`);
101
+ }
102
+ const oneTimeNode = findNodeChild(deviceNode, WA_NODE_TAGS.KEY);
103
+ const oneTimeIdNode = oneTimeNode
104
+ ? findNodeChild(oneTimeNode, WA_NODE_TAGS.ID)
105
+ : undefined;
106
+ const oneTimeValueNode = oneTimeNode
107
+ ? findNodeChild(oneTimeNode, WA_NODE_TAGS.VALUE)
108
+ : undefined;
109
+ if (oneTimeNode && (!oneTimeIdNode || !oneTimeValueNode)) {
110
+ throw new Error(`missing prekeys one-time key is incomplete for ${userJid}`);
111
+ }
112
+ const deviceIdentityNode = findNodeChild(deviceNode, WA_NODE_TAGS.DEVICE_IDENTITY);
113
+ const bundle = {
114
+ regId: parseUint(decodeExactLength(registrationNode.content, 'missing prekeys device registration', SIGNAL_REGISTRATION_ID_LENGTH), 'missing prekeys device registration'),
115
+ identity: decodeExactLength(identityNode.content, 'missing prekeys device identity', SIGNAL_KEY_DATA_LENGTH),
116
+ signedKey: {
117
+ id: parseUint(decodeExactLength(signedKeyIdNode.content, 'missing prekeys device skey.id', SIGNAL_KEY_ID_LENGTH), 'missing prekeys device skey.id'),
118
+ publicKey: decodeExactLength(signedKeyValueNode.content, 'missing prekeys device skey.value', SIGNAL_KEY_DATA_LENGTH),
119
+ signature: decodeExactLength(signedKeySignatureNode.content, 'missing prekeys device skey.signature', SIGNAL_SIGNATURE_LENGTH)
120
+ },
121
+ ...(oneTimeIdNode && oneTimeValueNode
122
+ ? {
123
+ oneTimeKey: {
124
+ id: parseUint(decodeExactLength(oneTimeIdNode.content, 'missing prekeys device key.id', SIGNAL_KEY_ID_LENGTH), 'missing prekeys device key.id'),
125
+ publicKey: decodeExactLength(oneTimeValueNode.content, 'missing prekeys device key.value', SIGNAL_KEY_DATA_LENGTH)
126
+ }
127
+ }
128
+ : {})
129
+ };
130
+ return {
131
+ deviceJid: deviceId === 0 ? userJid : `${user}:${deviceId}@${server}`,
132
+ bundle,
133
+ ...(deviceIdentityNode
134
+ ? {
135
+ deviceIdentity: decodeNodeContentBase64OrBytes(deviceIdentityNode.content, 'missing prekeys device device-identity')
136
+ }
137
+ : {})
138
+ };
139
+ });
140
+ }
141
+ }
@@ -0,0 +1,59 @@
1
+ import { WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS } from '../../protocol/constants.js';
2
+ import { buildSignedPreKeyRotateIq } from '../api/prekeys.js';
3
+ import { generateSignedPreKey } from '../registration/keygen.js';
4
+ import { parseIqError } from '../../transport/node/query.js';
5
+ export class SignalRotateKeyApi {
6
+ constructor(options) {
7
+ this.logger = options.logger;
8
+ this.query = options.query;
9
+ this.signalStore = options.signalStore;
10
+ this.defaultTimeoutMs = options.defaultTimeoutMs ?? WA_DEFAULTS.IQ_TIMEOUT_MS;
11
+ }
12
+ async rotateSignedPreKey(timeoutMs = this.defaultTimeoutMs) {
13
+ const registrationInfo = await this.signalStore.getRegistrationInfo();
14
+ if (!registrationInfo) {
15
+ throw new Error('signal rotate key requires registration info');
16
+ }
17
+ const currentSignedPreKey = await this.signalStore.getSignedPreKey();
18
+ const nextSignedPreKey = await generateSignedPreKey(currentSignedPreKey ? currentSignedPreKey.keyId + 1 : 1, registrationInfo.identityKeyPair.privKey);
19
+ await this.signalStore.setSignedPreKey(nextSignedPreKey);
20
+ this.logger.info('signal signed prekey uploading', {
21
+ keyId: nextSignedPreKey.keyId,
22
+ timeoutMs
23
+ });
24
+ const response = await this.query(buildSignedPreKeyRotateIq(nextSignedPreKey), timeoutMs);
25
+ if (response.tag !== WA_NODE_TAGS.IQ) {
26
+ throw new Error(`invalid signal rotate response tag: ${response.tag}`);
27
+ }
28
+ if (response.attrs.type === WA_IQ_TYPES.RESULT) {
29
+ this.logger.info('signal signed prekey upload completed', {
30
+ keyId: nextSignedPreKey.keyId
31
+ });
32
+ return { shouldDigestKey: false };
33
+ }
34
+ if (response.attrs.type !== WA_IQ_TYPES.ERROR) {
35
+ throw new Error(`invalid signal rotate response type: ${response.attrs.type ?? 'unknown'}`);
36
+ }
37
+ const failure = parseIqError(response);
38
+ const errorCode = failure.numericCode;
39
+ if (errorCode === 406) {
40
+ this.logger.warn('signal rotate key generated bad key');
41
+ return { shouldDigestKey: false, errorCode };
42
+ }
43
+ if (errorCode === 409) {
44
+ this.logger.warn('signal rotate key validation mismatch');
45
+ return { shouldDigestKey: true, errorCode };
46
+ }
47
+ if (errorCode !== undefined && errorCode >= 500) {
48
+ this.logger.warn('signal rotate key server error', {
49
+ errorCode
50
+ });
51
+ return { shouldDigestKey: false, errorCode };
52
+ }
53
+ this.logger.warn('signal rotate key unrecognized error', {
54
+ errorCode,
55
+ errorText: failure.text
56
+ });
57
+ return { shouldDigestKey: true, ...(errorCode !== undefined ? { errorCode } : {}) };
58
+ }
59
+ }
@@ -0,0 +1,187 @@
1
+ import { WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../../protocol/constants.js';
2
+ import { decodeExactLength, parseUint } from '../api/codec.js';
3
+ import { SIGNAL_KEY_DATA_LENGTH, SIGNAL_KEY_ID_LENGTH, SIGNAL_REGISTRATION_ID_LENGTH, SIGNAL_SIGNATURE_LENGTH } from '../api/constants.js';
4
+ import { findNodeChild, getNodeChildrenByTag, decodeNodeContentBase64OrBytes } from '../../transport/node/helpers.js';
5
+ export class SignalSessionSyncApi {
6
+ constructor(options) {
7
+ this.logger = options.logger;
8
+ this.query = options.query;
9
+ this.defaultTimeoutMs =
10
+ options.defaultTimeoutMs ?? WA_DEFAULTS.SIGNAL_FETCH_KEY_BUNDLES_TIMEOUT_MS;
11
+ this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
12
+ }
13
+ async fetchKeyBundle(target, timeoutMs = this.defaultTimeoutMs) {
14
+ const results = await this.fetchKeyBundles([target], timeoutMs);
15
+ const first = results[0];
16
+ if (!first || !('bundle' in first)) {
17
+ const errorCode = first && 'errorCode' in first ? (first.errorCode ?? 'unknown') : 'unknown';
18
+ const errorText = first && 'errorText' in first ? first.errorText : 'unknown';
19
+ throw new Error(`key bundle user error (${target.jid}): ${errorCode} ${errorText}`);
20
+ }
21
+ const parsed = first;
22
+ this.logger.debug('signal fetch key bundle success', {
23
+ requestJid: target.jid,
24
+ responseJid: parsed.jid,
25
+ hasOneTimeKey: parsed.bundle.oneTimeKey !== undefined,
26
+ hasDeviceIdentity: parsed.deviceIdentity !== undefined
27
+ });
28
+ return parsed;
29
+ }
30
+ async fetchKeyBundles(targets, timeoutMs = this.defaultTimeoutMs) {
31
+ if (targets.length === 0) {
32
+ return [];
33
+ }
34
+ const targetByJid = new Map();
35
+ for (let index = 0; index < targets.length; index += 1) {
36
+ const target = targets[index];
37
+ const previous = targetByJid.get(target.jid);
38
+ targetByJid.set(target.jid, {
39
+ jid: target.jid,
40
+ reasonIdentity: (previous?.reasonIdentity ?? false) || target.reasonIdentity === true
41
+ });
42
+ }
43
+ const mergedTargets = [...targetByJid.values()];
44
+ this.logger.debug('signal fetch key bundles request', {
45
+ targets: mergedTargets.length,
46
+ timeoutMs
47
+ });
48
+ const responseNode = await this.query({
49
+ tag: WA_NODE_TAGS.IQ,
50
+ attrs: {
51
+ type: WA_IQ_TYPES.GET,
52
+ xmlns: WA_XMLNS.SIGNAL,
53
+ to: this.hostDomain
54
+ },
55
+ content: [
56
+ {
57
+ tag: WA_NODE_TAGS.KEY,
58
+ attrs: {},
59
+ content: mergedTargets.map((target) => ({
60
+ tag: WA_NODE_TAGS.USER,
61
+ attrs: {
62
+ jid: target.jid,
63
+ ...(target.reasonIdentity === true ? { reason: 'identity' } : {})
64
+ }
65
+ }))
66
+ }
67
+ ]
68
+ }, timeoutMs);
69
+ return this.parseFetchKeyBundleResponse(responseNode, mergedTargets);
70
+ }
71
+ parseFetchKeyBundleResponse(node, requestedTargets) {
72
+ if (node.tag !== WA_NODE_TAGS.IQ) {
73
+ throw new Error(`invalid key bundle response tag: ${node.tag}`);
74
+ }
75
+ if (node.attrs.type === WA_IQ_TYPES.ERROR) {
76
+ const errorNode = findNodeChild(node, WA_NODE_TAGS.ERROR);
77
+ if (!errorNode) {
78
+ throw new Error(`key bundle iq error for ${node.attrs.id ?? 'unknown id'}`);
79
+ }
80
+ const code = errorNode.attrs.code ?? 'unknown';
81
+ const text = errorNode.attrs.text ?? errorNode.attrs.type ?? 'unknown';
82
+ throw new Error(`key bundle iq error (${code} ${text})`);
83
+ }
84
+ if (node.attrs.type !== WA_IQ_TYPES.RESULT) {
85
+ throw new Error(`invalid key bundle response type: ${node.attrs.type ?? 'unknown'}`);
86
+ }
87
+ const listNode = findNodeChild(node, WA_NODE_TAGS.LIST);
88
+ if (!listNode) {
89
+ throw new Error('key bundle response missing list node');
90
+ }
91
+ const userNodes = getNodeChildrenByTag(listNode, WA_NODE_TAGS.USER);
92
+ if (userNodes.length === 0) {
93
+ throw new Error('key bundle response list is empty');
94
+ }
95
+ const parsedByJid = new Map();
96
+ for (let index = 0; index < userNodes.length; index += 1) {
97
+ const userNode = userNodes[index];
98
+ const jid = userNode.attrs.jid;
99
+ if (!jid) {
100
+ continue;
101
+ }
102
+ const userErrorNode = findNodeChild(userNode, WA_NODE_TAGS.ERROR);
103
+ if (userErrorNode) {
104
+ parsedByJid.set(jid, {
105
+ jid,
106
+ errorCode: userErrorNode.attrs.code,
107
+ errorText: userErrorNode.attrs.text ?? 'unknown'
108
+ });
109
+ continue;
110
+ }
111
+ const parsed = this.parseUserKeyBundle(userNode);
112
+ parsedByJid.set(jid, {
113
+ jid,
114
+ bundle: parsed.bundle,
115
+ ...(parsed.deviceIdentity ? { deviceIdentity: parsed.deviceIdentity } : {})
116
+ });
117
+ }
118
+ return requestedTargets.map((target) => {
119
+ const parsed = parsedByJid.get(target.jid);
120
+ if (parsed) {
121
+ return parsed;
122
+ }
123
+ return {
124
+ jid: target.jid,
125
+ errorText: 'missing key bundle user in response'
126
+ };
127
+ });
128
+ }
129
+ parseUserKeyBundle(node) {
130
+ const registrationNode = findNodeChild(node, WA_NODE_TAGS.REGISTRATION);
131
+ if (!registrationNode) {
132
+ throw new Error('key bundle user missing registration node');
133
+ }
134
+ const identityNode = findNodeChild(node, WA_NODE_TAGS.IDENTITY);
135
+ if (!identityNode) {
136
+ throw new Error('key bundle user missing identity node');
137
+ }
138
+ const signedPreKeyNode = findNodeChild(node, WA_NODE_TAGS.SKEY);
139
+ if (!signedPreKeyNode) {
140
+ throw new Error('key bundle user missing signed pre-key node');
141
+ }
142
+ const registrationBytes = decodeExactLength(registrationNode.content, 'key bundle registration', SIGNAL_REGISTRATION_ID_LENGTH);
143
+ const registrationId = parseUint(registrationBytes, 'key bundle registration');
144
+ const identity = decodeExactLength(identityNode.content, 'key bundle identity', SIGNAL_KEY_DATA_LENGTH);
145
+ const signedIdNode = findNodeChild(signedPreKeyNode, WA_NODE_TAGS.ID);
146
+ const signedValueNode = findNodeChild(signedPreKeyNode, WA_NODE_TAGS.VALUE);
147
+ const signedSignatureNode = findNodeChild(signedPreKeyNode, WA_NODE_TAGS.SIGNATURE);
148
+ if (!signedIdNode || !signedValueNode || !signedSignatureNode) {
149
+ throw new Error('key bundle signed pre-key is incomplete');
150
+ }
151
+ const signedIdBytes = decodeExactLength(signedIdNode.content, 'key bundle skey.id', SIGNAL_KEY_ID_LENGTH);
152
+ const signedValue = decodeExactLength(signedValueNode.content, 'key bundle skey.value', SIGNAL_KEY_DATA_LENGTH);
153
+ const signedSignature = decodeExactLength(signedSignatureNode.content, 'key bundle skey.signature', SIGNAL_SIGNATURE_LENGTH);
154
+ const preKeyNode = findNodeChild(node, WA_NODE_TAGS.KEY);
155
+ let oneTimeKey;
156
+ if (preKeyNode) {
157
+ const preKeyIdNode = findNodeChild(preKeyNode, WA_NODE_TAGS.ID);
158
+ const preKeyValueNode = findNodeChild(preKeyNode, WA_NODE_TAGS.VALUE);
159
+ if (!preKeyIdNode || !preKeyValueNode) {
160
+ throw new Error('key bundle one-time pre-key is incomplete');
161
+ }
162
+ const preKeyIdBytes = decodeExactLength(preKeyIdNode.content, 'key bundle key.id', SIGNAL_KEY_ID_LENGTH);
163
+ const preKeyValue = decodeExactLength(preKeyValueNode.content, 'key bundle key.value', SIGNAL_KEY_DATA_LENGTH);
164
+ oneTimeKey = {
165
+ id: parseUint(preKeyIdBytes, 'key bundle key.id'),
166
+ publicKey: preKeyValue
167
+ };
168
+ }
169
+ const deviceIdentityNode = findNodeChild(node, WA_NODE_TAGS.DEVICE_IDENTITY);
170
+ const deviceIdentity = deviceIdentityNode
171
+ ? decodeNodeContentBase64OrBytes(deviceIdentityNode.content, 'key bundle device-identity')
172
+ : undefined;
173
+ return {
174
+ bundle: {
175
+ regId: registrationId,
176
+ identity,
177
+ signedKey: {
178
+ id: parseUint(signedIdBytes, 'key bundle skey.id'),
179
+ publicKey: signedValue,
180
+ signature: signedSignature
181
+ },
182
+ ...(oneTimeKey ? { oneTimeKey } : {})
183
+ },
184
+ ...(deviceIdentity ? { deviceIdentity } : {})
185
+ };
186
+ }
187
+ }