zapo-js 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (468) hide show
  1. package/README.md +12 -4
  2. package/dist/appstate/WaAppStateCrypto.js +1 -1
  3. package/dist/appstate/WaAppStateSyncClient.js +138 -93
  4. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  5. package/dist/appstate/index.js +8 -6
  6. package/dist/appstate/utils.js +0 -5
  7. package/dist/auth/WaAuthClient.js +36 -47
  8. package/dist/auth/flow/WaAuthCredentialsFlow.js +7 -7
  9. package/dist/auth/index.js +1 -6
  10. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  11. package/dist/auth/pairing/WaPairingFlow.js +13 -3
  12. package/dist/client/WaClient.js +225 -101
  13. package/dist/client/WaClientFactory.js +294 -44
  14. package/dist/client/connection/WaConnectionManager.js +19 -10
  15. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  16. package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
  17. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  18. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +292 -99
  19. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  20. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  21. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  22. package/dist/client/coordinators/WaRetryCoordinator.js +179 -27
  23. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  24. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  25. package/dist/client/dirty.js +40 -20
  26. package/dist/client/events/devices.js +72 -0
  27. package/dist/client/events/group.js +3 -11
  28. package/dist/client/events/identity.js +22 -0
  29. package/dist/client/events/privacy-token.js +39 -0
  30. package/dist/client/history-sync.js +50 -9
  31. package/dist/client/incoming.js +37 -7
  32. package/dist/client/mailbox.js +24 -23
  33. package/dist/client/messages.js +107 -31
  34. package/dist/client/messaging/fanout.js +21 -11
  35. package/dist/client/messaging/participants.js +6 -4
  36. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  37. package/dist/client/tokens/cs-token.js +50 -0
  38. package/dist/client/tokens/tc-token.js +25 -0
  39. package/dist/crypto/core/index.js +2 -2
  40. package/dist/crypto/core/keys.js +4 -4
  41. package/dist/crypto/core/nonce.js +2 -0
  42. package/dist/crypto/core/primitives.js +0 -8
  43. package/dist/crypto/core/random.js +22 -0
  44. package/dist/crypto/curves/X25519.js +25 -6
  45. package/dist/crypto/index.js +3 -0
  46. package/dist/crypto/math/constants.js +13 -36
  47. package/dist/crypto/math/edwards.js +171 -44
  48. package/dist/crypto/math/fe.js +706 -0
  49. package/dist/crypto/math/mod.js +10 -3
  50. package/dist/esm/appstate/WaAppStateCrypto.js +1 -1
  51. package/dist/esm/appstate/WaAppStateSyncClient.js +138 -93
  52. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  53. package/dist/esm/appstate/index.js +2 -2
  54. package/dist/esm/appstate/utils.js +2 -5
  55. package/dist/esm/auth/WaAuthClient.js +36 -47
  56. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +7 -7
  57. package/dist/esm/auth/index.js +0 -2
  58. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  59. package/dist/esm/auth/pairing/WaPairingFlow.js +14 -4
  60. package/dist/esm/client/WaClient.js +225 -101
  61. package/dist/esm/client/WaClientFactory.js +295 -45
  62. package/dist/esm/client/connection/WaConnectionManager.js +19 -10
  63. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  64. package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
  65. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  66. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +295 -102
  67. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  68. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  69. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  70. package/dist/esm/client/coordinators/WaRetryCoordinator.js +181 -29
  71. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  72. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  73. package/dist/esm/client/dirty.js +40 -20
  74. package/dist/esm/client/events/devices.js +68 -0
  75. package/dist/esm/client/events/group.js +3 -11
  76. package/dist/esm/client/events/identity.js +19 -0
  77. package/dist/esm/client/events/privacy-token.js +36 -0
  78. package/dist/esm/client/history-sync.js +50 -9
  79. package/dist/esm/client/incoming.js +38 -8
  80. package/dist/esm/client/mailbox.js +24 -23
  81. package/dist/esm/client/messages.js +108 -32
  82. package/dist/esm/client/messaging/fanout.js +22 -12
  83. package/dist/esm/client/messaging/participants.js +6 -4
  84. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  85. package/dist/esm/client/tokens/cs-token.js +46 -0
  86. package/dist/esm/client/tokens/tc-token.js +18 -0
  87. package/dist/esm/crypto/core/index.js +2 -2
  88. package/dist/esm/crypto/core/keys.js +1 -1
  89. package/dist/esm/crypto/core/nonce.js +2 -0
  90. package/dist/esm/crypto/core/primitives.js +0 -7
  91. package/dist/esm/crypto/core/random.js +22 -1
  92. package/dist/esm/crypto/curves/X25519.js +25 -6
  93. package/dist/esm/crypto/index.js +1 -0
  94. package/dist/esm/crypto/math/constants.js +12 -35
  95. package/dist/esm/crypto/math/edwards.js +174 -47
  96. package/dist/esm/crypto/math/fe.js +691 -0
  97. package/dist/esm/crypto/math/mod.js +10 -1
  98. package/dist/esm/index.js +1 -1
  99. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  100. package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
  101. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  102. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  103. package/dist/esm/infra/perf/StoreLock.js +77 -0
  104. package/dist/esm/media/WaMediaCrypto.js +95 -13
  105. package/dist/esm/media/WaMediaTransferClient.js +39 -47
  106. package/dist/esm/media/constants.js +2 -1
  107. package/dist/esm/message/WaMessageClient.js +26 -19
  108. package/dist/esm/message/content.js +195 -9
  109. package/dist/esm/message/icdc.js +76 -0
  110. package/dist/esm/message/incoming.js +24 -12
  111. package/dist/esm/message/phash.js +3 -1
  112. package/dist/esm/message/reporting-token.js +14 -27
  113. package/dist/esm/protocol/appstate.js +9 -40
  114. package/dist/esm/protocol/browser.js +10 -18
  115. package/dist/esm/protocol/constants.js +5 -3
  116. package/dist/esm/protocol/defaults.js +6 -0
  117. package/dist/esm/protocol/index.js +1 -2
  118. package/dist/esm/protocol/jid.js +105 -36
  119. package/dist/esm/protocol/message.js +61 -1
  120. package/dist/esm/protocol/nodes.js +2 -0
  121. package/dist/esm/protocol/notification.js +3 -1
  122. package/dist/esm/protocol/privacy-token.js +17 -0
  123. package/dist/esm/protocol/privacy.js +55 -0
  124. package/dist/esm/protocol/stream.js +26 -1
  125. package/dist/esm/retry/codec.js +216 -0
  126. package/dist/esm/retry/constants.js +1 -1
  127. package/dist/esm/retry/index.js +2 -2
  128. package/dist/esm/retry/parse.js +50 -30
  129. package/dist/esm/retry/replay.js +11 -7
  130. package/dist/esm/retry/tracker.js +50 -12
  131. package/dist/esm/signal/api/SignalDeviceSyncApi.js +49 -32
  132. package/dist/esm/signal/api/SignalDigestSyncApi.js +13 -9
  133. package/dist/esm/signal/api/SignalIdentitySyncApi.js +26 -11
  134. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +18 -7
  135. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  136. package/dist/esm/signal/api/SignalSessionSyncApi.js +16 -7
  137. package/dist/esm/signal/api/result-map.js +10 -0
  138. package/dist/esm/signal/constants.js +0 -4
  139. package/dist/esm/signal/crypto/WaAdvSignature.js +12 -6
  140. package/dist/esm/signal/{store/sqlite.js → encoding.js} +78 -24
  141. package/dist/esm/signal/group/SenderKeyCodec.js +3 -2
  142. package/dist/esm/signal/group/SenderKeyManager.js +125 -106
  143. package/dist/esm/signal/index.js +1 -0
  144. package/dist/esm/signal/registration/keygen.js +6 -2
  145. package/dist/esm/signal/registration/utils.js +1 -0
  146. package/dist/esm/signal/session/SignalProtocol.js +150 -74
  147. package/dist/esm/signal/session/resolver.js +137 -102
  148. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  149. package/dist/esm/store/createStore.js +101 -187
  150. package/dist/esm/store/index.js +1 -10
  151. package/dist/esm/store/locks/appstate.lock.js +26 -0
  152. package/dist/esm/store/locks/auth.lock.js +15 -0
  153. package/dist/esm/store/locks/contact.lock.js +20 -0
  154. package/dist/esm/store/locks/device-list.lock.js +20 -0
  155. package/dist/esm/store/locks/message.lock.js +21 -0
  156. package/dist/esm/store/locks/participants.lock.js +20 -0
  157. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  158. package/dist/esm/store/locks/retry.lock.js +29 -0
  159. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  160. package/dist/esm/store/locks/signal.lock.js +63 -0
  161. package/dist/esm/store/locks/thread.lock.js +21 -0
  162. package/dist/esm/store/noop.store.js +1 -1
  163. package/dist/esm/store/providers/memory/appstate.store.js +22 -24
  164. package/dist/esm/store/providers/memory/device-list.store.js +10 -5
  165. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  166. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  167. package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
  168. package/dist/esm/store/providers/memory/signal.store.js +36 -19
  169. package/dist/esm/transport/WaComms.js +3 -1
  170. package/dist/esm/transport/WaWebSocket.js +0 -6
  171. package/dist/esm/transport/binary/constants.js +0 -30
  172. package/dist/esm/transport/binary/decoder.js +4 -4
  173. package/dist/esm/transport/binary/encoder.js +8 -15
  174. package/dist/esm/transport/binary/index.js +0 -1
  175. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -19
  176. package/dist/esm/transport/node/builders/business.js +129 -0
  177. package/dist/esm/transport/node/builders/global.js +370 -0
  178. package/dist/esm/transport/node/builders/index.js +5 -2
  179. package/dist/esm/transport/node/builders/message.js +63 -239
  180. package/dist/esm/transport/node/builders/pairing.js +0 -24
  181. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  182. package/dist/esm/transport/node/builders/privacy.js +48 -0
  183. package/dist/esm/transport/node/builders/profile.js +70 -0
  184. package/dist/esm/transport/node/builders/retry.js +10 -22
  185. package/dist/esm/transport/node/builders/usync.js +6 -2
  186. package/dist/esm/transport/node/helpers.js +19 -1
  187. package/dist/esm/transport/node/usync.js +3 -33
  188. package/dist/esm/transport/node/xml.js +35 -14
  189. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  190. package/dist/esm/transport/noise/WaNoiseCert.js +3 -3
  191. package/dist/esm/transport/noise/WaNoiseSession.js +64 -23
  192. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  193. package/dist/esm/transport/stream/parse.js +8 -4
  194. package/dist/esm/util/bytes.js +22 -18
  195. package/dist/esm/util/index.js +5 -0
  196. package/dist/esm/util/primitives.js +3 -2
  197. package/dist/index.js +7 -1
  198. package/dist/infra/perf/BackgroundQueue.js +482 -0
  199. package/dist/infra/perf/BoundedTaskQueue.js +3 -1
  200. package/dist/infra/perf/PromiseDedup.js +24 -0
  201. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  202. package/dist/infra/perf/StoreLock.js +81 -0
  203. package/dist/media/WaMediaCrypto.js +94 -12
  204. package/dist/media/WaMediaTransferClient.js +39 -47
  205. package/dist/media/constants.js +2 -1
  206. package/dist/message/WaMessageClient.js +26 -19
  207. package/dist/message/content.js +198 -9
  208. package/dist/message/icdc.js +81 -0
  209. package/dist/message/incoming.js +24 -12
  210. package/dist/message/phash.js +3 -1
  211. package/dist/message/reporting-token.js +14 -28
  212. package/dist/protocol/appstate.js +10 -41
  213. package/dist/protocol/browser.js +10 -18
  214. package/dist/protocol/constants.js +21 -2
  215. package/dist/protocol/defaults.js +6 -0
  216. package/dist/protocol/index.js +8 -5
  217. package/dist/protocol/jid.js +111 -36
  218. package/dist/protocol/message.js +62 -2
  219. package/dist/protocol/nodes.js +2 -0
  220. package/dist/protocol/notification.js +3 -1
  221. package/dist/protocol/privacy-token.js +20 -0
  222. package/dist/protocol/privacy.js +58 -0
  223. package/dist/protocol/stream.js +27 -2
  224. package/dist/retry/codec.js +220 -0
  225. package/dist/retry/constants.js +1 -1
  226. package/dist/retry/index.js +5 -5
  227. package/dist/retry/parse.js +51 -30
  228. package/dist/retry/replay.js +10 -6
  229. package/dist/retry/tracker.js +50 -12
  230. package/dist/signal/api/SignalDeviceSyncApi.js +48 -31
  231. package/dist/signal/api/SignalDigestSyncApi.js +13 -9
  232. package/dist/signal/api/SignalIdentitySyncApi.js +25 -10
  233. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
  234. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  235. package/dist/signal/api/SignalSessionSyncApi.js +16 -7
  236. package/dist/signal/api/result-map.js +13 -0
  237. package/dist/signal/constants.js +1 -5
  238. package/dist/signal/crypto/WaAdvSignature.js +11 -5
  239. package/dist/signal/{store/sqlite.js → encoding.js} +79 -25
  240. package/dist/signal/group/SenderKeyCodec.js +4 -3
  241. package/dist/signal/group/SenderKeyManager.js +125 -106
  242. package/dist/signal/index.js +13 -1
  243. package/dist/signal/registration/keygen.js +6 -2
  244. package/dist/signal/registration/utils.js +1 -0
  245. package/dist/signal/session/SignalProtocol.js +150 -74
  246. package/dist/signal/session/resolver.js +135 -100
  247. package/dist/store/contracts/privacy-token.store.js +2 -0
  248. package/dist/store/createStore.js +101 -187
  249. package/dist/store/index.js +15 -33
  250. package/dist/store/locks/appstate.lock.js +29 -0
  251. package/dist/store/locks/auth.lock.js +18 -0
  252. package/dist/store/locks/contact.lock.js +23 -0
  253. package/dist/store/locks/device-list.lock.js +23 -0
  254. package/dist/store/locks/message.lock.js +24 -0
  255. package/dist/store/locks/participants.lock.js +23 -0
  256. package/dist/store/locks/privacy-token.lock.js +21 -0
  257. package/dist/store/locks/retry.lock.js +32 -0
  258. package/dist/store/locks/sender-key.lock.js +55 -0
  259. package/dist/store/locks/signal.lock.js +66 -0
  260. package/dist/store/locks/thread.lock.js +24 -0
  261. package/dist/store/noop.store.js +1 -1
  262. package/dist/store/providers/memory/appstate.store.js +22 -24
  263. package/dist/store/providers/memory/device-list.store.js +10 -5
  264. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  265. package/dist/store/providers/memory/retry.store.js +77 -2
  266. package/dist/store/providers/memory/sender-key.store.js +6 -1
  267. package/dist/store/providers/memory/signal.store.js +36 -19
  268. package/dist/transport/WaComms.js +3 -1
  269. package/dist/transport/WaWebSocket.js +0 -6
  270. package/dist/transport/binary/constants.js +1 -31
  271. package/dist/transport/binary/decoder.js +4 -4
  272. package/dist/transport/binary/encoder.js +8 -15
  273. package/dist/transport/binary/index.js +0 -4
  274. package/dist/transport/node/WaNodeOrchestrator.js +24 -18
  275. package/dist/transport/node/builders/business.js +137 -0
  276. package/dist/transport/node/builders/global.js +375 -0
  277. package/dist/transport/node/builders/index.js +18 -9
  278. package/dist/transport/node/builders/message.js +64 -245
  279. package/dist/transport/node/builders/pairing.js +0 -26
  280. package/dist/transport/node/builders/privacy-token.js +46 -0
  281. package/dist/transport/node/builders/privacy.js +55 -0
  282. package/dist/transport/node/builders/profile.js +78 -0
  283. package/dist/transport/node/builders/retry.js +9 -21
  284. package/dist/transport/node/builders/usync.js +6 -2
  285. package/dist/transport/node/helpers.js +20 -1
  286. package/dist/transport/node/usync.js +2 -32
  287. package/dist/transport/node/xml.js +35 -14
  288. package/dist/transport/noise/WaClientPayload.js +13 -13
  289. package/dist/transport/noise/WaNoiseCert.js +2 -2
  290. package/dist/transport/noise/WaNoiseSession.js +64 -23
  291. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  292. package/dist/transport/stream/parse.js +7 -3
  293. package/dist/types/appstate/encoding.d.ts +7 -0
  294. package/dist/types/appstate/index.d.ts +3 -3
  295. package/dist/types/appstate/utils.d.ts +0 -2
  296. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  297. package/dist/types/auth/index.d.ts +0 -2
  298. package/dist/types/auth/types.d.ts +1 -0
  299. package/dist/types/client/WaClient.d.ts +27 -12
  300. package/dist/types/client/WaClientFactory.d.ts +12 -4
  301. package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
  302. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  303. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -1
  304. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +14 -0
  305. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  306. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  307. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  308. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
  309. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  310. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  311. package/dist/types/client/events/devices.d.ts +20 -0
  312. package/dist/types/client/events/identity.d.ts +9 -0
  313. package/dist/types/client/events/privacy-token.d.ts +7 -0
  314. package/dist/types/client/history-sync.d.ts +9 -6
  315. package/dist/types/client/incoming.d.ts +3 -1
  316. package/dist/types/client/index.d.ts +1 -1
  317. package/dist/types/client/mailbox.d.ts +3 -5
  318. package/dist/types/client/messages.d.ts +1 -2
  319. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  320. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  321. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  322. package/dist/types/client/types.d.ts +51 -3
  323. package/dist/types/crypto/core/index.d.ts +2 -2
  324. package/dist/types/crypto/core/nonce.d.ts +2 -0
  325. package/dist/types/crypto/core/primitives.d.ts +0 -1
  326. package/dist/types/crypto/core/random.d.ts +1 -0
  327. package/dist/types/crypto/index.d.ts +1 -0
  328. package/dist/types/crypto/math/constants.d.ts +4 -2
  329. package/dist/types/crypto/math/fe.d.ts +30 -0
  330. package/dist/types/crypto/math/mod.d.ts +0 -2
  331. package/dist/types/crypto/math/types.d.ts +11 -4
  332. package/dist/types/index.d.ts +5 -3
  333. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  334. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  335. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  336. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  337. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  338. package/dist/types/media/WaMediaTransferClient.d.ts +3 -12
  339. package/dist/types/media/constants.d.ts +1 -1
  340. package/dist/types/media/index.d.ts +1 -1
  341. package/dist/types/media/types.d.ts +10 -2
  342. package/dist/types/message/content.d.ts +8 -0
  343. package/dist/types/message/icdc.d.ts +13 -0
  344. package/dist/types/message/reporting-token.d.ts +0 -1
  345. package/dist/types/message/types.d.ts +45 -6
  346. package/dist/types/protocol/appstate.d.ts +0 -11
  347. package/dist/types/protocol/constants.d.ts +7 -3
  348. package/dist/types/protocol/defaults.d.ts +6 -0
  349. package/dist/types/protocol/index.d.ts +1 -2
  350. package/dist/types/protocol/jid.d.ts +19 -2
  351. package/dist/types/protocol/message.d.ts +60 -0
  352. package/dist/types/protocol/nodes.d.ts +2 -0
  353. package/dist/types/protocol/notification.d.ts +2 -0
  354. package/dist/types/protocol/privacy-token.d.ts +17 -0
  355. package/dist/types/protocol/privacy.d.ts +75 -0
  356. package/dist/types/protocol/stream.d.ts +30 -0
  357. package/dist/types/retry/codec.d.ts +3 -0
  358. package/dist/types/retry/index.d.ts +3 -3
  359. package/dist/types/retry/parse.d.ts +5 -2
  360. package/dist/types/retry/tracker.d.ts +1 -0
  361. package/dist/types/retry/types.d.ts +6 -1
  362. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
  363. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  364. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  365. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  366. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  367. package/dist/types/signal/api/result-map.d.ts +1 -0
  368. package/dist/types/signal/constants.d.ts +0 -3
  369. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  370. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  371. package/dist/types/signal/index.d.ts +2 -0
  372. package/dist/types/signal/session/SignalProtocol.d.ts +10 -4
  373. package/dist/types/signal/session/resolver.d.ts +7 -2
  374. package/dist/types/store/contracts/appstate.store.d.ts +1 -1
  375. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  376. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  377. package/dist/types/store/contracts/signal.store.d.ts +7 -0
  378. package/dist/types/store/createStore.d.ts +1 -1
  379. package/dist/types/store/index.d.ts +5 -13
  380. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  381. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  382. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  383. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  384. package/dist/types/store/locks/message.lock.d.ts +3 -0
  385. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  386. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  387. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  388. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  389. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  390. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  391. package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
  392. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  393. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  394. package/dist/types/store/providers/memory/signal.store.d.ts +2 -1
  395. package/dist/types/store/types.d.ts +49 -61
  396. package/dist/types/transport/WaWebSocket.d.ts +0 -1
  397. package/dist/types/transport/binary/constants.d.ts +0 -30
  398. package/dist/types/transport/binary/index.d.ts +0 -1
  399. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  400. package/dist/types/transport/node/builders/business.d.ts +29 -0
  401. package/dist/types/transport/node/builders/global.d.ts +102 -0
  402. package/dist/types/transport/node/builders/index.d.ts +5 -2
  403. package/dist/types/transport/node/builders/message.d.ts +8 -7
  404. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  405. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  406. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  407. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  408. package/dist/types/transport/node/builders/retry.d.ts +0 -1
  409. package/dist/types/transport/node/helpers.d.ts +5 -0
  410. package/dist/types/transport/noise/WaNoiseSession.d.ts +3 -2
  411. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  412. package/dist/types/util/bytes.d.ts +1 -1
  413. package/dist/types/util/index.d.ts +5 -0
  414. package/dist/types/util/primitives.d.ts +0 -1
  415. package/dist/util/bytes.js +22 -18
  416. package/dist/util/index.js +23 -0
  417. package/dist/util/primitives.js +2 -2
  418. package/package.json +29 -7
  419. package/proto/index.js +1 -1
  420. package/dist/crypto/core/constants.js +0 -4
  421. package/dist/esm/crypto/core/constants.js +0 -1
  422. package/dist/esm/retry/outbound.js +0 -82
  423. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  424. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
  425. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  426. package/dist/esm/store/providers/sqlite/connection.js +0 -245
  427. package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
  428. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
  429. package/dist/esm/store/providers/sqlite/message.store.js +0 -132
  430. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  431. package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
  432. package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
  433. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
  434. package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
  435. package/dist/esm/store/providers/sqlite/table-names.js +0 -107
  436. package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
  437. package/dist/retry/outbound.js +0 -87
  438. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  439. package/dist/store/providers/sqlite/appstate.store.js +0 -254
  440. package/dist/store/providers/sqlite/auth.store.js +0 -180
  441. package/dist/store/providers/sqlite/connection.js +0 -281
  442. package/dist/store/providers/sqlite/contact.store.js +0 -78
  443. package/dist/store/providers/sqlite/device-list.store.js +0 -131
  444. package/dist/store/providers/sqlite/message.store.js +0 -136
  445. package/dist/store/providers/sqlite/migrations.js +0 -350
  446. package/dist/store/providers/sqlite/participants.store.js +0 -81
  447. package/dist/store/providers/sqlite/retry.store.js +0 -145
  448. package/dist/store/providers/sqlite/sender-key.store.js +0 -202
  449. package/dist/store/providers/sqlite/signal.store.js +0 -439
  450. package/dist/store/providers/sqlite/table-names.js +0 -113
  451. package/dist/store/providers/sqlite/thread.store.js +0 -89
  452. package/dist/types/appstate/store/sqlite.d.ts +0 -7
  453. package/dist/types/crypto/core/constants.d.ts +0 -1
  454. package/dist/types/retry/outbound.d.ts +0 -4
  455. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  456. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
  457. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  458. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  459. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
  460. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
  461. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
  462. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  463. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
  464. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
  465. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
  466. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
  467. package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
  468. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
