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
package/README.md CHANGED
@@ -112,6 +112,7 @@ Auth state is persisted in `.auth/state.sqlite`.
112
112
 
113
113
  ```ts
114
114
  import { createPinoLogger, createStore, WaClient } from 'zapo-js'
115
+ import { createSqliteStore } from '@zapo-js/store-sqlite'
115
116
 
116
117
  const logger = await createPinoLogger({
117
118
  level: 'info',
@@ -119,14 +120,21 @@ const logger = await createPinoLogger({
119
120
  })
120
121
 
121
122
  const store = createStore({
122
- sqlite: {
123
- path: '.auth/state.sqlite',
124
- driver: 'auto'
123
+ backends: {
124
+ sqlite: createSqliteStore({
125
+ path: '.auth/state.sqlite',
126
+ driver: 'auto'
127
+ })
125
128
  },
126
129
  providers: {
130
+ auth: 'sqlite',
131
+ signal: 'sqlite',
132
+ senderKey: 'sqlite',
133
+ appState: 'sqlite',
127
134
  messages: 'sqlite',
128
135
  threads: 'sqlite',
129
- contacts: 'sqlite'
136
+ contacts: 'sqlite',
137
+ privacyToken: 'sqlite'
130
138
  }
131
139
  })
132
140
 
@@ -183,7 +183,7 @@ class WaAppStateCrypto {
183
183
  octetLength[octetLength.length - 1] = associatedData.byteLength & 0xff;
184
184
  const key = await (0, primitives_1.importHmacSha512Key)(valueMacKey);
185
185
  const full = await (0, primitives_1.hmacSign)(key, (0, bytes_2.concatBytes)([associatedData, cipherWithIv, octetLength]));
186
- return full.slice(0, constants_1.APP_STATE_VALUE_MAC_LENGTH);
186
+ return full.subarray(0, constants_1.APP_STATE_VALUE_MAC_LENGTH);
187
187
  }
188
188
  touchDerivedKeysCacheEntry(cacheKey, keys) {
189
189
  if (this.derivedKeysCacheMaxSize <= 0) {
@@ -168,7 +168,12 @@ class WaAppStateSyncClient {
168
168
  }
169
169
  }
170
170
  async syncCollectionsRound(collections, pendingByCollection, options) {
171
- const requests = await Promise.all(collections.map((collection) => this.buildCollectionSyncRequest(collection, pendingByCollection)));
171
+ const activeSyncKey = await this.store.getActiveSyncKey();
172
+ const requestPromises = new Array(collections.length);
173
+ for (let index = 0; index < collections.length; index += 1) {
174
+ requestPromises[index] = this.buildCollectionSyncRequest(collections[index], pendingByCollection, activeSyncKey);
175
+ }
176
+ const requests = await Promise.all(requestPromises);
172
177
  const collectionNodes = new Array(requests.length);
173
178
  const outgoingContexts = new Map();
174
179
  const skippedUploadCollections = new Set();
@@ -184,21 +189,26 @@ class WaAppStateSyncClient {
184
189
  }
185
190
  const iqNode = this.buildSyncIqNode(collectionNodes);
186
191
  const payloadByCollection = await this.fetchSyncPayloadByCollection(iqNode, options.timeoutMs ?? this.defaultTimeoutMs);
187
- const collectionOutcomes = await Promise.all(collections.map((collection) => this.processCollectionRound({
188
- collection,
189
- payloadByCollection,
190
- pendingByCollection,
191
- options,
192
- outgoingContexts,
193
- skippedUploadCollections
194
- })));
192
+ const collectionOutcomePromises = new Array(collections.length);
193
+ for (let index = 0; index < collections.length; index += 1) {
194
+ collectionOutcomePromises[index] = this.processCollectionRound({
195
+ collection: collections[index],
196
+ payloadByCollection,
197
+ pendingByCollection,
198
+ options,
199
+ outgoingContexts,
200
+ skippedUploadCollections
201
+ });
202
+ }
203
+ const collectionOutcomes = await Promise.all(collectionOutcomePromises);
195
204
  const results = [];
196
205
  const collectionsToRefetch = [];
197
206
  const blockedCollections = [];
198
207
  const missingKeyIds = [];
199
208
  const missingKeyIdHexes = new Set();
200
209
  let stateChanged = false;
201
- for (const entry of collectionOutcomes) {
210
+ for (let index = 0; index < collectionOutcomes.length; index += 1) {
211
+ const entry = collectionOutcomes[index];
202
212
  results.push(entry.result);
203
213
  if (entry.shouldRefetch) {
204
214
  collectionsToRefetch.push(entry.collection);
@@ -225,7 +235,7 @@ class WaAppStateSyncClient {
225
235
  blockedCollections
226
236
  };
227
237
  }
228
- async buildCollectionSyncRequest(collection, pendingByCollection) {
238
+ async buildCollectionSyncRequest(collection, pendingByCollection, activeSyncKey) {
229
239
  const collectionState = await this.getCollectionState(collection);
230
240
  const hasPersistedState = collectionState.initialized;
231
241
  const attrs = {
@@ -246,7 +256,7 @@ class WaAppStateSyncClient {
246
256
  });
247
257
  }
248
258
  else {
249
- const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations);
259
+ const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations, activeSyncKey);
250
260
  outgoingContext = outgoing.context;
251
261
  children.push({
252
262
  tag: constants_2.WA_NODE_TAGS.PATCH,
@@ -332,14 +342,14 @@ class WaAppStateSyncClient {
332
342
  const snapshotBytes = await downloader(payload.collection, 'snapshot', payload.snapshotReference);
333
343
  const snapshot = this.validateSnapshot(payload.collection, _proto_1.proto.SyncdSnapshot.decode(snapshotBytes));
334
344
  const snapshotMutations = await this.applySnapshot(payload.collection, snapshot);
335
- appliedMutations = appliedMutations.concat(snapshotMutations);
345
+ appliedMutations.push(...snapshotMutations);
336
346
  collectionStateChanged = true;
337
347
  }
338
348
  if (payload.patches.length > 0) {
339
349
  const readyPatches = await this.resolveReadyPatches(payload, options);
340
350
  for (const readyPatch of readyPatches) {
341
351
  const patchMutations = await this.applyPatch(payload.collection, readyPatch);
342
- appliedMutations = appliedMutations.concat(patchMutations);
352
+ appliedMutations.push(...patchMutations);
343
353
  collectionStateChanged = true;
344
354
  }
345
355
  }
@@ -428,13 +438,12 @@ class WaAppStateSyncClient {
428
438
  }
429
439
  }
430
440
  async resolveReadyPatches(payload, options) {
431
- const sortedPatches = payload.patches
432
- .map((patch) => ({
433
- patch,
434
- sortVersion: this.parseCollectionPatchVersion(payload.collection, patch)
435
- }))
436
- .sort((left, right) => left.sortVersion - right.sortVersion)
437
- .map((entry) => entry.patch);
441
+ const sortedPatches = payload.patches.slice();
442
+ const sortVersions = new Map();
443
+ for (const patch of sortedPatches) {
444
+ sortVersions.set(patch, this.parseCollectionPatchVersion(payload.collection, patch));
445
+ }
446
+ sortedPatches.sort((left, right) => sortVersions.get(left) - sortVersions.get(right));
438
447
  return Promise.all(sortedPatches.map(async (patch) => {
439
448
  let readyPatch = patch;
440
449
  if ((!readyPatch.mutations || readyPatch.mutations.length === 0) &&
@@ -521,7 +530,13 @@ class WaAppStateSyncClient {
521
530
  timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `snapshot.record.value.timestamp (${collection})`)
522
531
  });
523
532
  }
524
- const ltHash = await this.crypto.ltHashAdd(constants_1.APP_STATE_EMPTY_LT_HASH, Array.from(indexValueMap.values()));
533
+ const ltHashInput = new Array(indexValueMap.size);
534
+ let ltHashInputIndex = 0;
535
+ for (const valueMac of indexValueMap.values()) {
536
+ ltHashInput[ltHashInputIndex] = valueMac;
537
+ ltHashInputIndex += 1;
538
+ }
539
+ const ltHash = await this.crypto.ltHashAdd(constants_1.APP_STATE_EMPTY_LT_HASH, ltHashInput);
525
540
  const expectedSnapshotMac = await this.crypto.generateSnapshotMac(keyData, ltHash, version, collection);
526
541
  if (!(0, bytes_2.uint8Equal)(expectedSnapshotMac, snapshot.mac)) {
527
542
  throw new Error(`snapshot MAC mismatch for ${collection}`);
@@ -555,35 +570,52 @@ class WaAppStateSyncClient {
555
570
  const nextState = await this.computeNextCollectionState(current.hash, current.indexValueMap, macMutations, collection);
556
571
  await this.assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextState.hash, valueMacs);
557
572
  this.setCollectionState(collection, patchVersion, nextState.hash, nextState.indexValueMap);
558
- return decryptedMutations.slice();
573
+ return decryptedMutations;
559
574
  }
560
575
  async decryptSnapshotRecords(collection, snapshot) {
561
- const records = (snapshot.records ?? []).map((record) => ({
562
- indexMac: (0, bytes_1.decodeProtoBytes)(record.index?.blob, `snapshot.record.index.blob (${collection})`),
563
- valueBlob: (0, bytes_1.decodeProtoBytes)(record.value?.blob, `snapshot.record.value.blob (${collection})`),
564
- recordKeyId: (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `snapshot.record.keyId.id (${collection})`)
565
- }));
566
- await this.preloadKeyData(records.map((record) => record.recordKeyId));
567
- return Promise.all(records.map(async ({ indexMac, valueBlob, recordKeyId }) => {
568
- const recordKeyData = await this.getKeyData(recordKeyId);
569
- if (!recordKeyData) {
570
- throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
571
- }
572
- const decrypted = await this.crypto.decryptMutation({
573
- operation: _proto_1.proto.SyncdMutation.SyncdOperation.SET,
574
- keyId: recordKeyId,
575
- keyData: recordKeyData,
576
- indexMac,
577
- valueBlob
578
- });
579
- return {
580
- decrypted,
576
+ const rawRecords = snapshot.records ?? [];
577
+ const records = new Array(rawRecords.length);
578
+ const recordKeyIds = new Array(rawRecords.length);
579
+ for (let i = 0; i < rawRecords.length; i += 1) {
580
+ const record = rawRecords[i];
581
+ const recordKeyId = (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `snapshot.record.keyId.id (${collection})`);
582
+ records[i] = {
583
+ indexMac: (0, bytes_1.decodeProtoBytes)(record.index?.blob, `snapshot.record.index.blob (${collection})`),
584
+ valueBlob: (0, bytes_1.decodeProtoBytes)(record.value?.blob, `snapshot.record.value.blob (${collection})`),
581
585
  recordKeyId
582
586
  };
583
- }));
587
+ recordKeyIds[i] = recordKeyId;
588
+ }
589
+ await this.preloadKeyData(recordKeyIds);
590
+ const decryptTasks = new Array(records.length);
591
+ for (let i = 0; i < records.length; i += 1) {
592
+ const { indexMac, valueBlob, recordKeyId } = records[i];
593
+ decryptTasks[i] = (async () => {
594
+ const recordKeyData = await this.getKeyData(recordKeyId);
595
+ if (!recordKeyData) {
596
+ throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
597
+ }
598
+ const decrypted = await this.crypto.decryptMutation({
599
+ operation: _proto_1.proto.SyncdMutation.SyncdOperation.SET,
600
+ keyId: recordKeyId,
601
+ keyData: recordKeyData,
602
+ indexMac,
603
+ valueBlob
604
+ });
605
+ return {
606
+ decrypted,
607
+ recordKeyId
608
+ };
609
+ })();
610
+ }
611
+ return Promise.all(decryptTasks);
584
612
  }
585
613
  async decryptPatchMutations(collection, patch) {
586
- const parsedMutations = (patch.mutations ?? []).map((mutation) => {
614
+ const rawMutations = patch.mutations ?? [];
615
+ const parsedMutations = new Array(rawMutations.length);
616
+ const mutationKeyIds = new Array(rawMutations.length);
617
+ for (let i = 0; i < rawMutations.length; i += 1) {
618
+ const mutation = rawMutations[i];
587
619
  const operationCode = mutation.operation;
588
620
  if (operationCode === null || operationCode === undefined) {
589
621
  throw new Error(`patch mutation is missing operation (${collection})`);
@@ -592,42 +624,49 @@ class WaAppStateSyncClient {
592
624
  if (!record) {
593
625
  throw new Error(`patch mutation is missing record (${collection})`);
594
626
  }
595
- return {
627
+ const recordKeyId = (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `patch.record.keyId.id (${collection})`);
628
+ parsedMutations[i] = {
596
629
  operationCode,
597
630
  indexMac: (0, bytes_1.decodeProtoBytes)(record.index?.blob, `patch.record.index.blob (${collection})`),
598
631
  valueBlob: (0, bytes_1.decodeProtoBytes)(record.value?.blob, `patch.record.value.blob (${collection})`),
599
- recordKeyId: (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `patch.record.keyId.id (${collection})`)
600
- };
601
- });
602
- await this.preloadKeyData(parsedMutations.map((mutation) => mutation.recordKeyId));
603
- return Promise.all(parsedMutations.map(async ({ operationCode, indexMac, valueBlob, recordKeyId }) => {
604
- const recordKeyData = await this.getKeyData(recordKeyId);
605
- if (!recordKeyData) {
606
- throw new WaAppStateMissingKeyError(`missing mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
607
- }
608
- const decrypted = await this.crypto.decryptMutation({
609
- operation: operationCode,
610
- keyId: recordKeyId,
611
- keyData: recordKeyData,
612
- indexMac,
613
- valueBlob
614
- });
615
- return {
616
- collection,
617
- operation: operationCode === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE
618
- ? 'remove'
619
- : 'set',
620
- source: 'patch',
621
- operationCode,
622
- index: decrypted.index,
623
- value: decrypted.value,
624
- version: decrypted.version,
625
- indexMac: decrypted.indexMac,
626
- valueMac: decrypted.valueMac,
627
- keyId: recordKeyId,
628
- timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
632
+ recordKeyId
629
633
  };