@@ -1,12 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GROUP_L = exports.FIELD_P = void 0;
4
3
  exports.mod = mod;
5
4
  exports.modGroup = modGroup;
6
5
  exports.modInv = modInv;
7
6
  const constants_1 = require("../math/constants");
8
- Object.defineProperty(exports, "FIELD_P", { enumerable: true, get: function () { return constants_1.FIELD_P; } });
9
- Object.defineProperty(exports, "GROUP_L", { enumerable: true, get: function () { return constants_1.GROUP_L; } });
7
+ const fe_1 = require("../math/fe");
10
8
  function mod(value, modulus = constants_1.FIELD_P) {
11
9
  const remainder = value % modulus;
12
10
  return remainder >= 0n ? remainder : remainder + modulus;
@@ -18,8 +16,17 @@ function modInv(value, modulus = constants_1.FIELD_P) {
18
16
  if (value === 0n) {
19
17
  throw new Error('field inversion by zero');
20
18
  }
19
+ if (modulus === constants_1.FIELD_P) {
20
+ return fieldInv(value);
21
+ }
21
22
  return modPow(value, modulus - 2n, modulus);
22
23
  }
24
+ function fieldInv(x) {
25
+ const a = (0, fe_1.feFromBigInt)(mod(x));
26
+ const out = (0, fe_1.fe)();
27
+ (0, fe_1.feInv)(out, a);
28
+ return (0, fe_1.feToBigInt)(out);
29
+ }
23
30
  function modPow(base, exponent, modulus) {
24
31
  if (modulus <= 0n) {
25
32
  throw new Error('modulus must be positive');
@@ -180,7 +180,7 @@ export class WaAppStateCrypto {
180
180
  octetLength[octetLength.length - 1] = associatedData.byteLength & 0xff;
181
181
  const key = await importHmacSha512Key(valueMacKey);
182
182
  const full = await hmacSign(key, concatBytes([associatedData, cipherWithIv, octetLength]));
183
- return full.slice(0, APP_STATE_VALUE_MAC_LENGTH);
183
+ return full.subarray(0, APP_STATE_VALUE_MAC_LENGTH);
184
184
  }
185
185
  touchDerivedKeysCacheEntry(cacheKey, keys) {
186
186
  if (this.derivedKeysCacheMaxSize <= 0) {
@@ -164,7 +164,12 @@ export class WaAppStateSyncClient {
164
164
  }
165
165
  }
166
166
  async syncCollectionsRound(collections, pendingByCollection, options) {
167
- const requests = await Promise.all(collections.map((collection) => this.buildCollectionSyncRequest(collection, pendingByCollection)));
167
+ const activeSyncKey = await this.store.getActiveSyncKey();
168
+ const requestPromises = new Array(collections.length);
169
+ for (let index = 0; index < collections.length; index += 1) {
170
+ requestPromises[index] = this.buildCollectionSyncRequest(collections[index], pendingByCollection, activeSyncKey);
171
+ }
172
+ const requests = await Promise.all(requestPromises);
168
173
  const collectionNodes = new Array(requests.length);
169
174
  const outgoingContexts = new Map();
170
175
  const skippedUploadCollections = new Set();
@@ -180,21 +185,26 @@ export class WaAppStateSyncClient {
180
185
  }
181
186
  const iqNode = this.buildSyncIqNode(collectionNodes);
182
187
  const payloadByCollection = await this.fetchSyncPayloadByCollection(iqNode, options.timeoutMs ?? this.defaultTimeoutMs);
183
- const collectionOutcomes = await Promise.all(collections.map((collection) => this.processCollectionRound({
184
- collection,
185
- payloadByCollection,
186
- pendingByCollection,
187
- options,
188
- outgoingContexts,
189
- skippedUploadCollections
190
- })));
188
+ const collectionOutcomePromises = new Array(collections.length);
189
+ for (let index = 0; index < collections.length; index += 1) {
190
+ collectionOutcomePromises[index] = this.processCollectionRound({
191
+ collection: collections[index],
192
+ payloadByCollection,
193
+ pendingByCollection,
194
+ options,
195
+ outgoingContexts,
196
+ skippedUploadCollections
197
+ });
198
+ }
199
+ const collectionOutcomes = await Promise.all(collectionOutcomePromises);
191
200
  const results = [];
192
201
  const collectionsToRefetch = [];
193
202
  const blockedCollections = [];
194
203
  const missingKeyIds = [];
195
204
  const missingKeyIdHexes = new Set();
196
205
  let stateChanged = false;
197
- for (const entry of collectionOutcomes) {
206
+ for (let index = 0; index < collectionOutcomes.length; index += 1) {
207
+ const entry = collectionOutcomes[index];
198
208
  results.push(entry.result);
199
209
  if (entry.shouldRefetch) {
200
210
  collectionsToRefetch.push(entry.collection);
@@ -221,7 +231,7 @@ export class WaAppStateSyncClient {
221
231
  blockedCollections
222
232
  };
223
233
  }
224
- async buildCollectionSyncRequest(collection, pendingByCollection) {
234
+ async buildCollectionSyncRequest(collection, pendingByCollection, activeSyncKey) {
225
235
  const collectionState = await this.getCollectionState(collection);
226
236
  const hasPersistedState = collectionState.initialized;
227
237
  const attrs = {
@@ -242,7 +252,7 @@ export class WaAppStateSyncClient {
242
252
  });
243
253
  }
244
254
  else {
245
- const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations);
255
+ const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations, activeSyncKey);
246
256
  outgoingContext = outgoing.context;
247
257
  children.push({
248
258
  tag: WA_NODE_TAGS.PATCH,
@@ -328,14 +338,14 @@ export class WaAppStateSyncClient {
328
338
  const snapshotBytes = await downloader(payload.collection, 'snapshot', payload.snapshotReference);
329
339
  const snapshot = this.validateSnapshot(payload.collection, proto.SyncdSnapshot.decode(snapshotBytes));
330
340
  const snapshotMutations = await this.applySnapshot(payload.collection, snapshot);
331
- appliedMutations = appliedMutations.concat(snapshotMutations);
341
+ appliedMutations.push(...snapshotMutations);
332
342
  collectionStateChanged = true;
333
343
  }
334
344
  if (payload.patches.length > 0) {
335
345
  const readyPatches = await this.resolveReadyPatches(payload, options);
336
346
  for (const readyPatch of readyPatches) {
337
347
  const patchMutations = await this.applyPatch(payload.collection, readyPatch);
338
- appliedMutations = appliedMutations.concat(patchMutations);
348
+ appliedMutations.push(...patchMutations);
339
349
  collectionStateChanged = true;
340
350
  }
341
351
  }
@@ -424,13 +434,12 @@ export class WaAppStateSyncClient {
424
434
  }
425
435
  }
426
436
  async resolveReadyPatches(payload, options) {
427
- const sortedPatches = payload.patches
428
- .map((patch) => ({
429
- patch,
430
- sortVersion: this.parseCollectionPatchVersion(payload.collection, patch)
431
- }))
432
- .sort((left, right) => left.sortVersion - right.sortVersion)
433
- .map((entry) => entry.patch);
437
+ const sortedPatches = payload.patches.slice();
438
+ const sortVersions = new Map();
439
+ for (const patch of sortedPatches) {
440
+ sortVersions.set(patch, this.parseCollectionPatchVersion(payload.collection, patch));
441
+ }
442
+ sortedPatches.sort((left, right) => sortVersions.get(left) - sortVersions.get(right));
434
443
  return Promise.all(sortedPatches.map(async (patch) => {
435
444
  let readyPatch = patch;
436
445
  if ((!readyPatch.mutations || readyPatch.mutations.length === 0) &&
@@ -517,7 +526,13 @@ export class WaAppStateSyncClient {
517
526
  timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `snapshot.record.value.timestamp (${collection})`)
518
527
  });
519
528
  }
520
- const ltHash = await this.crypto.ltHashAdd(APP_STATE_EMPTY_LT_HASH, Array.from(indexValueMap.values()));
529
+ const ltHashInput = new Array(indexValueMap.size);
530
+ let ltHashInputIndex = 0;
531
+ for (const valueMac of indexValueMap.values()) {
532
+ ltHashInput[ltHashInputIndex] = valueMac;
533
+ ltHashInputIndex += 1;
534
+ }
535
+ const ltHash = await this.crypto.ltHashAdd(APP_STATE_EMPTY_LT_HASH, ltHashInput);
521
536
  const expectedSnapshotMac = await this.crypto.generateSnapshotMac(keyData, ltHash, version, collection);
522
537
  if (!uint8Equal(expectedSnapshotMac, snapshot.mac)) {
523
538
  throw new Error(`snapshot MAC mismatch for ${collection}`);
@@ -551,35 +566,52 @@ export class WaAppStateSyncClient {
551
566
  const nextState = await this.computeNextCollectionState(current.hash, current.indexValueMap, macMutations, collection);
552
567
  await this.assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextState.hash, valueMacs);
553
568
  this.setCollectionState(collection, patchVersion, nextState.hash, nextState.indexValueMap);
554
- return decryptedMutations.slice();
569
+ return decryptedMutations;
555
570
  }
556
571
  async decryptSnapshotRecords(collection, snapshot) {
557
- const records = (snapshot.records ?? []).map((record) => ({
558
- indexMac: decodeProtoBytes(record.index?.blob, `snapshot.record.index.blob (${collection})`),
559
- valueBlob: decodeProtoBytes(record.value?.blob, `snapshot.record.value.blob (${collection})`),
560
- recordKeyId: decodeProtoBytes(record.keyId?.id, `snapshot.record.keyId.id (${collection})`)
561
- }));
562
- await this.preloadKeyData(records.map((record) => record.recordKeyId));
563
- return Promise.all(records.map(async ({ indexMac, valueBlob, recordKeyId }) => {
564
- const recordKeyData = await this.getKeyData(recordKeyId);
565
- if (!recordKeyData) {
566
- throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${bytesToHex(recordKeyId)} for ${collection}`, recordKeyId, collection);
567
- }
568
- const decrypted = await this.crypto.decryptMutation({
569
- operation: proto.SyncdMutation.SyncdOperation.SET,
570
- keyId: recordKeyId,
571
- keyData: recordKeyData,
572
- indexMac,
573
- valueBlob
574
- });
575
- return {
576
- decrypted,
572
+ const rawRecords = snapshot.records ?? [];
573
+ const records = new Array(rawRecords.length);
574
+ const recordKeyIds = new Array(rawRecords.length);
575
+ for (let i = 0; i < rawRecords.length; i += 1) {
576
+ const record = rawRecords[i];
577
+ const recordKeyId = decodeProtoBytes(record.keyId?.id, `snapshot.record.keyId.id (${collection})`);
578
+ records[i] = {
579
+ indexMac: decodeProtoBytes(record.index?.blob, `snapshot.record.index.blob (${collection})`),
580
+ valueBlob: decodeProtoBytes(record.value?.blob, `snapshot.record.value.blob (${collection})`),
577
581
  recordKeyId
578
582
  };
579
- }));
583
+ recordKeyIds[i] = recordKeyId;
584
+ }
585
+ await this.preloadKeyData(recordKeyIds);
586
+ const decryptTasks = new Array(records.length);
587
+ for (let i = 0; i < records.length; i += 1) {
588
+ const { indexMac, valueBlob, recordKeyId } = records[i];
589
+ decryptTasks[i] = (async () => {
590
+ const recordKeyData = await this.getKeyData(recordKeyId);
591
+ if (!recordKeyData) {
592
+ throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${bytesToHex(recordKeyId)} for ${collection}`, recordKeyId, collection);
593
+ }
594
+ const decrypted = await this.crypto.decryptMutation({
595
+ operation: proto.SyncdMutation.SyncdOperation.SET,
596
+ keyId: recordKeyId,
597
+ keyData: recordKeyData,
598
+ indexMac,
599
+ valueBlob
600
+ });
601
+ return {
602
+ decrypted,
603
+ recordKeyId
604
+ };
605
+ })();
606
+ }
607
+ return Promise.all(decryptTasks);
580
608
  }
581
609
  async decryptPatchMutations(collection, patch) {
582
- const parsedMutations = (patch.mutations ?? []).map((mutation) => {
610
+ const rawMutations = patch.mutations ?? [];
611
+ const parsedMutations = new Array(rawMutations.length);
612
+ const mutationKeyIds = new Array(rawMutations.length);
613
+ for (let i = 0; i < rawMutations.length; i += 1) {
614
+ const mutation = rawMutations[i];
583
615
  const operationCode = mutation.operation;
584
616
  if (operationCode === null || operationCode === undefined) {
585
617
  throw new Error(`patch mutation is missing operation (${collection})`);
@@ -588,42 +620,49 @@ export class WaAppStateSyncClient {
588
620
  if (!record) {
589
621
  throw new Error(`patch mutation is missing record (${collection})`);
590
622
  }
591
- return {
623
+ const recordKeyId = decodeProtoBytes(record.keyId?.id, `patch.record.keyId.id (${collection})`);
624
+ parsedMutations[i] = {
592
625
  operationCode,
593
626
  indexMac: decodeProtoBytes(record.index?.blob, `patch.record.index.blob (${collection})`),
594
627
  valueBlob: decodeProtoBytes(record.value?.blob, `patch.record.value.blob (${collection})`),
595
- recordKeyId: decodeProtoBytes(record.keyId?.id, `patch.record.keyId.id (${collection})`)
596
- };
597
- });
598
- await this.preloadKeyData(parsedMutations.map((mutation) => mutation.recordKeyId));
599
- return Promise.all(parsedMutations.map(async ({ operationCode, indexMac, valueBlob, recordKeyId }) => {
600
- const recordKeyData = await this.getKeyData(recordKeyId);
601
- if (!recordKeyData) {
602
- throw new WaAppStateMissingKeyError(`missing mutation key ${bytesToHex(recordKeyId)} for ${collection}`, recordKeyId, collection);
603
- }
604
- const decrypted = await this.crypto.decryptMutation({
605
- operation: operationCode,
606
- keyId: recordKeyId,
607
- keyData: recordKeyData,
608
- indexMac,
609
- valueBlob
610
- });
611
- return {
612
- collection,
613
- operation: operationCode === proto.SyncdMutation.SyncdOperation.REMOVE
614
- ? 'remove'
615
- : 'set',
616
- source: 'patch',
617
- operationCode,
618
- index: decrypted.index,
619
- value: decrypted.value,
620
- version: decrypted.version,
621
- indexMac: decrypted.indexMac,
622
- valueMac: decrypted.valueMac,
623
- keyId: recordKeyId,
624
- timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
628
+ recordKeyId
625
629
  };
626
- }));
630
+ mutationKeyIds[i] = recordKeyId;
631
+ }
632
+ await this.preloadKeyData(mutationKeyIds);
633
+ const decryptTasks = new Array(parsedMutations.length);
634
+ for (let i = 0; i < parsedMutations.length; i += 1) {
635
+ const { operationCode, indexMac, valueBlob, recordKeyId } = parsedMutations[i];
636
+ decryptTasks[i] = (async () => {
637
+ const recordKeyData = await this.getKeyData(recordKeyId);
638
+ if (!recordKeyData) {
639
+ throw new WaAppStateMissingKeyError(`missing mutation key ${bytesToHex(recordKeyId)} for ${collection}`, recordKeyId, collection);
640
+ }
641
+ const decrypted = await this.crypto.decryptMutation({
642
+ operation: operationCode,
643
+ keyId: recordKeyId,
644
+ keyData: recordKeyData,
645
+ indexMac,
646
+ valueBlob
647
+ });
648
+ return {
649
+ collection,
650
+ operation: operationCode === proto.SyncdMutation.SyncdOperation.REMOVE
651
+ ? 'remove'
652
+ : 'set',
653
+ source: 'patch',
654
+ operationCode,
655
+ index: decrypted.index,
656
+ value: decrypted.value,
657
+ version: decrypted.version,
658
+ indexMac: decrypted.indexMac,
659
+ valueMac: decrypted.valueMac,
660
+ keyId: recordKeyId,
661
+ timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
662
+ };
663
+ })();
664
+ }
665
+ return Promise.all(decryptTasks);
627
666
  }
628
667
  async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash, valueMacs) {
629
668
  const snapshotMac = decodeProtoBytes(patch.snapshotMac, `patch.snapshotMac (${collection})`);
@@ -637,8 +676,7 @@ export class WaAppStateSyncClient {
637
676
  throw new Error(`patch MAC mismatch for ${collection}`);
638
677
  }
639
678
  }
640
- async buildOutgoingPatch(collection, snapshot, pendingMutations) {
641
- const activeKey = await this.store.getActiveSyncKey();
679
+ async buildOutgoingPatch(collection, snapshot, pendingMutations, activeKey) {
642
680
  if (!activeKey) {
643
681
  throw new WaAppStateMissingKeyError(`no sync key available to upload ${collection}`, null, collection);
644
682
  }
@@ -657,23 +695,30 @@ export class WaAppStateSyncClient {
657
695
  });
658
696
  return { operationCode, encrypted };
659
697
  }));
660
- const encryptedMutations = encryptedResults.map(({ operationCode, encrypted }) => ({
661
- operation: operationCode,
662
- record: {
663
- keyId: { id: activeKey.keyId },
664
- index: { blob: encrypted.indexMac },
665
- value: { blob: encrypted.valueBlob }
666
- }
667
- }));
668
- const macMutations = encryptedResults.map(({ operationCode, encrypted }) => ({
669
- operation: operationCode,
670
- indexMac: encrypted.indexMac,
671
- valueMac: encrypted.valueMac
672
- }));
698
+ const encryptedMutations = new Array(encryptedResults.length);
699
+ const macMutations = new Array(encryptedResults.length);
700
+ const valueMacs = new Array(encryptedResults.length);
701
+ for (let i = 0; i < encryptedResults.length; i += 1) {
702
+ const { operationCode, encrypted } = encryptedResults[i];
703
+ encryptedMutations[i] = {
704
+ operation: operationCode,
705
+ record: {
706
+ keyId: { id: activeKey.keyId },
707
+ index: { blob: encrypted.indexMac },
708
+ value: { blob: encrypted.valueBlob }
709
+ }
710
+ };
711
+ macMutations[i] = {
712
+ operation: operationCode,
713
+ indexMac: encrypted.indexMac,
714
+ valueMac: encrypted.valueMac
715
+ };
716
+ valueMacs[i] = encrypted.valueMac;
717
+ }
673
718
  const nextState = await this.computeNextCollectionState(snapshot.hash, snapshot.indexValueMap, macMutations, collection);
674
719
  const patchVersion = snapshot.version + 1;
675
720
  const snapshotMac = await this.crypto.generateSnapshotMac(activeKey.keyData, nextState.hash, patchVersion, collection);
676
- const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, macMutations.map((item) => item.valueMac), patchVersion, collection);
721
+ const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, valueMacs, patchVersion, collection);
677
722
  const deviceIndex = this.resolveDeviceIndex();
678
723
  const clientDebugData = this.buildPatchClientDebugData();
679
724
  const encodedPatch = proto.SyncdPatch.encode({
@@ -1,5 +1,5 @@
1
- import { proto } from '../../proto.js';
2
- import { asBytes, asNumber, asOptionalBytes, asString } from '../../util/coercion.js';
1
+ import { proto } from '../proto.js';
2
+ import { asBytes, asNumber, asOptionalBytes, asString } from '../util/coercion.js';
3
3
  export function encodeAppStateFingerprint(fingerprint) {
4
4
  if (!fingerprint) {
5
5
  return null;
@@ -20,12 +20,17 @@ export function decodeAppStateFingerprint(raw) {
20
20
  }
21
21
  }
22
22
  export function decodeAppStateSyncKeys(rows) {
23
- return rows.map((row) => ({
24
- keyId: asBytes(row.key_id, 'appstate_sync_keys.key_id'),
25
- keyData: asBytes(row.key_data, 'appstate_sync_keys.key_data'),
26
- timestamp: asNumber(row.timestamp, 'appstate_sync_keys.timestamp'),
27
- fingerprint: decodeAppStateFingerprint(row.fingerprint)
28
- }));
23
+ const decoded = new Array(rows.length);
24
+ for (let i = 0; i < rows.length; i += 1) {
25
+ const row = rows[i];
26
+ decoded[i] = {
27
+ keyId: asBytes(row.key_id, 'appstate_sync_keys.key_id'),
28
+ keyData: asBytes(row.key_data, 'appstate_sync_keys.key_data'),
29
+ timestamp: asNumber(row.timestamp, 'appstate_sync_keys.timestamp'),
30
+ fingerprint: decodeAppStateFingerprint(row.fingerprint)
31
+ };
32
+ }
33
+ return decoded;
29
34
  }
30
35
  export function decodeAppStateCollections(versionRows, valueRows) {
31
36
  const valueMapByCollection = new Map();
@@ -1,6 +1,6 @@
1
1
  export * from './constants.js';
2
+ export { encodeAppStateFingerprint, decodeAppStateFingerprint, decodeAppStateCollections, decodeAppStateSyncKeys } from './encoding.js';
2
3
  export * from './utils.js';
3
4
  export { WaAppStateCrypto } from './WaAppStateCrypto.js';
4
- export { WaAppStateMissingKeyError } from './WaAppStateSyncClient.js';
5
- export { parseCollectionState, parseSyncResponse } from './WaAppStateSyncResponseParser.js';
5
+ export { parseSyncResponse } from './WaAppStateSyncResponseParser.js';
6
6
  export { WaAppStateSyncClient } from './WaAppStateSyncClient.js';
@@ -1,10 +1,10 @@
1
1
  import { WA_APP_STATE_COLLECTIONS, WA_APP_STATE_KEY_TYPES } from '../protocol/constants.js';
2
- import { decodeProtoBytes, intToBytes } from '../util/bytes.js';
2
+ import { decodeProtoBytes } from '../util/bytes.js';
3
3
  const APP_STATE_COLLECTION_NAMES = new Set(Object.values(WA_APP_STATE_COLLECTIONS));
4
4
  export function parseCollectionName(value) {
5
5
  return value && APP_STATE_COLLECTION_NAMES.has(value) ? value : null;
6
6
  }
7
- export function keyDeviceId(keyId) {
7
+ function keyDeviceId(keyId) {
8
8
  return keyId.byteLength < 6 ? null : (keyId[0] << 8) | keyId[1];
9
9
  }
10
10
  export function keyEpoch(keyId) {
@@ -36,9 +36,6 @@ export function pickActiveSyncKey(keys) {
36
36
  }
37
37
  return active;
38
38
  }
39
- export function toNetworkOrder64(value) {
40
- return intToBytes(8, value);
41
- }
42
39
  export async function downloadExternalBlobReference(mediaTransfer, reference) {
43
40
  if (!reference.directPath) {
44
41
  throw new Error('external blob reference is missing directPath');
@@ -50,7 +50,7 @@ export class WaAuthClient {
50
50
  getState(connected = false) {
51
51
  return {
52
52
  connected,
53
- registered: hasMeJid(this.credentials),
53
+ registered: this.credentials?.meJid !== null && this.credentials?.meJid !== undefined,
54
54
  hasQr: this.qrFlow.hasQr(),
55
55
  hasPairingCode: this.pairingFlow.hasPairingSession()
56
56
  };
@@ -67,7 +67,7 @@ export class WaAuthClient {
67
67
  signalStore: this.signalStore
68
68
  });
69
69
  this.logger.info('auth client credentials ready', {
70
- registered: hasMeJid(this.credentials)
70
+ registered: this.credentials?.meJid !== null && this.credentials?.meJid !== undefined
71
71
  });
72
72
  return this.credentials;
73
73
  });
@@ -77,7 +77,8 @@ export class WaAuthClient {
77
77
  return buildCommsConfig(this.logger, this.requireCredentials(), socketOptions, {
78
78
  deviceBrowser: this.options.deviceBrowser,
79
79
  deviceOsDisplayName: this.options.deviceOsDisplayName,
80
- requireFullSync: this.options.requireFullSync
80
+ requireFullSync: this.options.requireFullSync,
81
+ version: this.options.version
81
82
  });
82
83
  }
83
84
  async clearTransientState() {
@@ -87,9 +88,8 @@ export class WaAuthClient {
87
88
  }
88
89
  async clearStoredCredentials() {
89
90
  this.logger.warn('auth client clearing stored credentials');
90
- await this.authStore.clear();
91
91
  this.credentials = null;
92
- await this.clearTransientState();
92
+ await Promise.all([this.authStore.clear(), this.clearTransientState()]);
93
93
  }
94
94
  async persistServerStaticKey(serverStaticKey) {
95
95
  this.logger.debug('persisting server static key', {
@@ -142,46 +142,38 @@ export class WaAuthClient {
142
142
  });
143
143
  }
144
144
  async persistSuccessAttributes(attributes) {
145
- await this.patchCredentials((credentials) => {
146
- return {
147
- ...credentials,
148
- meLid: attributes.meLid ?? credentials.meLid,
149
- meDisplayName: attributes.meDisplayName ?? credentials.meDisplayName,
150
- companionEncStatic: attributes.companionEncStatic ?? credentials.companionEncStatic,
151
- lastSuccessTs: attributes.lastSuccessTs ?? credentials.lastSuccessTs,
152
- propsVersion: attributes.propsVersion ?? credentials.propsVersion,
153
- abPropsVersion: attributes.abPropsVersion ?? credentials.abPropsVersion,
154
- connectionLocation: attributes.connectionLocation ?? credentials.connectionLocation,
155
- accountCreationTs: attributes.accountCreationTs ?? credentials.accountCreationTs
156
- };
157
- }, {
158
- shouldPersist: (current, next) => next.meLid !== current.meLid ||
159
- next.meDisplayName !== current.meDisplayName ||
160
- (current.companionEncStatic === undefined) !==
161
- (next.companionEncStatic === undefined) ||
145
+ let persistDiff;
146
+ const computeDiff = (current, next) => ({
147
+ lidChanged: next.meLid !== current.meLid,
148
+ displayNameChanged: next.meDisplayName !== current.meDisplayName,
149
+ companionChanged: (current.companionEncStatic === undefined) !==
150
+ (next.companionEncStatic === undefined) ||
162
151
  (current.companionEncStatic !== undefined &&
163
152
  next.companionEncStatic !== undefined &&
164
- !uint8Equal(current.companionEncStatic, next.companionEncStatic)) ||
165
- next.lastSuccessTs !== current.lastSuccessTs ||
166
- next.propsVersion !== current.propsVersion ||
167
- next.abPropsVersion !== current.abPropsVersion ||
168
- next.connectionLocation !== current.connectionLocation ||
169
- next.accountCreationTs !== current.accountCreationTs,
170
- onPersist: (current, next) => {
171
- this.logger.debug('persisting success attributes', {
172
- lidChanged: next.meLid !== current.meLid,
173
- displayNameChanged: next.meDisplayName !== current.meDisplayName,
174
- companionChanged: (current.companionEncStatic === undefined) !==
175
- (next.companionEncStatic === undefined) ||
176
- (current.companionEncStatic !== undefined &&
177
- next.companionEncStatic !== undefined &&
178
- !uint8Equal(current.companionEncStatic, next.companionEncStatic)),
179
- lastSuccessTsChanged: next.lastSuccessTs !== current.lastSuccessTs,
180
- propsVersionChanged: next.propsVersion !== current.propsVersion,
181
- abPropsVersionChanged: next.abPropsVersion !== current.abPropsVersion,
182
- connectionLocationChanged: next.connectionLocation !== current.connectionLocation,
183
- accountCreationTsChanged: next.accountCreationTs !== current.accountCreationTs
184
- });
153
+ !uint8Equal(current.companionEncStatic, next.companionEncStatic)),
154
+ lastSuccessTsChanged: next.lastSuccessTs !== current.lastSuccessTs,
155
+ propsVersionChanged: next.propsVersion !== current.propsVersion,
156
+ abPropsVersionChanged: next.abPropsVersion !== current.abPropsVersion,
157
+ connectionLocationChanged: next.connectionLocation !== current.connectionLocation,
158
+ accountCreationTsChanged: next.accountCreationTs !== current.accountCreationTs
159
+ });
160
+ await this.patchCredentials((credentials) => ({
161
+ ...credentials,
162
+ meLid: attributes.meLid ?? credentials.meLid,
163
+ meDisplayName: attributes.meDisplayName ?? credentials.meDisplayName,
164
+ companionEncStatic: attributes.companionEncStatic ?? credentials.companionEncStatic,
165
+ lastSuccessTs: attributes.lastSuccessTs ?? credentials.lastSuccessTs,
166
+ propsVersion: attributes.propsVersion ?? credentials.propsVersion,
167
+ abPropsVersion: attributes.abPropsVersion ?? credentials.abPropsVersion,
168
+ connectionLocation: attributes.connectionLocation ?? credentials.connectionLocation,
169
+ accountCreationTs: attributes.accountCreationTs ?? credentials.accountCreationTs
170
+ }), {
171
+ shouldPersist: (current, next) => {
172
+ persistDiff = computeDiff(current, next);
173
+ return Object.values(persistDiff).some(Boolean);
174
+ },
175
+ onPersist: () => {
176
+ this.logger.debug('persisting success attributes', persistDiff);
185
177
  }
186
178
  });
187
179
  }
@@ -230,7 +222,7 @@ export class WaAuthClient {
230
222
  }
231
223
  async updateCredentials(credentials) {
232
224
  this.logger.trace('auth client update credentials', {
233
- registered: hasMeJid(credentials)
225
+ registered: credentials?.meJid !== null && credentials?.meJid !== undefined
234
226
  });
235
227
  this.credentials = credentials;
236
228
  await persistCredentials({
@@ -250,6 +242,3 @@ export class WaAuthClient {
250
242
  this.callbacks.onError?.(error);
251
243
  }
252
244
  }
253
- function hasMeJid(credentials) {
254
- return credentials?.meJid !== null && credentials?.meJid !== undefined;
255
- }
@@ -15,7 +15,7 @@ export async function loadOrCreateCredentials(args) {
15
15
  return credentials;
16
16
  }
17
17
  args.logger.debug('auth credentials loaded from store', {
18
- registered: isRegistered(existing),
18
+ registered: existing.meJid !== null && existing.meJid !== undefined,
19
19
  hasServerStaticKey: existing.serverStaticKey !== null && existing.serverStaticKey !== undefined
20
20
  });
21
21
  if (!existing.meJid && !(await hasValidSignedPreKey(args.logger, existing))) {
@@ -30,7 +30,7 @@ export async function loadOrCreateCredentials(args) {
30
30
  }
31
31
  export async function persistCredentials(args, credentials) {
32
32
  args.logger.trace('persisting auth credentials', {
33
- registered: isRegistered(credentials)
33
+ registered: credentials.meJid !== null && credentials.meJid !== undefined
34
34
  });
35
35
  await args.authStore.save(credentials);
36
36
  }
@@ -63,7 +63,8 @@ export function buildCommsConfig(logger, credentials, socketOptions, clientOptio
63
63
  username: loginIdentity.username,
64
64
  device: loginIdentity.device,
65
65
  deviceBrowser: clientOptions.deviceBrowser,
66
- deviceOsDisplayName: clientOptions.deviceOsDisplayName
66
+ deviceOsDisplayName: clientOptions.deviceOsDisplayName,
67
+ versionBase: clientOptions.version
67
68
  }
68
69
  : undefined,
69
70
  registrationPayloadConfig: !loginIdentity
@@ -72,7 +73,8 @@ export function buildCommsConfig(logger, credentials, socketOptions, clientOptio
72
73
  signedPreKey: credentials.signedPreKey,
73
74
  deviceBrowser: clientOptions.deviceBrowser,
74
75
  deviceOsDisplayName: clientOptions.deviceOsDisplayName,
75
- requireFullSync: clientOptions.requireFullSync
76
+ requireFullSync: clientOptions.requireFullSync,
77
+ versionBase: clientOptions.version
76
78
  }
77
79
  : undefined
78
80
  }
@@ -95,6 +97,7 @@ async function createFreshCredentials(signalStore, logger) {
95
97
  }
96
98
  async function createFreshAndPersistCredentials(args) {
97
99
  const credentials = await createFreshCredentials(args.signalStore, args.logger);
100
+ // Persist credentials first so signal restore never commits state for credentials that failed to save.
98
101
  await args.authStore.save(credentials);
99
102
  await restoreSignalStore(args.signalStore, credentials);
100
103
  return credentials;
@@ -120,6 +123,3 @@ async function restoreSignalStore(signalStore, credentials) {
120
123
  signalStore.setServerHasPreKeys(credentials.serverHasPreKeys === true)
121
124
  ]);
122
125
  }
123
- function isRegistered(credentials) {
124
- return credentials.meJid !== null && credentials.meJid !== undefined;
125
- }
@@ -1,4 +1,2 @@
1
1
  export * from './types.js';
2
2
  export { WaAuthClient } from './WaAuthClient.js';
3
- export { completeCompanionFinish, createCompanionHello } from './pairing/WaPairingCodeCrypto.js';
4
- export { WaAuthSqliteStore } from '../store/providers/sqlite/auth.store.js';