630
- }));
634
+ mutationKeyIds[i] = recordKeyId;
635
+ }
636
+ await this.preloadKeyData(mutationKeyIds);
637
+ const decryptTasks = new Array(parsedMutations.length);
638
+ for (let i = 0; i < parsedMutations.length; i += 1) {
639
+ const { operationCode, indexMac, valueBlob, recordKeyId } = parsedMutations[i];
640
+ decryptTasks[i] = (async () => {
641
+ const recordKeyData = await this.getKeyData(recordKeyId);
642
+ if (!recordKeyData) {
643
+ throw new WaAppStateMissingKeyError(`missing mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
644
+ }
645
+ const decrypted = await this.crypto.decryptMutation({
646
+ operation: operationCode,
647
+ keyId: recordKeyId,
648
+ keyData: recordKeyData,
649
+ indexMac,
650
+ valueBlob
651
+ });
652
+ return {
653
+ collection,
654
+ operation: operationCode === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE
655
+ ? 'remove'
656
+ : 'set',
657
+ source: 'patch',
658
+ operationCode,
659
+ index: decrypted.index,
660
+ value: decrypted.value,
661
+ version: decrypted.version,
662
+ indexMac: decrypted.indexMac,
663
+ valueMac: decrypted.valueMac,
664
+ keyId: recordKeyId,
665
+ timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
666
+ };
667
+ })();
668
+ }
669
+ return Promise.all(decryptTasks);
631
670
  }
632
671
  async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash, valueMacs) {
633
672
  const snapshotMac = (0, bytes_1.decodeProtoBytes)(patch.snapshotMac, `patch.snapshotMac (${collection})`);
@@ -641,8 +680,7 @@ class WaAppStateSyncClient {
641
680
  throw new Error(`patch MAC mismatch for ${collection}`);
642
681
  }
643
682
  }
644
- async buildOutgoingPatch(collection, snapshot, pendingMutations) {
645
- const activeKey = await this.store.getActiveSyncKey();
683
+ async buildOutgoingPatch(collection, snapshot, pendingMutations, activeKey) {
646
684
  if (!activeKey) {
647
685
  throw new WaAppStateMissingKeyError(`no sync key available to upload ${collection}`, null, collection);
648
686
  }
@@ -661,23 +699,30 @@ class WaAppStateSyncClient {
661
699
  });
662
700
  return { operationCode, encrypted };
663
701
  }));
664
- const encryptedMutations = encryptedResults.map(({ operationCode, encrypted }) => ({
665
- operation: operationCode,
666
- record: {
667
- keyId: { id: activeKey.keyId },
668
- index: { blob: encrypted.indexMac },
669
- value: { blob: encrypted.valueBlob }
670
- }
671
- }));
672
- const macMutations = encryptedResults.map(({ operationCode, encrypted }) => ({
673
- operation: operationCode,
674
- indexMac: encrypted.indexMac,
675
- valueMac: encrypted.valueMac
676
- }));
702
+ const encryptedMutations = new Array(encryptedResults.length);
703
+ const macMutations = new Array(encryptedResults.length);
704
+ const valueMacs = new Array(encryptedResults.length);
705
+ for (let i = 0; i < encryptedResults.length; i += 1) {
706
+ const { operationCode, encrypted } = encryptedResults[i];
707
+ encryptedMutations[i] = {
708
+ operation: operationCode,
709
+ record: {
710
+ keyId: { id: activeKey.keyId },
711
+ index: { blob: encrypted.indexMac },
712
+ value: { blob: encrypted.valueBlob }
713
+ }
714
+ };
715
+ macMutations[i] = {
716
+ operation: operationCode,
717
+ indexMac: encrypted.indexMac,
718
+ valueMac: encrypted.valueMac
719
+ };
720
+ valueMacs[i] = encrypted.valueMac;
721
+ }
677
722
  const nextState = await this.computeNextCollectionState(snapshot.hash, snapshot.indexValueMap, macMutations, collection);
678
723
  const patchVersion = snapshot.version + 1;
679
724
  const snapshotMac = await this.crypto.generateSnapshotMac(activeKey.keyData, nextState.hash, patchVersion, collection);
680
- const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, macMutations.map((item) => item.valueMac), patchVersion, collection);
725
+ const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, valueMacs, patchVersion, collection);
681
726
  const deviceIndex = this.resolveDeviceIndex();
682
727
  const clientDebugData = this.buildPatchClientDebugData();
683
728
  const encodedPatch = _proto_1.proto.SyncdPatch.encode({
@@ -4,8 +4,8 @@ exports.encodeAppStateFingerprint = encodeAppStateFingerprint;
4
4
  exports.decodeAppStateFingerprint = decodeAppStateFingerprint;
5
5
  exports.decodeAppStateSyncKeys = decodeAppStateSyncKeys;
6
6
  exports.decodeAppStateCollections = decodeAppStateCollections;
7
- const _proto_1 = require("../../proto.js");
8
- const coercion_1 = require("../../util/coercion");
7
+ const _proto_1 = require("../proto.js");
8
+ const coercion_1 = require("../util/coercion");
9
9
  function encodeAppStateFingerprint(fingerprint) {
10
10
  if (!fingerprint) {
11
11
  return null;
@@ -26,12 +26,17 @@ function decodeAppStateFingerprint(raw) {
26
26
  }
27
27
  }
28
28
  function decodeAppStateSyncKeys(rows) {
29
- return rows.map((row) => ({
30
- keyId: (0, coercion_1.asBytes)(row.key_id, 'appstate_sync_keys.key_id'),
31
- keyData: (0, coercion_1.asBytes)(row.key_data, 'appstate_sync_keys.key_data'),
32
- timestamp: (0, coercion_1.asNumber)(row.timestamp, 'appstate_sync_keys.timestamp'),
33
- fingerprint: decodeAppStateFingerprint(row.fingerprint)
34
- }));
29
+ const decoded = new Array(rows.length);
30
+ for (let i = 0; i < rows.length; i += 1) {
31
+ const row = rows[i];
32
+ decoded[i] = {
33
+ keyId: (0, coercion_1.asBytes)(row.key_id, 'appstate_sync_keys.key_id'),
34
+ keyData: (0, coercion_1.asBytes)(row.key_data, 'appstate_sync_keys.key_data'),
35
+ timestamp: (0, coercion_1.asNumber)(row.timestamp, 'appstate_sync_keys.timestamp'),
36
+ fingerprint: decodeAppStateFingerprint(row.fingerprint)
37
+ };
38
+ }
39
+ return decoded;
35
40
  }
36
41
  function decodeAppStateCollections(versionRows, valueRows) {
37
42
  const valueMapByCollection = new Map();
@@ -14,15 +14,17 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.WaAppStateSyncClient = exports.parseSyncResponse = exports.parseCollectionState = exports.WaAppStateMissingKeyError = exports.WaAppStateCrypto = void 0;
17
+ exports.WaAppStateSyncClient = exports.parseSyncResponse = exports.WaAppStateCrypto = exports.decodeAppStateSyncKeys = exports.decodeAppStateCollections = exports.decodeAppStateFingerprint = exports.encodeAppStateFingerprint = void 0;
18
18
  __exportStar(require("./constants"), exports);
19
+ var encoding_1 = require("./encoding");
20
+ Object.defineProperty(exports, "encodeAppStateFingerprint", { enumerable: true, get: function () { return encoding_1.encodeAppStateFingerprint; } });
21
+ Object.defineProperty(exports, "decodeAppStateFingerprint", { enumerable: true, get: function () { return encoding_1.decodeAppStateFingerprint; } });
22
+ Object.defineProperty(exports, "decodeAppStateCollections", { enumerable: true, get: function () { return encoding_1.decodeAppStateCollections; } });
23
+ Object.defineProperty(exports, "decodeAppStateSyncKeys", { enumerable: true, get: function () { return encoding_1.decodeAppStateSyncKeys; } });
19
24
  __exportStar(require("./utils"), exports);
20
25
  var WaAppStateCrypto_1 = require("./WaAppStateCrypto");
21
26
  Object.defineProperty(exports, "WaAppStateCrypto", { enumerable: true, get: function () { return WaAppStateCrypto_1.WaAppStateCrypto; } });
22
- var WaAppStateSyncClient_1 = require("./WaAppStateSyncClient");
23
- Object.defineProperty(exports, "WaAppStateMissingKeyError", { enumerable: true, get: function () { return WaAppStateSyncClient_1.WaAppStateMissingKeyError; } });
24
27
  var WaAppStateSyncResponseParser_1 = require("./WaAppStateSyncResponseParser");
25
- Object.defineProperty(exports, "parseCollectionState", { enumerable: true, get: function () { return WaAppStateSyncResponseParser_1.parseCollectionState; } });
26
28
  Object.defineProperty(exports, "parseSyncResponse", { enumerable: true, get: function () { return WaAppStateSyncResponseParser_1.parseSyncResponse; } });
27
- var WaAppStateSyncClient_2 = require("./WaAppStateSyncClient");
28
- Object.defineProperty(exports, "WaAppStateSyncClient", { enumerable: true, get: function () { return WaAppStateSyncClient_2.WaAppStateSyncClient; } });
29
+ var WaAppStateSyncClient_1 = require("./WaAppStateSyncClient");
30
+ Object.defineProperty(exports, "WaAppStateSyncClient", { enumerable: true, get: function () { return WaAppStateSyncClient_1.WaAppStateSyncClient; } });
@@ -1,10 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseCollectionName = parseCollectionName;
4
- exports.keyDeviceId = keyDeviceId;
5
4
  exports.keyEpoch = keyEpoch;
6
5
  exports.pickActiveSyncKey = pickActiveSyncKey;
7
- exports.toNetworkOrder64 = toNetworkOrder64;
8
6
  exports.downloadExternalBlobReference = downloadExternalBlobReference;
9
7
  const constants_1 = require("../protocol/constants");
10
8
  const bytes_1 = require("../util/bytes");
@@ -44,9 +42,6 @@ function pickActiveSyncKey(keys) {
44
42
  }
45
43
  return active;
46
44
  }
47
- function toNetworkOrder64(value) {
48
- return (0, bytes_1.intToBytes)(8, value);
49
- }
50
45
  async function downloadExternalBlobReference(mediaTransfer, reference) {
51
46
  if (!reference.directPath) {
52
47
  throw new Error('external blob reference is missing directPath');
@@ -53,7 +53,7 @@ class WaAuthClient {
53
53
  getState(connected = false) {
54
54
  return {
55
55
  connected,
56
- registered: hasMeJid(this.credentials),
56
+ registered: this.credentials?.meJid !== null && this.credentials?.meJid !== undefined,
57
57
  hasQr: this.qrFlow.hasQr(),
58
58
  hasPairingCode: this.pairingFlow.hasPairingSession()
59
59
  };
@@ -70,7 +70,7 @@ class WaAuthClient {
70
70
  signalStore: this.signalStore
71
71
  });
72
72
  this.logger.info('auth client credentials ready', {
73
- registered: hasMeJid(this.credentials)
73
+ registered: this.credentials?.meJid !== null && this.credentials?.meJid !== undefined
74
74
  });
75
75
  return this.credentials;
76
76
  });
@@ -80,7 +80,8 @@ class WaAuthClient {
80
80
  return (0, WaAuthCredentialsFlow_1.buildCommsConfig)(this.logger, this.requireCredentials(), socketOptions, {
81
81
  deviceBrowser: this.options.deviceBrowser,
82
82
  deviceOsDisplayName: this.options.deviceOsDisplayName,
83
- requireFullSync: this.options.requireFullSync
83
+ requireFullSync: this.options.requireFullSync,
84
+ version: this.options.version
84
85
  });
85
86
  }
86
87
  async clearTransientState() {
@@ -90,9 +91,8 @@ class WaAuthClient {
90
91
  }
91
92
  async clearStoredCredentials() {
92
93
  this.logger.warn('auth client clearing stored credentials');
93
- await this.authStore.clear();
94
94
  this.credentials = null;
95
- await this.clearTransientState();
95
+ await Promise.all([this.authStore.clear(), this.clearTransientState()]);
96
96
  }
97
97
  async persistServerStaticKey(serverStaticKey) {
98
98
  this.logger.debug('persisting server static key', {
@@ -145,46 +145,38 @@ class WaAuthClient {
145
145
  });
146
146
  }
147
147
  async persistSuccessAttributes(attributes) {
148
- await this.patchCredentials((credentials) => {
149
- return {
150
- ...credentials,
151
- meLid: attributes.meLid ?? credentials.meLid,
152
- meDisplayName: attributes.meDisplayName ?? credentials.meDisplayName,
153
- companionEncStatic: attributes.companionEncStatic ?? credentials.companionEncStatic,
154
- lastSuccessTs: attributes.lastSuccessTs ?? credentials.lastSuccessTs,
155
- propsVersion: attributes.propsVersion ?? credentials.propsVersion,
156
- abPropsVersion: attributes.abPropsVersion ?? credentials.abPropsVersion,
157
- connectionLocation: attributes.connectionLocation ?? credentials.connectionLocation,
158
- accountCreationTs: attributes.accountCreationTs ?? credentials.accountCreationTs
159
- };
160
- }, {
161
- shouldPersist: (current, next) => next.meLid !== current.meLid ||
162
- next.meDisplayName !== current.meDisplayName ||
163
- (current.companionEncStatic === undefined) !==
164
- (next.companionEncStatic === undefined) ||
148
+ let persistDiff;
149
+ const computeDiff = (current, next) => ({
150
+ lidChanged: next.meLid !== current.meLid,
151
+ displayNameChanged: next.meDisplayName !== current.meDisplayName,
152
+ companionChanged: (current.companionEncStatic === undefined) !==
153
+ (next.companionEncStatic === undefined) ||
165
154
  (current.companionEncStatic !== undefined &&
166
155
  next.companionEncStatic !== undefined &&
167
- !(0, bytes_1.uint8Equal)(current.companionEncStatic, next.companionEncStatic)) ||
168
- next.lastSuccessTs !== current.lastSuccessTs ||
169
- next.propsVersion !== current.propsVersion ||
170
- next.abPropsVersion !== current.abPropsVersion ||
171
- next.connectionLocation !== current.connectionLocation ||
172
- next.accountCreationTs !== current.accountCreationTs,
173
- onPersist: (current, next) => {
174
- this.logger.debug('persisting success attributes', {
175
- lidChanged: next.meLid !== current.meLid,
176
- displayNameChanged: next.meDisplayName !== current.meDisplayName,
177
- companionChanged: (current.companionEncStatic === undefined) !==
178
- (next.companionEncStatic === undefined) ||
179
- (current.companionEncStatic !== undefined &&
180
- next.companionEncStatic !== undefined &&
181
- !(0, bytes_1.uint8Equal)(current.companionEncStatic, next.companionEncStatic)),
182
- lastSuccessTsChanged: next.lastSuccessTs !== current.lastSuccessTs,
183
- propsVersionChanged: next.propsVersion !== current.propsVersion,
184
- abPropsVersionChanged: next.abPropsVersion !== current.abPropsVersion,
185
- connectionLocationChanged: next.connectionLocation !== current.connectionLocation,
186
- accountCreationTsChanged: next.accountCreationTs !== current.accountCreationTs
187
- });
156
+ !(0, bytes_1.uint8Equal)(current.companionEncStatic, next.companionEncStatic)),
157
+ lastSuccessTsChanged: next.lastSuccessTs !== current.lastSuccessTs,
158
+ propsVersionChanged: next.propsVersion !== current.propsVersion,
159
+ abPropsVersionChanged: next.abPropsVersion !== current.abPropsVersion,
160
+ connectionLocationChanged: next.connectionLocation !== current.connectionLocation,
161
+ accountCreationTsChanged: next.accountCreationTs !== current.accountCreationTs
162
+ });
163
+ await this.patchCredentials((credentials) => ({
164
+ ...credentials,
165
+ meLid: attributes.meLid ?? credentials.meLid,
166
+ meDisplayName: attributes.meDisplayName ?? credentials.meDisplayName,
167
+ companionEncStatic: attributes.companionEncStatic ?? credentials.companionEncStatic,
168
+ lastSuccessTs: attributes.lastSuccessTs ?? credentials.lastSuccessTs,
169
+ propsVersion: attributes.propsVersion ?? credentials.propsVersion,
170
+ abPropsVersion: attributes.abPropsVersion ?? credentials.abPropsVersion,
171
+ connectionLocation: attributes.connectionLocation ?? credentials.connectionLocation,
172
+ accountCreationTs: attributes.accountCreationTs ?? credentials.accountCreationTs
173
+ }), {
174
+ shouldPersist: (current, next) => {
175
+ persistDiff = computeDiff(current, next);
176
+ return Object.values(persistDiff).some(Boolean);
177
+ },
178
+ onPersist: () => {
179
+ this.logger.debug('persisting success attributes', persistDiff);
188
180
  }
189
181
  });
190
182
  }
@@ -233,7 +225,7 @@ class WaAuthClient {
233
225
  }
234
226
  async updateCredentials(credentials) {
235
227
  this.logger.trace('auth client update credentials', {
236
- registered: hasMeJid(credentials)
228
+ registered: credentials?.meJid !== null && credentials?.meJid !== undefined
237
229
  });
238
230
  this.credentials = credentials;
239
231
  await (0, WaAuthCredentialsFlow_1.persistCredentials)({
@@ -254,6 +246,3 @@ class WaAuthClient {
254
246
  }
255
247
  }
256
248
  exports.WaAuthClient = WaAuthClient;
257
- function hasMeJid(credentials) {
258
- return credentials?.meJid !== null && credentials?.meJid !== undefined;
259
- }
@@ -20,7 +20,7 @@ async function loadOrCreateCredentials(args) {
20
20
  return credentials;
21
21
  }
22
22
  args.logger.debug('auth credentials loaded from store', {
23
- registered: isRegistered(existing),
23
+ registered: existing.meJid !== null && existing.meJid !== undefined,
24
24
  hasServerStaticKey: existing.serverStaticKey !== null && existing.serverStaticKey !== undefined
25
25
  });
26
26
  if (!existing.meJid && !(await hasValidSignedPreKey(args.logger, existing))) {
@@ -35,7 +35,7 @@ async function loadOrCreateCredentials(args) {
35
35
  }
36
36
  async function persistCredentials(args, credentials) {
37
37
  args.logger.trace('persisting auth credentials', {
38
- registered: isRegistered(credentials)
38
+ registered: credentials.meJid !== null && credentials.meJid !== undefined
39
39
  });
40
40
  await args.authStore.save(credentials);
41
41
  }
@@ -68,7 +68,8 @@ function buildCommsConfig(logger, credentials, socketOptions, clientOptions) {
68
68
  username: loginIdentity.username,
69
69
  device: loginIdentity.device,
70
70
  deviceBrowser: clientOptions.deviceBrowser,
71
- deviceOsDisplayName: clientOptions.deviceOsDisplayName
71
+ deviceOsDisplayName: clientOptions.deviceOsDisplayName,
72
+ versionBase: clientOptions.version
72
73
  }
73
74
  : undefined,
74
75
  registrationPayloadConfig: !loginIdentity
@@ -77,7 +78,8 @@ function buildCommsConfig(logger, credentials, socketOptions, clientOptions) {
77
78
  signedPreKey: credentials.signedPreKey,
78
79
  deviceBrowser: clientOptions.deviceBrowser,
79
80
  deviceOsDisplayName: clientOptions.deviceOsDisplayName,
80
- requireFullSync: clientOptions.requireFullSync
81
+ requireFullSync: clientOptions.requireFullSync,
82
+ versionBase: clientOptions.version
81
83
  }
82
84
  : undefined
83
85
  }
@@ -100,6 +102,7 @@ async function createFreshCredentials(signalStore, logger) {
100
102
  }
101
103
  async function createFreshAndPersistCredentials(args) {
102
104
  const credentials = await createFreshCredentials(args.signalStore, args.logger);
105
+ // Persist credentials first so signal restore never commits state for credentials that failed to save.
103
106
  await args.authStore.save(credentials);
104
107
  await restoreSignalStore(args.signalStore, credentials);
105
108
  return credentials;
@@ -125,6 +128,3 @@ async function restoreSignalStore(signalStore, credentials) {
125
128
  signalStore.setServerHasPreKeys(credentials.serverHasPreKeys === true)
126
129
  ]);
127
130
  }
128
- function isRegistered(credentials) {
129
- return credentials.meJid !== null && credentials.meJid !== undefined;
130
- }