zapo-js 0.3.0 → 1.0.1
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.
- package/LICENSE +21 -0
- package/README.md +98 -178
- package/dist/appstate/{WaAppStateCrypto.js → crypto/WaAppStateCrypto.js} +58 -49
- package/dist/appstate/index.js +7 -6
- package/dist/appstate/{encoding.js → parsers/encoding.js} +11 -4
- package/dist/appstate/{response-parser.js → parsers/response-parser.js} +20 -8
- package/dist/appstate/{WaAppStateSyncClient.js → sync/WaAppStateSyncClient.js} +174 -53
- package/dist/appstate/utils.js +16 -0
- package/dist/appstate-spec.js +89 -0
- package/dist/auth/WaAuthClient.js +100 -5
- package/dist/auth/credentials-flow.js +20 -8
- package/dist/auth/pairing/WaPairingFlow.js +35 -26
- package/dist/auth/pairing/pairing-code-crypto.js +17 -19
- package/dist/client/WaClient.js +343 -474
- package/dist/client/WaClientFactory.js +281 -78
- package/dist/client/connection/WaConnectionManager.js +28 -11
- package/dist/client/coordinators/WaAbPropsCoordinator.js +1 -2
- package/dist/client/coordinators/WaAppStateMutationCoordinator.js +663 -143
- package/dist/client/coordinators/WaBotCoordinator.js +345 -0
- package/dist/client/coordinators/WaBroadcastListCoordinator.js +20 -0
- package/dist/client/coordinators/WaBusinessCoordinator.js +81 -171
- package/dist/client/coordinators/WaEmailCoordinator.js +1 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +529 -52
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +97 -12
- package/dist/client/coordinators/WaLowLevelCoordinator.js +41 -0
- package/dist/client/coordinators/WaMessageCoordinator.js +365 -0
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +685 -207
- package/dist/client/coordinators/WaNewsletterCoordinator.js +18 -0
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +17 -4
- package/dist/client/coordinators/WaPresenceCoordinator.js +21 -0
- package/dist/client/coordinators/WaPrivacyCoordinator.js +7 -5
- package/dist/client/coordinators/WaProfileCoordinator.js +220 -49
- package/dist/client/coordinators/WaRetryCoordinator.js +257 -126
- package/dist/client/coordinators/WaStatusCoordinator.js +49 -0
- package/dist/client/coordinators/WaStreamControlCoordinator.js +8 -9
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +7 -6
- package/dist/client/events/appstate-mutation.js +133 -0
- package/dist/client/events/business.js +375 -0
- package/dist/client/events/call.js +58 -0
- package/dist/client/events/chatstate.js +23 -0
- package/dist/client/events/devices.js +15 -16
- package/dist/client/{dirty.js → events/dirty.js} +33 -19
- package/dist/client/events/group.js +13 -24
- package/dist/client/events/identity.js +2 -1
- package/dist/client/events/incoming.js +502 -0
- package/dist/client/events/mex-notification.js +181 -0
- package/dist/client/events/picture.js +33 -0
- package/dist/client/events/presence.js +44 -0
- package/dist/client/events/receipt.js +26 -0
- package/dist/client/media.js +163 -6
- package/dist/client/messaging/fanout.js +9 -10
- package/dist/client/messaging/{participants.js → group-metadata.js} +93 -44
- package/dist/client/messaging/ignore-key.js +132 -0
- package/dist/client/messaging/key-protocol.js +4 -18
- package/dist/client/messaging/link-preview.js +159 -0
- package/dist/client/messaging/messages.js +671 -0
- package/dist/client/newsletter/admin.js +165 -0
- package/dist/client/newsletter/content.js +253 -0
- package/dist/client/newsletter/discovery.js +115 -0
- package/dist/client/newsletter/messaging.js +197 -0
- package/dist/client/newsletter/mex.js +41 -0
- package/dist/client/newsletter/parse.js +217 -0
- package/dist/client/persistence/WriteBehindPersistence.js +31 -4
- package/dist/client/{history-sync.js → persistence/history-sync.js} +125 -18
- package/dist/client/persistence/mailbox.js +104 -0
- package/dist/client/tokens/cs-token.js +11 -17
- package/dist/crypto/core/hkdf.js +12 -12
- package/dist/crypto/core/index.js +6 -8
- package/dist/crypto/core/keys.js +1 -8
- package/dist/crypto/core/nonce.js +12 -12
- package/dist/crypto/core/primitives.js +123 -93
- package/dist/crypto/core/random.js +6 -0
- package/dist/crypto/core/xeddsa.js +11 -9
- package/dist/crypto/curves/Ed25519.js +32 -21
- package/dist/crypto/curves/X25519.js +70 -34
- package/dist/crypto/curves/constants.js +2 -1
- package/dist/crypto/math/constants.js +1 -2
- package/dist/crypto/math/mod.js +0 -33
- package/dist/esm/appstate/{WaAppStateCrypto.js → crypto/WaAppStateCrypto.js} +58 -49
- package/dist/esm/appstate/index.js +5 -5
- package/dist/esm/appstate/{encoding.js → parsers/encoding.js} +11 -4
- package/dist/esm/appstate/{response-parser.js → parsers/response-parser.js} +20 -8
- package/dist/esm/appstate/{WaAppStateSyncClient.js → sync/WaAppStateSyncClient.js} +174 -52
- package/dist/esm/appstate/utils.js +16 -0
- package/dist/esm/appstate-spec.js +79 -0
- package/dist/esm/auth/WaAuthClient.js +100 -5
- package/dist/esm/auth/credentials-flow.js +18 -6
- package/dist/esm/auth/pairing/WaPairingFlow.js +34 -25
- package/dist/esm/auth/pairing/pairing-code-crypto.js +12 -14
- package/dist/esm/client/WaClient.js +345 -476
- package/dist/esm/client/WaClientFactory.js +282 -79
- package/dist/esm/client/connection/WaConnectionManager.js +28 -11
- package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +2 -3
- package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +665 -145
- package/dist/esm/client/coordinators/WaBotCoordinator.js +342 -0
- package/dist/esm/client/coordinators/WaBroadcastListCoordinator.js +17 -0
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +79 -169
- package/dist/esm/client/coordinators/WaEmailCoordinator.js +1 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +532 -55
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +98 -13
- package/dist/esm/client/coordinators/WaLowLevelCoordinator.js +38 -0
- package/dist/esm/client/coordinators/WaMessageCoordinator.js +361 -0
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +686 -208
- package/dist/esm/client/coordinators/WaNewsletterCoordinator.js +13 -0
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +18 -5
- package/dist/esm/client/coordinators/WaPresenceCoordinator.js +18 -0
- package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +7 -5
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +223 -52
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +258 -127
- package/dist/esm/client/coordinators/WaStatusCoordinator.js +46 -0
- package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +8 -9
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +7 -6
- package/dist/esm/client/events/appstate-mutation.js +130 -0
- package/dist/esm/client/events/business.js +370 -0
- package/dist/esm/client/events/call.js +55 -0
- package/dist/esm/client/events/chatstate.js +20 -0
- package/dist/esm/client/events/devices.js +15 -16
- package/dist/esm/client/{dirty.js → events/dirty.js} +33 -19
- package/dist/esm/client/events/group.js +14 -25
- package/dist/esm/client/events/identity.js +2 -1
- package/dist/esm/client/events/incoming.js +487 -0
- package/dist/esm/client/events/mex-notification.js +178 -0
- package/dist/esm/client/events/picture.js +30 -0
- package/dist/esm/client/events/presence.js +41 -0
- package/dist/esm/client/events/receipt.js +23 -0
- package/dist/esm/client/media.js +158 -8
- package/dist/esm/client/messaging/fanout.js +10 -11
- package/dist/esm/client/messaging/{participants.js → group-metadata.js} +92 -43
- package/dist/esm/client/messaging/ignore-key.js +126 -0
- package/dist/esm/client/messaging/key-protocol.js +3 -17
- package/dist/esm/client/messaging/link-preview.js +156 -0
- package/dist/esm/client/messaging/messages.js +667 -0
- package/dist/esm/client/newsletter/admin.js +162 -0
- package/dist/esm/client/newsletter/content.js +249 -0
- package/dist/esm/client/newsletter/discovery.js +112 -0
- package/dist/esm/client/newsletter/messaging.js +194 -0
- package/dist/esm/client/newsletter/mex.js +37 -0
- package/dist/esm/client/newsletter/parse.js +200 -0
- package/dist/esm/client/persistence/WriteBehindPersistence.js +31 -4
- package/dist/esm/client/{history-sync.js → persistence/history-sync.js} +124 -18
- package/dist/esm/client/persistence/mailbox.js +101 -0
- package/dist/esm/client/tokens/cs-token.js +12 -18
- package/dist/esm/crypto/core/hkdf.js +14 -14
- package/dist/esm/crypto/core/index.js +2 -2
- package/dist/esm/crypto/core/keys.js +1 -7
- package/dist/esm/crypto/core/nonce.js +11 -11
- package/dist/esm/crypto/core/primitives.js +121 -88
- package/dist/esm/crypto/core/random.js +6 -0
- package/dist/esm/crypto/core/xeddsa.js +11 -9
- package/dist/esm/crypto/curves/Ed25519.js +35 -24
- package/dist/esm/crypto/curves/X25519.js +72 -36
- package/dist/esm/crypto/curves/constants.js +1 -0
- package/dist/esm/crypto/math/constants.js +1 -2
- package/dist/esm/crypto/math/mod.js +0 -32
- package/dist/esm/index.js +7 -2
- package/dist/esm/infra/log/ConsoleLogger.js +30 -6
- package/dist/esm/infra/log/PinoLogger.js +64 -0
- package/dist/esm/infra/log/types.js +4 -2
- package/dist/esm/infra/perf/BackgroundQueue.js +55 -13
- package/dist/esm/media/constants.js +33 -2
- package/dist/esm/media/crypto/WaMediaCrypto.js +374 -0
- package/dist/esm/media/index.js +4 -3
- package/dist/esm/media/sticker/sticker-pack.js +133 -0
- package/dist/esm/media/{WaMediaTransferClient.js → transfer/WaMediaTransferClient.js} +37 -6
- package/dist/esm/media/{conn.js → transfer/conn.js} +10 -5
- package/dist/esm/message/WaMessageClient.js +46 -15
- package/dist/esm/message/addons/link-preview/builder.js +36 -0
- package/dist/esm/message/addons/link-preview/detect.js +55 -0
- package/dist/esm/message/addons/link-preview/fetcher.js +391 -0
- package/dist/esm/message/addons/link-preview/types.js +1 -0
- package/dist/esm/message/context-info.js +123 -0
- package/dist/esm/message/{addon-crypto.js → crypto/addon-crypto.js} +68 -10
- package/dist/esm/message/{icdc.js → crypto/icdc.js} +5 -7
- package/dist/esm/message/crypto/phash.js +133 -0
- package/dist/esm/message/{reporting-token.js → crypto/reporting-token.js} +6 -6
- package/dist/esm/message/{use-case-secret.js → crypto/use-case-secret.js} +20 -3
- package/dist/esm/message/{content.js → encode/content.js} +176 -7
- package/dist/esm/message/encode/media-payload.js +42 -0
- package/dist/esm/message/{padding.js → encode/padding.js} +9 -3
- package/dist/esm/message/index.js +2 -2
- package/dist/esm/message/kinds/bot.js +111 -0
- package/dist/esm/message/kinds/newsletter.js +244 -0
- package/dist/esm/message/kinds/sticker-pack.js +29 -0
- package/dist/esm/message/{ack.js → primitives/ack.js} +8 -1
- package/dist/esm/message/{incoming.js → primitives/incoming.js} +215 -31
- package/dist/esm/message/primitives/peer-data-operation.js +93 -0
- package/dist/esm/mex.js +1 -0
- package/dist/esm/protocol/abprops.js +10 -0
- package/dist/esm/protocol/appstate.js +6 -30
- package/dist/esm/protocol/auth.js +3 -2
- package/dist/esm/protocol/bot.js +77 -0
- package/dist/esm/protocol/browser.js +8 -0
- package/dist/esm/protocol/business.js +19 -0
- package/dist/esm/protocol/call.js +48 -0
- package/dist/esm/protocol/constants.js +8 -2
- package/dist/esm/protocol/defaults.js +3 -0
- package/dist/esm/protocol/index.js +1 -1
- package/dist/esm/protocol/jid.js +102 -5
- package/dist/esm/protocol/media.js +25 -12
- package/dist/esm/protocol/message.js +4 -1
- package/dist/esm/protocol/newsletter.js +61 -0
- package/dist/esm/protocol/nodes.js +22 -2
- package/dist/esm/protocol/notification.js +18 -2
- package/dist/esm/protocol/presence.js +13 -0
- package/dist/esm/protocol/status.js +6 -0
- package/dist/esm/retry/codec.js +5 -0
- package/dist/esm/retry/parse.js +20 -38
- package/dist/esm/retry/reason.js +5 -0
- package/dist/esm/retry/replay.js +131 -37
- package/dist/esm/retry/tracker.js +4 -8
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +69 -20
- package/dist/esm/signal/api/SignalDigestSyncApi.js +7 -2
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +9 -0
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +24 -63
- package/dist/esm/signal/api/SignalRotateKeyApi.js +10 -0
- package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -51
- package/dist/esm/signal/api/codec.js +52 -1
- package/dist/esm/signal/api/prekeys.js +4 -0
- package/dist/esm/signal/{crypto → attestation}/WaAdvSignature.js +5 -6
- package/dist/esm/signal/constants.js +3 -0
- package/dist/esm/signal/encoding.js +6 -289
- package/dist/esm/signal/group/SenderKeyChain.js +18 -33
- package/dist/esm/signal/group/SenderKeyManager.js +25 -8
- package/dist/esm/signal/group/encoding.js +96 -0
- package/dist/esm/signal/index.js +4 -1
- package/dist/esm/signal/registration/encoding.js +34 -0
- package/dist/esm/signal/registration/keygen.js +10 -0
- package/dist/esm/signal/registration/utils.js +8 -1
- package/dist/esm/signal/session/SignalProtocol.js +113 -11
- package/dist/esm/signal/session/SignalRatchet.js +29 -58
- package/dist/esm/signal/session/SignalSession.js +7 -14
- package/dist/esm/signal/session/encoding.js +173 -0
- package/dist/esm/signal/session/resolver.js +139 -30
- package/dist/esm/store/cache/identity.cache.js +75 -0
- package/dist/esm/store/cache/privacy-token.cache.js +57 -0
- package/dist/esm/store/cache/sender-key.cache.js +101 -0
- package/dist/esm/store/cache/session.cache.js +92 -0
- package/dist/esm/store/contracts/group-metadata.store.js +1 -0
- package/dist/esm/store/createStore.js +91 -37
- package/dist/esm/store/index.js +15 -14
- package/dist/esm/store/locks/contact.lock.js +1 -0
- package/dist/esm/store/locks/device-list.lock.js +1 -0
- package/dist/esm/store/locks/group-metadata.lock.js +20 -0
- package/dist/esm/store/locks/pre-key.lock.js +4 -1
- package/dist/esm/store/{providers/memory → memory}/appstate.store.js +5 -5
- package/dist/esm/store/memory/auth.store.js +24 -0
- package/dist/esm/store/memory/contact.store.js +79 -0
- package/dist/esm/store/memory/device-list.store.js +103 -0
- package/dist/esm/store/{providers/memory/participants.store.js → memory/group-metadata.store.js} +22 -13
- package/dist/esm/store/{providers/memory → memory}/identity.store.js +3 -3
- package/dist/esm/store/{providers/memory → memory}/message-secret.store.js +17 -8
- package/dist/esm/store/{providers/memory → memory}/message.store.js +2 -2
- package/dist/esm/store/{providers/memory → memory}/pre-key.store.js +2 -2
- package/dist/esm/store/{providers/memory → memory}/privacy-token.store.js +1 -1
- package/dist/esm/store/{providers/memory → memory}/retry.store.js +28 -7
- package/dist/esm/store/{providers/memory → memory}/sender-key.store.js +3 -3
- package/dist/esm/store/{providers/memory → memory}/session.store.js +3 -3
- package/dist/esm/store/{providers/memory → memory}/thread.store.js +2 -2
- package/dist/esm/store/noop.store.js +6 -4
- package/dist/esm/transport/WaComms.js +14 -5
- package/dist/esm/transport/WaWebSocket.js +32 -8
- package/dist/esm/transport/binary/constants.js +10 -4
- package/dist/esm/transport/binary/decoder.js +21 -15
- package/dist/esm/transport/binary/encoder.js +96 -21
- package/dist/esm/transport/binary/tokens.js +12 -12
- package/dist/esm/transport/index.js +1 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +18 -4
- package/dist/esm/transport/node/WaMobileTcpSocket.js +6 -0
- package/dist/esm/transport/node/WaNodeOrchestrator.js +9 -5
- package/dist/esm/transport/node/WaNodeTransport.js +13 -0
- package/dist/esm/transport/node/builders/abprops.js +2 -2
- package/dist/esm/transport/node/builders/account-sync.js +7 -15
- package/dist/esm/transport/node/builders/bot.js +38 -0
- package/dist/esm/transport/node/builders/business.js +30 -30
- package/dist/esm/transport/node/builders/chatstate.js +28 -0
- package/dist/esm/transport/node/builders/community.js +53 -0
- package/dist/esm/transport/node/builders/device.js +2 -2
- package/dist/esm/transport/node/builders/email.js +6 -5
- package/dist/esm/transport/node/builders/global.js +1 -1
- package/dist/esm/transport/node/builders/group.js +114 -4
- package/dist/esm/transport/node/builders/media.js +2 -2
- package/dist/esm/transport/node/builders/message.js +83 -49
- package/dist/esm/transport/node/builders/newsletter.js +176 -0
- package/dist/esm/transport/node/builders/passive.js +7 -0
- package/dist/esm/transport/node/builders/prekeys.js +4 -4
- package/dist/esm/transport/node/builders/presence.js +27 -1
- package/dist/esm/transport/node/builders/privacy-token.js +2 -2
- package/dist/esm/transport/node/builders/privacy.js +6 -6
- package/dist/esm/transport/node/builders/profile.js +28 -8
- package/dist/esm/transport/node/builders/tos.js +58 -0
- package/dist/esm/transport/node/builders/usync.js +51 -2
- package/dist/esm/transport/node/helpers.js +3 -1
- package/dist/esm/transport/node/mex/argo-decoder.js +2 -2
- package/dist/esm/transport/node/mex/client.js +22 -0
- package/dist/esm/transport/node/query.js +17 -0
- package/dist/esm/transport/node/usync.js +12 -0
- package/dist/esm/transport/noise/WaClientPayload.js +8 -8
- package/dist/esm/transport/noise/WaMobileClientPayload.js +5 -0
- package/dist/esm/transport/noise/WaNoiseCert.js +5 -0
- package/dist/esm/transport/noise/WaNoiseHandshake.js +27 -25
- package/dist/esm/transport/noise/WaNoiseSession.js +39 -59
- package/dist/esm/transport/noise/WaNoiseSocket.js +19 -13
- package/dist/esm/transport/noise/constants.js +0 -1
- package/dist/esm/transport/proxy.js +5 -0
- package/dist/esm/transport/stream/parse.js +3 -7
- package/dist/esm/transport/wa-web-version-fetcher.js +91 -0
- package/dist/esm/util/async.js +4 -0
- package/dist/esm/util/bytes.js +37 -2
- package/dist/esm/util/clock.js +15 -0
- package/dist/esm/util/coercion.js +45 -3
- package/dist/esm/util/collections.js +11 -0
- package/dist/esm/util/index.js +2 -2
- package/dist/esm/util/primitives.js +19 -0
- package/dist/esm/util/runtime.js +5 -0
- package/dist/esm/version-spec.js +1 -0
- package/dist/index.js +35 -5
- package/dist/infra/log/ConsoleLogger.js +30 -6
- package/dist/infra/log/PinoLogger.js +64 -0
- package/dist/infra/log/types.js +4 -2
- package/dist/infra/perf/BackgroundQueue.js +55 -13
- package/dist/media/constants.js +34 -3
- package/dist/media/crypto/WaMediaCrypto.js +378 -0
- package/dist/media/index.js +9 -4
- package/dist/media/sticker/sticker-pack.js +136 -0
- package/dist/media/{WaMediaTransferClient.js → transfer/WaMediaTransferClient.js} +37 -6
- package/dist/media/{conn.js → transfer/conn.js} +10 -5
- package/dist/message/WaMessageClient.js +46 -15
- package/dist/message/addons/link-preview/builder.js +39 -0
- package/dist/message/addons/link-preview/detect.js +58 -0
- package/dist/message/addons/link-preview/fetcher.js +394 -0
- package/dist/message/addons/link-preview/types.js +2 -0
- package/dist/message/context-info.js +129 -0
- package/dist/message/{addon-crypto.js → crypto/addon-crypto.js} +68 -10
- package/dist/message/{icdc.js → crypto/icdc.js} +5 -7
- package/dist/message/crypto/phash.js +136 -0
- package/dist/message/{reporting-token.js → crypto/reporting-token.js} +6 -6
- package/dist/message/{use-case-secret.js → crypto/use-case-secret.js} +20 -3
- package/dist/message/{content.js → encode/content.js} +192 -7
- package/dist/message/encode/media-payload.js +45 -0
- package/dist/message/{padding.js → encode/padding.js} +9 -3
- package/dist/message/index.js +2 -2
- package/dist/message/kinds/bot.js +120 -0
- package/dist/message/kinds/newsletter.js +248 -0
- package/dist/message/kinds/sticker-pack.js +34 -0
- package/dist/message/{ack.js → primitives/ack.js} +8 -1
- package/dist/message/{incoming.js → primitives/incoming.js} +216 -31
- package/dist/message/primitives/peer-data-operation.js +96 -0
- package/dist/mex.js +6 -0
- package/dist/proto.js +1 -1
- package/dist/protocol/abprops.js +10 -0
- package/dist/protocol/appstate.js +7 -31
- package/dist/protocol/auth.js +3 -2
- package/dist/protocol/bot.js +81 -0
- package/dist/protocol/browser.js +8 -0
- package/dist/protocol/business.js +22 -0
- package/dist/protocol/call.js +51 -0
- package/dist/protocol/constants.js +39 -3
- package/dist/protocol/defaults.js +3 -0
- package/dist/protocol/index.js +12 -3
- package/dist/protocol/jid.js +107 -5
- package/dist/protocol/media.js +25 -12
- package/dist/protocol/message.js +4 -1
- package/dist/protocol/newsletter.js +64 -0
- package/dist/protocol/nodes.js +22 -2
- package/dist/protocol/notification.js +19 -3
- package/dist/protocol/presence.js +16 -0
- package/dist/protocol/status.js +9 -0
- package/dist/retry/codec.js +5 -0
- package/dist/retry/parse.js +16 -34
- package/dist/retry/reason.js +5 -0
- package/dist/retry/replay.js +130 -36
- package/dist/retry/tracker.js +3 -7
- package/dist/signal/api/SignalDeviceSyncApi.js +67 -18
- package/dist/signal/api/SignalDigestSyncApi.js +7 -2
- package/dist/signal/api/SignalIdentitySyncApi.js +9 -0
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +21 -60
- package/dist/signal/api/SignalRotateKeyApi.js +10 -0
- package/dist/signal/api/SignalSessionSyncApi.js +20 -48
- package/dist/signal/api/codec.js +52 -0
- package/dist/signal/api/prekeys.js +4 -0
- package/dist/signal/{crypto → attestation}/WaAdvSignature.js +6 -8
- package/dist/signal/constants.js +4 -1
- package/dist/signal/encoding.js +5 -303
- package/dist/signal/group/SenderKeyChain.js +18 -33
- package/dist/signal/group/SenderKeyCodec.js +2 -2
- package/dist/signal/group/SenderKeyManager.js +26 -9
- package/dist/signal/group/encoding.js +101 -0
- package/dist/signal/index.js +13 -10
- package/dist/signal/registration/encoding.js +39 -0
- package/dist/signal/registration/keygen.js +11 -1
- package/dist/signal/registration/utils.js +8 -1
- package/dist/signal/session/SignalProtocol.js +113 -11
- package/dist/signal/session/SignalRatchet.js +26 -56
- package/dist/signal/session/SignalSerializer.js +2 -2
- package/dist/signal/session/SignalSession.js +7 -15
- package/dist/signal/session/encoding.js +183 -0
- package/dist/signal/session/resolver.js +139 -30
- package/dist/store/cache/identity.cache.js +78 -0
- package/dist/store/cache/privacy-token.cache.js +60 -0
- package/dist/store/cache/sender-key.cache.js +104 -0
- package/dist/store/cache/session.cache.js +95 -0
- package/dist/store/contracts/group-metadata.store.js +2 -0
- package/dist/store/createStore.js +90 -36
- package/dist/store/index.js +18 -16
- package/dist/store/locks/contact.lock.js +1 -0
- package/dist/store/locks/device-list.lock.js +1 -0
- package/dist/store/locks/group-metadata.lock.js +23 -0
- package/dist/store/locks/pre-key.lock.js +4 -1
- package/dist/store/{providers/memory → memory}/appstate.store.js +5 -5
- package/dist/store/memory/auth.store.js +28 -0
- package/dist/store/memory/contact.store.js +83 -0
- package/dist/store/memory/device-list.store.js +107 -0
- package/dist/store/{providers/memory/participants.store.js → memory/group-metadata.store.js} +24 -15
- package/dist/store/{providers/memory → memory}/identity.store.js +3 -3
- package/dist/store/{providers/memory → memory}/message-secret.store.js +17 -8
- package/dist/store/{providers/memory → memory}/message.store.js +2 -2
- package/dist/store/{providers/memory → memory}/pre-key.store.js +2 -2
- package/dist/store/{providers/memory → memory}/privacy-token.store.js +1 -1
- package/dist/store/{providers/memory → memory}/retry.store.js +28 -7
- package/dist/store/{providers/memory → memory}/sender-key.store.js +3 -3
- package/dist/store/{providers/memory → memory}/session.store.js +3 -3
- package/dist/store/{providers/memory → memory}/thread.store.js +2 -2
- package/dist/store/noop.store.js +7 -5
- package/dist/transport/WaComms.js +14 -5
- package/dist/transport/WaWebSocket.js +32 -8
- package/dist/transport/binary/constants.js +11 -5
- package/dist/transport/binary/decoder.js +24 -18
- package/dist/transport/binary/encoder.js +109 -34
- package/dist/transport/binary/tokens.js +12 -12
- package/dist/transport/index.js +3 -1
- package/dist/transport/keepalive/WaKeepAlive.js +18 -4
- package/dist/transport/node/WaMobileTcpSocket.js +6 -0
- package/dist/transport/node/WaNodeOrchestrator.js +9 -5
- package/dist/transport/node/WaNodeTransport.js +13 -0
- package/dist/transport/node/builders/abprops.js +1 -1
- package/dist/transport/node/builders/account-sync.js +7 -16
- package/dist/transport/node/builders/bot.js +43 -0
- package/dist/transport/node/builders/business.js +31 -31
- package/dist/transport/node/builders/chatstate.js +31 -0
- package/dist/transport/node/builders/community.js +59 -0
- package/dist/transport/node/builders/device.js +1 -1
- package/dist/transport/node/builders/email.js +6 -5
- package/dist/transport/node/builders/global.js +2 -2
- package/dist/transport/node/builders/group.js +121 -3
- package/dist/transport/node/builders/media.js +1 -1
- package/dist/transport/node/builders/message.js +84 -49
- package/dist/transport/node/builders/newsletter.js +183 -0
- package/dist/transport/node/builders/passive.js +10 -0
- package/dist/transport/node/builders/prekeys.js +3 -3
- package/dist/transport/node/builders/presence.js +28 -1
- package/dist/transport/node/builders/privacy-token.js +1 -1
- package/dist/transport/node/builders/privacy.js +5 -5
- package/dist/transport/node/builders/profile.js +30 -7
- package/dist/transport/node/builders/tos.js +63 -0
- package/dist/transport/node/builders/usync.js +52 -1
- package/dist/transport/node/helpers.js +3 -2
- package/dist/transport/node/mex/argo-decoder.js +2 -2
- package/dist/transport/node/mex/client.js +23 -0
- package/dist/transport/node/query.js +17 -0
- package/dist/transport/node/usync.js +13 -0
- package/dist/transport/noise/WaClientPayload.js +9 -9
- package/dist/transport/noise/WaMobileClientPayload.js +6 -1
- package/dist/transport/noise/WaNoiseCert.js +7 -2
- package/dist/transport/noise/WaNoiseHandshake.js +26 -24
- package/dist/transport/noise/WaNoiseSession.js +41 -61
- package/dist/transport/noise/WaNoiseSocket.js +19 -13
- package/dist/transport/noise/constants.js +1 -2
- package/dist/transport/proxy.js +5 -0
- package/dist/transport/stream/parse.js +3 -7
- package/dist/transport/wa-web-version-fetcher.js +94 -0
- package/dist/types/appstate/constants.d.ts +1 -1
- package/dist/types/appstate/{WaAppStateCrypto.d.ts → crypto/WaAppStateCrypto.d.ts} +26 -9
- package/dist/types/appstate/index.d.ts +5 -5
- package/dist/types/appstate/{encoding.d.ts → parsers/encoding.d.ts} +8 -1
- package/dist/types/appstate/{response-parser.d.ts → parsers/response-parser.d.ts} +13 -3
- package/dist/types/appstate/sync/WaAppStateSyncClient.d.ts +105 -0
- package/dist/types/appstate/types.d.ts +1 -1
- package/dist/types/appstate/utils.d.ts +18 -2
- package/dist/types/appstate-spec.d.ts +24 -0
- package/dist/types/auth/WaAuthClient.d.ts +89 -3
- package/dist/types/auth/credentials-flow.d.ts +4 -3
- package/dist/types/auth/pairing/pairing-code-crypto.d.ts +0 -1
- package/dist/types/auth/types.d.ts +49 -2
- package/dist/types/client/WaClient.d.ts +178 -71
- package/dist/types/client/WaClientFactory.d.ts +30 -5
- package/dist/types/client/connection/WaConnectionManager.d.ts +4 -2
- package/dist/types/client/connection/WaReceiptQueue.d.ts +1 -1
- package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +215 -5
- package/dist/types/client/coordinators/WaBotCoordinator.d.ts +117 -0
- package/dist/types/client/coordinators/WaBroadcastListCoordinator.d.ts +39 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +44 -43
- package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +16 -0
- package/dist/types/client/coordinators/WaGroupCoordinator.d.ts +311 -9
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +11 -4
- package/dist/types/client/coordinators/WaLowLevelCoordinator.d.ts +47 -0
- package/dist/types/client/coordinators/WaMessageCoordinator.d.ts +232 -0
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +55 -32
- package/dist/types/client/coordinators/WaNewsletterCoordinator.d.ts +13 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -3
- package/dist/types/client/coordinators/WaPresenceCoordinator.d.ts +27 -0
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +27 -0
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +113 -0
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +19 -17
- package/dist/types/client/coordinators/WaStatusCoordinator.d.ts +42 -0
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +5 -1
- package/dist/types/client/events/abprops.d.ts +2 -1
- package/dist/types/client/events/appstate-mutation.d.ts +3 -0
- package/dist/types/client/events/business.d.ts +10 -0
- package/dist/types/client/events/call.d.ts +31 -0
- package/dist/types/client/events/chatstate.d.ts +9 -0
- package/dist/types/client/events/devices.d.ts +5 -4
- package/dist/types/client/{dirty.d.ts → events/dirty.d.ts} +4 -3
- package/dist/types/client/events/group.d.ts +2 -1
- package/dist/types/client/events/identity.d.ts +2 -1
- package/dist/types/client/{incoming.d.ts → events/incoming.d.ts} +27 -4
- package/dist/types/client/events/mex-notification.d.ts +6 -0
- package/dist/types/client/events/picture.d.ts +8 -0
- package/dist/types/client/events/presence.d.ts +28 -0
- package/dist/types/client/events/receipt.d.ts +14 -0
- package/dist/types/client/events/registration.d.ts +4 -3
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/media.d.ts +35 -1
- package/dist/types/client/messaging/fanout.d.ts +2 -2
- package/dist/types/client/messaging/group-metadata.d.ts +19 -0
- package/dist/types/client/messaging/ignore-key.d.ts +11 -0
- package/dist/types/client/messaging/key-protocol.d.ts +9 -7
- package/dist/types/client/messaging/link-preview.d.ts +19 -0
- package/dist/types/client/messaging/messages.d.ts +28 -0
- package/dist/types/client/newsletter/admin.d.ts +71 -0
- package/dist/types/client/newsletter/content.d.ts +42 -0
- package/dist/types/client/newsletter/discovery.d.ts +33 -0
- package/dist/types/client/newsletter/messaging.d.ts +66 -0
- package/dist/types/client/newsletter/mex.d.ts +14 -0
- package/dist/types/client/newsletter/parse.d.ts +19 -0
- package/dist/types/client/newsletter/types.d.ts +190 -0
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +12 -1
- package/dist/types/client/persistence/history-sync.d.ts +29 -0
- package/dist/types/client/{mailbox.d.ts → persistence/mailbox.d.ts} +4 -4
- package/dist/types/client/tokens/cs-token.d.ts +1 -3
- package/dist/types/client/types.d.ts +844 -72
- package/dist/types/crypto/core/hkdf.d.ts +10 -2
- package/dist/types/crypto/core/index.d.ts +2 -2
- package/dist/types/crypto/core/keys.d.ts +0 -4
- package/dist/types/crypto/core/nonce.d.ts +4 -5
- package/dist/types/crypto/core/primitives.d.ts +31 -20
- package/dist/types/crypto/core/random.d.ts +6 -0
- package/dist/types/crypto/core/xeddsa.d.ts +9 -0
- package/dist/types/crypto/curves/Ed25519.d.ts +7 -1
- package/dist/types/crypto/curves/X25519.d.ts +20 -1
- package/dist/types/crypto/curves/constants.d.ts +4 -3
- package/dist/types/crypto/curves/types.d.ts +0 -5
- package/dist/types/crypto/math/constants.d.ts +0 -1
- package/dist/types/crypto/math/mod.d.ts +0 -1
- package/dist/types/index.d.ts +34 -8
- package/dist/types/infra/log/ConsoleLogger.d.ts +18 -1
- package/dist/types/infra/log/PinoLogger.d.ts +55 -1
- package/dist/types/infra/log/types.d.ts +6 -0
- package/dist/types/infra/perf/BackgroundQueue.d.ts +19 -0
- package/dist/types/media/constants.d.ts +7 -2
- package/dist/types/media/crypto/WaMediaCrypto.d.ts +59 -0
- package/dist/types/media/index.d.ts +7 -5
- package/dist/types/media/processor.d.ts +27 -5
- package/dist/types/media/sticker/sticker-pack.d.ts +6 -0
- package/dist/types/media/{WaMediaTransferClient.d.ts → transfer/WaMediaTransferClient.d.ts} +30 -1
- package/dist/types/media/transfer/conn.d.ts +7 -0
- package/dist/types/media/types.d.ts +1 -2
- package/dist/types/message/WaMessageClient.d.ts +14 -0
- package/dist/types/message/addons/link-preview/builder.d.ts +13 -0
- package/dist/types/message/addons/link-preview/detect.d.ts +5 -0
- package/dist/types/message/addons/link-preview/fetcher.d.ts +13 -0
- package/dist/types/message/addons/link-preview/types.d.ts +51 -0
- package/dist/types/message/context-info.d.ts +66 -0
- package/dist/types/message/{addon-crypto.d.ts → crypto/addon-crypto.d.ts} +27 -5
- package/dist/types/message/{icdc.d.ts → crypto/icdc.d.ts} +4 -4
- package/dist/types/message/{phash.d.ts → crypto/phash.d.ts} +1 -1
- package/dist/types/message/{reporting-token.d.ts → crypto/reporting-token.d.ts} +2 -2
- package/dist/types/message/{use-case-secret.d.ts → crypto/use-case-secret.d.ts} +17 -1
- package/dist/types/message/encode/content.d.ts +43 -0
- package/dist/types/message/{device-sent.d.ts → encode/device-sent.d.ts} +1 -1
- package/dist/types/message/encode/media-payload.d.ts +12 -0
- package/dist/types/message/index.d.ts +2 -2
- package/dist/types/message/kinds/bot.d.ts +31 -0
- package/dist/types/message/kinds/newsletter.d.ts +12 -0
- package/dist/types/message/kinds/sticker-pack.d.ts +6 -0
- package/dist/types/message/{ack.d.ts → primitives/ack.d.ts} +1 -1
- package/dist/types/message/primitives/incoming.d.ts +21 -0
- package/dist/types/message/primitives/peer-data-operation.d.ts +23 -0
- package/dist/types/message/types.d.ts +209 -11
- package/dist/types/mex.d.ts +2 -0
- package/dist/types/proto.d.ts +2 -2
- package/dist/types/protocol/abprops.d.ts +9 -0
- package/dist/types/protocol/appstate.d.ts +4 -49
- package/dist/types/protocol/auth.d.ts +2 -2
- package/dist/types/protocol/bot.d.ts +45 -0
- package/dist/types/protocol/browser.d.ts +8 -0
- package/dist/types/protocol/business.d.ts +21 -0
- package/dist/types/protocol/call.d.ts +44 -0
- package/dist/types/protocol/constants.d.ts +16 -3
- package/dist/types/protocol/defaults.d.ts +3 -0
- package/dist/types/protocol/group.d.ts +1 -1
- package/dist/types/protocol/index.d.ts +2 -1
- package/dist/types/protocol/jid.d.ts +78 -0
- package/dist/types/protocol/media.d.ts +21 -13
- package/dist/types/protocol/message.d.ts +4 -0
- package/dist/types/protocol/newsletter.d.ts +65 -0
- package/dist/types/protocol/nodes.d.ts +20 -0
- package/dist/types/protocol/notification.d.ts +16 -0
- package/dist/types/protocol/presence.d.ts +16 -0
- package/dist/types/protocol/status.d.ts +7 -0
- package/dist/types/retry/codec.d.ts +5 -0
- package/dist/types/retry/index.d.ts +1 -1
- package/dist/types/retry/parse.d.ts +9 -0
- package/dist/types/retry/reason.d.ts +5 -0
- package/dist/types/retry/replay.d.ts +19 -5
- package/dist/types/retry/tracker.d.ts +10 -3
- package/dist/types/retry/types.d.ts +3 -8
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +20 -0
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +10 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +9 -0
- package/dist/types/signal/api/SignalMissingPreKeysSyncApi.d.ts +8 -0
- package/dist/types/signal/api/SignalRotateKeyApi.d.ts +10 -0
- package/dist/types/signal/api/SignalSessionSyncApi.d.ts +13 -0
- package/dist/types/signal/api/codec.d.ts +20 -0
- package/dist/types/signal/api/constants.d.ts +1 -1
- package/dist/types/signal/api/prekeys.d.ts +4 -0
- package/dist/types/signal/{crypto → attestation}/WaAdvSignature.d.ts +2 -2
- package/dist/types/signal/attestation/constants.d.ts +4 -0
- package/dist/types/signal/constants.d.ts +7 -4
- package/dist/types/signal/encoding.d.ts +6 -68
- package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
- package/dist/types/signal/group/SenderKeyManager.d.ts +18 -1
- package/dist/types/signal/group/encoding.d.ts +25 -0
- package/dist/types/signal/index.d.ts +4 -1
- package/dist/types/signal/registration/encoding.d.ts +30 -0
- package/dist/types/signal/registration/keygen.d.ts +10 -0
- package/dist/types/signal/registration/utils.d.ts +5 -0
- package/dist/types/signal/session/SignalProtocol.d.ts +55 -0
- package/dist/types/signal/session/SignalRatchet.d.ts +2 -3
- package/dist/types/signal/session/SignalSession.d.ts +0 -1
- package/dist/types/signal/session/encoding.d.ts +28 -0
- package/dist/types/signal/session/resolver.d.ts +14 -0
- package/dist/types/signal/types.d.ts +1 -1
- package/dist/types/store/cache/identity.cache.d.ts +15 -0
- package/dist/types/store/cache/privacy-token.cache.d.ts +15 -0
- package/dist/types/store/cache/sender-key.cache.d.ts +18 -0
- package/dist/types/store/cache/session.cache.d.ts +23 -0
- package/dist/types/store/contracts/contact.store.d.ts +14 -0
- package/dist/types/store/contracts/device-list.store.d.ts +13 -0
- package/dist/types/store/contracts/group-metadata.store.d.ts +14 -0
- package/dist/types/store/contracts/message.store.d.ts +0 -2
- package/dist/types/store/createStore.d.ts +54 -2
- package/dist/types/store/index.d.ts +17 -16
- package/dist/types/store/locks/group-metadata.lock.d.ts +2 -0
- package/dist/types/store/{providers/memory → memory}/appstate.store.d.ts +2 -2
- package/dist/types/store/memory/auth.store.d.ts +18 -0
- package/dist/types/store/{providers/memory → memory}/contact.store.d.ts +6 -1
- package/dist/types/store/{providers/memory → memory}/device-list.store.d.ts +15 -2
- package/dist/types/store/memory/group-metadata.store.d.ts +27 -0
- package/dist/types/store/{providers/memory → memory}/identity.store.d.ts +2 -2
- package/dist/types/store/{providers/memory → memory}/message-secret.store.d.ts +12 -2
- package/dist/types/store/{providers/memory → memory}/message.store.d.ts +1 -1
- package/dist/types/store/{providers/memory → memory}/pre-key.store.d.ts +2 -2
- package/dist/types/store/{providers/memory → memory}/privacy-token.store.d.ts +1 -1
- package/dist/types/store/{providers/memory → memory}/retry.store.d.ts +16 -3
- package/dist/types/store/{providers/memory → memory}/sender-key.store.d.ts +2 -2
- package/dist/types/store/{providers/memory → memory}/session.store.d.ts +2 -2
- package/dist/types/store/{providers/memory → memory}/signal.store.d.ts +2 -2
- package/dist/types/store/{providers/memory → memory}/thread.store.d.ts +1 -1
- package/dist/types/store/noop.store.d.ts +2 -2
- package/dist/types/store/types.d.ts +250 -6
- package/dist/types/transport/WaComms.d.ts +5 -0
- package/dist/types/transport/WaWebSocket.d.ts +5 -0
- package/dist/types/transport/binary/constants.d.ts +8 -2
- package/dist/types/transport/binary/decoder.d.ts +5 -0
- package/dist/types/transport/binary/encoder.d.ts +5 -0
- package/dist/types/transport/binary/tokens.d.ts +6 -6
- package/dist/types/transport/index.d.ts +3 -1
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +7 -0
- package/dist/types/transport/node/WaMobileTcpSocket.d.ts +6 -0
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +5 -0
- package/dist/types/transport/node/WaNodeTransport.d.ts +13 -0
- package/dist/types/transport/node/builders/account-sync.d.ts +1 -2
- package/dist/types/transport/node/builders/bot.d.ts +4 -0
- package/dist/types/transport/node/builders/business.d.ts +21 -4
- package/dist/types/transport/node/builders/chatstate.d.ts +11 -0
- package/dist/types/transport/node/builders/community.d.ts +17 -0
- package/dist/types/transport/node/builders/group.d.ts +44 -2
- package/dist/types/transport/node/builders/message.d.ts +11 -6
- package/dist/types/transport/node/builders/newsletter.d.ts +73 -0
- package/dist/types/transport/node/builders/passive.d.ts +3 -0
- package/dist/types/transport/node/builders/presence.d.ts +8 -1
- package/dist/types/transport/node/builders/profile.d.ts +3 -0
- package/dist/types/transport/node/builders/tos.d.ts +12 -0
- package/dist/types/transport/node/builders/usync.d.ts +16 -0
- package/dist/types/transport/node/helpers.d.ts +1 -2
- package/dist/types/transport/node/mex/client.d.ts +12 -1
- package/dist/types/transport/node/query.d.ts +19 -1
- package/dist/types/transport/node/usync.d.ts +3 -0
- package/dist/types/transport/noise/WaMobileClientPayload.d.ts +6 -1
- package/dist/types/transport/noise/WaNoiseCert.d.ts +5 -0
- package/dist/types/transport/noise/WaNoiseHandshake.d.ts +12 -6
- package/dist/types/transport/noise/WaNoiseSession.d.ts +0 -1
- package/dist/types/transport/noise/WaNoiseSocket.d.ts +12 -6
- package/dist/types/transport/noise/constants.d.ts +4 -5
- package/dist/types/transport/noise/types.d.ts +1 -1
- package/dist/types/transport/proxy.d.ts +5 -0
- package/dist/types/transport/types.d.ts +14 -7
- package/dist/types/transport/wa-web-version-fetcher.d.ts +44 -0
- package/dist/types/util/async.d.ts +4 -0
- package/dist/types/util/bytes.d.ts +36 -1
- package/dist/types/util/clock.d.ts +6 -0
- package/dist/types/util/coercion.d.ts +25 -0
- package/dist/types/util/collections.d.ts +8 -0
- package/dist/types/util/index.d.ts +2 -2
- package/dist/types/util/primitives.d.ts +11 -0
- package/dist/types/util/runtime.d.ts +5 -0
- package/dist/types/version-spec.d.ts +1 -0
- package/dist/util/async.js +4 -0
- package/dist/util/bytes.js +37 -2
- package/dist/util/clock.js +18 -0
- package/dist/util/coercion.js +48 -3
- package/dist/util/collections.js +12 -0
- package/dist/util/index.js +7 -1
- package/dist/util/primitives.js +20 -0
- package/dist/util/runtime.js +5 -0
- package/dist/version-spec.js +5 -0
- package/package.json +32 -8
- package/spec/appstate/index.d.ts +188 -0
- package/spec/appstate/index.js +850 -0
- package/spec/mex/index.d.ts +4172 -0
- package/spec/mex/index.js +261 -0
- package/spec/proto/index.d.ts +16305 -0
- package/spec/proto/index.js +1 -0
- package/spec/version/index.d.ts +4 -0
- package/spec/version/index.js +9 -0
- package/spec/version/version.json +3 -0
- package/dist/client/events/chat.js +0 -227
- package/dist/client/incoming.js +0 -306
- package/dist/client/mailbox.js +0 -66
- package/dist/client/messages.js +0 -305
- package/dist/esm/client/events/chat.js +0 -224
- package/dist/esm/client/incoming.js +0 -296
- package/dist/esm/client/mailbox.js +0 -63
- package/dist/esm/client/messages.js +0 -301
- package/dist/esm/media/WaMediaCrypto.js +0 -499
- package/dist/esm/message/phash.js +0 -47
- package/dist/esm/store/locks/participants.lock.js +0 -20
- package/dist/esm/store/providers/memory/contact.store.js +0 -28
- package/dist/esm/store/providers/memory/device-list.store.js +0 -67
- package/dist/esm/transport/node/mex/persist-ids.js +0 -10
- package/dist/media/WaMediaCrypto.js +0 -503
- package/dist/message/phash.js +0 -50
- package/dist/store/locks/participants.lock.js +0 -23
- package/dist/store/providers/memory/contact.store.js +0 -32
- package/dist/store/providers/memory/device-list.store.js +0 -71
- package/dist/transport/node/mex/persist-ids.js +0 -13
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +0 -70
- package/dist/types/client/events/chat.d.ts +0 -3
- package/dist/types/client/history-sync.d.ts +0 -20
- package/dist/types/client/messages.d.ts +0 -18
- package/dist/types/client/messaging/participants.d.ts +0 -13
- package/dist/types/media/WaMediaCrypto.d.ts +0 -22
- package/dist/types/media/conn.d.ts +0 -3
- package/dist/types/message/content.d.ts +0 -14
- package/dist/types/message/incoming.d.ts +0 -18
- package/dist/types/signal/crypto/constants.d.ts +0 -4
- package/dist/types/store/contracts/participants.store.d.ts +0 -13
- package/dist/types/store/locks/participants.lock.d.ts +0 -2
- package/dist/types/store/providers/memory/participants.store.d.ts +0 -17
- package/dist/types/transport/node/mex/persist-ids.d.ts +0 -14
- package/proto/index.d.ts +0 -10903
- package/proto/index.js +0 -1
- /package/dist/{store/contracts/participants.store.js → client/newsletter/types.js} +0 -0
- /package/dist/esm/{store/contracts/participants.store.js → client/newsletter/types.js} +0 -0
- /package/dist/esm/message/{device-sent.js → encode/device-sent.js} +0 -0
- /package/dist/esm/signal/{crypto → attestation}/constants.js +0 -0
- /package/dist/esm/store/{providers/memory → memory}/signal.store.js +0 -0
- /package/dist/message/{device-sent.js → encode/device-sent.js} +0 -0
- /package/dist/signal/{crypto → attestation}/constants.js +0 -0
- /package/dist/store/{providers/memory → memory}/signal.store.js +0 -0
- /package/dist/types/message/{padding.d.ts → encode/padding.d.ts} +0 -0
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { persistIncomingMailboxEntities } from './mailbox.js';
|
|
2
|
+
import { createIgnoreKeyFilter, validateIgnoreKey } from './messaging/ignore-key.js';
|
|
3
|
+
import { runHistorySyncNotification } from './persistence/history-sync.js';
|
|
4
|
+
import { persistIncomingMailboxEntities } from './persistence/mailbox.js';
|
|
6
5
|
import { WriteBehindPersistence } from './persistence/WriteBehindPersistence.js';
|
|
7
6
|
import { buildWaClientDependencies, resolveWaClientBase } from './WaClientFactory.js';
|
|
8
7
|
import { ConsoleLogger } from '../infra/log/ConsoleLogger.js';
|
|
9
|
-
import { buildAddonAdditionalData, decodeAddonPlaintext, decryptAddonPayload, identifyEncryptedAddon, resolveParentMessageSecret, resolvePollOptionNames, shouldUseAddonAdditionalData } from '../message/addon-crypto.js';
|
|
10
8
|
import { proto } from '../proto.js';
|
|
11
|
-
import {
|
|
12
|
-
import { normalizeDeviceJid
|
|
13
|
-
import { WA_LOGOUT_REASONS } from '../protocol/stream.js';
|
|
9
|
+
import { WA_DEFAULTS, WA_MESSAGE_TYPES } from '../protocol/constants.js';
|
|
10
|
+
import { normalizeDeviceJid } from '../protocol/jid.js';
|
|
11
|
+
import { WA_DISCONNECT_REASONS, WA_LOGOUT_REASONS } from '../protocol/stream.js';
|
|
14
12
|
import { NOOP_MESSAGE_SECRET_STORE } from '../store/noop.store.js';
|
|
15
13
|
import { buildRemoveCompanionDeviceIq } from '../transport/node/builders/device.js';
|
|
16
|
-
import { buildPresenceNode } from '../transport/node/builders/presence.js';
|
|
17
14
|
import { assertIqResult, queryWithContext as queryNodeWithContext } from '../transport/node/query.js';
|
|
18
|
-
import {
|
|
15
|
+
import { fetchLatestWaWebVersion } from '../transport/wa-web-version-fetcher.js';
|
|
19
16
|
import { toError } from '../util/primitives.js';
|
|
20
17
|
const SYNC_RELATED_PROTOCOL_TYPES = new Set([
|
|
21
18
|
proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_REQUEST,
|
|
@@ -23,7 +20,59 @@ const SYNC_RELATED_PROTOCOL_TYPES = new Set([
|
|
|
23
20
|
proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE,
|
|
24
21
|
proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE
|
|
25
22
|
]);
|
|
23
|
+
/**
|
|
24
|
+
* Top-level WhatsApp client. Owns the transport, auth, signal, and per-feature
|
|
25
|
+
* coordinators (accessible via getters such as {@link message}, {@link group},
|
|
26
|
+
* {@link newsletter}, etc.) and re-emits every {@link WaClientEventMap} event.
|
|
27
|
+
*
|
|
28
|
+
* Lifecycle: construct with {@link WaClientOptions}, call {@link connect} to
|
|
29
|
+
* open the socket, react to `connection`/`auth_qr`/`auth_pairing_code` events,
|
|
30
|
+
* then use the coordinator getters to drive the session. Call {@link disconnect}
|
|
31
|
+
* to shut down cleanly or {@link logout} to remove the companion device.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { createPinoLogger, createStore, WaClient } from '..'
|
|
36
|
+
* import { createSqliteStore } from '@zapo-js/store-sqlite'
|
|
37
|
+
*
|
|
38
|
+
* const store = createStore({
|
|
39
|
+
* backends: { sqlite: createSqliteStore({ path: '.auth/state.sqlite' }) },
|
|
40
|
+
* providers: {
|
|
41
|
+
* auth: 'sqlite',
|
|
42
|
+
* signal: 'sqlite',
|
|
43
|
+
* preKey: 'sqlite',
|
|
44
|
+
* session: 'sqlite',
|
|
45
|
+
* identity: 'sqlite',
|
|
46
|
+
* senderKey: 'sqlite',
|
|
47
|
+
* appState: 'sqlite',
|
|
48
|
+
* privacyToken: 'sqlite',
|
|
49
|
+
* messages: 'sqlite',
|
|
50
|
+
* threads: 'sqlite',
|
|
51
|
+
* contacts: 'sqlite'
|
|
52
|
+
* }
|
|
53
|
+
* })
|
|
54
|
+
*
|
|
55
|
+
* const client = new WaClient(
|
|
56
|
+
* { store, sessionId: 'default' },
|
|
57
|
+
* await createPinoLogger({ level: 'info', pretty: true })
|
|
58
|
+
* )
|
|
59
|
+
*
|
|
60
|
+
* client.on('auth_qr', ({ qr, ttlMs }) => console.log('scan:', qr, ttlMs))
|
|
61
|
+
* client.on('connection', (event) => console.log('connection', event))
|
|
62
|
+
* client.on('message', async (event) => {
|
|
63
|
+
* if (event.message?.conversation === 'ping') {
|
|
64
|
+
* await client.message.send(event.chatJid!, 'pong')
|
|
65
|
+
* }
|
|
66
|
+
* })
|
|
67
|
+
*
|
|
68
|
+
* await client.connect()
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
26
71
|
export class WaClient extends EventEmitter {
|
|
72
|
+
/**
|
|
73
|
+
* @param options Client configuration (store, transport, addons, history...).
|
|
74
|
+
* @param logger Optional structured logger. Defaults to a `ConsoleLogger('info')`.
|
|
75
|
+
*/
|
|
27
76
|
constructor(options, logger = new ConsoleLogger('info')) {
|
|
28
77
|
super();
|
|
29
78
|
this.connectPromise = null;
|
|
@@ -33,38 +82,26 @@ export class WaClient extends EventEmitter {
|
|
|
33
82
|
const base = resolveWaClientBase(options, logger);
|
|
34
83
|
this.options = base.options;
|
|
35
84
|
this.logger = base.logger;
|
|
36
|
-
this.
|
|
37
|
-
this.contactStore = base.sessionStore.contacts;
|
|
38
|
-
this.messageStore = base.sessionStore.messages;
|
|
39
|
-
this.messageSecretStore = base.sessionStore.messageSecret;
|
|
40
|
-
this.participantsStore = base.sessionStore.participants;
|
|
41
|
-
this.privacyTokenStore = base.sessionStore.privacyToken;
|
|
42
|
-
this.deviceListStore = base.sessionStore.deviceList;
|
|
43
|
-
this.retryStore = base.sessionStore.retry;
|
|
44
|
-
this.signalStore = base.sessionStore.signal;
|
|
45
|
-
this.preKeyStore = base.sessionStore.preKey;
|
|
46
|
-
this.sessionStore = base.sessionStore.session;
|
|
47
|
-
this.identityStore = base.sessionStore.identity;
|
|
48
|
-
this.senderKeyStore = base.sessionStore.senderKey;
|
|
49
|
-
this.threadStore = base.sessionStore.threads;
|
|
85
|
+
this.stores = base.sessionStore;
|
|
50
86
|
this.writeBehind = new WriteBehindPersistence({
|
|
51
|
-
messageStore: this.
|
|
52
|
-
threadStore: this.
|
|
53
|
-
contactStore: this.
|
|
87
|
+
messageStore: this.stores.messages,
|
|
88
|
+
threadStore: this.stores.threads,
|
|
89
|
+
contactStore: this.stores.contacts
|
|
54
90
|
}, this.logger, this.options.writeBehind);
|
|
55
|
-
if (this.options.addons?.autoDecrypt &&
|
|
56
|
-
this.
|
|
57
|
-
this.logger.warn('addons.autoDecrypt is
|
|
58
|
-
'addon decryption will only work if secrets are in the message store'
|
|
91
|
+
if (this.options.addons?.autoDecrypt !== false &&
|
|
92
|
+
this.stores.messageSecret === NOOP_MESSAGE_SECRET_STORE) {
|
|
93
|
+
this.logger.warn('addons.autoDecrypt is on (default) but messageSecret cache is noop – ' +
|
|
94
|
+
'addon decryption will only work if secrets are in the message store. ' +
|
|
95
|
+
'Set addons.autoDecrypt: false to silence this warning.');
|
|
59
96
|
}
|
|
60
97
|
const dependencies = buildWaClientDependencies({
|
|
61
98
|
base,
|
|
62
99
|
runtime: {
|
|
63
|
-
sendNode: (node) => this.sendNode(node),
|
|
64
|
-
query: (node, timeoutMs, options) => this.query(node, timeoutMs, options),
|
|
100
|
+
sendNode: (node) => this.deps.lowLevelCoordinator.sendNode(node),
|
|
101
|
+
query: (node, timeoutMs, options) => this.deps.lowLevelCoordinator.query(node, timeoutMs, options),
|
|
65
102
|
queryWithContext: this.queryWithContext.bind(this),
|
|
66
|
-
syncAppState: () => this.
|
|
67
|
-
syncAppStateWithOptions: (syncOptions) => this.
|
|
103
|
+
syncAppState: () => this.deps.chatCoordinator.sync().then(() => { }),
|
|
104
|
+
syncAppStateWithOptions: (syncOptions) => this.deps.chatCoordinator.sync(syncOptions),
|
|
68
105
|
emitEvent: this.emit.bind(this),
|
|
69
106
|
handleIncomingMessageEvent: this.handleIncomingMessageEvent.bind(this),
|
|
70
107
|
handleError: this.handleError.bind(this),
|
|
@@ -72,11 +109,50 @@ export class WaClient extends EventEmitter {
|
|
|
72
109
|
clearStoredState: this.clearStoredState.bind(this),
|
|
73
110
|
resumeIncomingEvents: () => {
|
|
74
111
|
this.acceptingIncomingEvents = true;
|
|
75
|
-
}
|
|
112
|
+
},
|
|
113
|
+
subscribeProtocolMessage: (handler) => {
|
|
114
|
+
this.on('message_protocol', handler);
|
|
115
|
+
return () => {
|
|
116
|
+
this.off('message_protocol', handler);
|
|
117
|
+
};
|
|
118
|
+
},
|
|
119
|
+
persistContact: (record) => this.writeBehind.persistContact(record)
|
|
76
120
|
}
|
|
77
121
|
});
|
|
78
|
-
|
|
122
|
+
this.deps = dependencies;
|
|
123
|
+
this.appStateSync = dependencies.appStateSync;
|
|
124
|
+
this.mediaTransfer = dependencies.mediaTransfer;
|
|
79
125
|
this.bindNodeTransportEvents();
|
|
126
|
+
this.on('connection', (event) => {
|
|
127
|
+
if (event.status !== 'close')
|
|
128
|
+
return;
|
|
129
|
+
if (!this.options.recoverFromClientTooOld)
|
|
130
|
+
return;
|
|
131
|
+
if (event.reason !== WA_DISCONNECT_REASONS.FAILURE_CLIENT_TOO_OLD)
|
|
132
|
+
return;
|
|
133
|
+
this.logger.warn('wa rejected the connect with client_too_old: the zapo default WA Web version is outdated. ' +
|
|
134
|
+
'Auto-recovering by fetching the current version from web.whatsapp.com – ' +
|
|
135
|
+
'please upgrade zapo so the shipped default catches up.');
|
|
136
|
+
void this.runClientTooOldRecover();
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async runClientTooOldRecover() {
|
|
140
|
+
try {
|
|
141
|
+
if (this.connectPromise) {
|
|
142
|
+
await this.connectPromise.catch(() => undefined);
|
|
143
|
+
}
|
|
144
|
+
const latest = await fetchLatestWaWebVersion();
|
|
145
|
+
this.logger.info('client_too_old auto-recover: reconnecting', {
|
|
146
|
+
version: latest.version
|
|
147
|
+
});
|
|
148
|
+
this.deps.authClient.setNextConnectVersion(latest.version);
|
|
149
|
+
await this.connect();
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
this.logger.warn('client_too_old auto-recover failed', {
|
|
153
|
+
message: toError(error).message
|
|
154
|
+
});
|
|
155
|
+
}
|
|
80
156
|
}
|
|
81
157
|
on(event, listener) {
|
|
82
158
|
return super.on(event, listener);
|
|
@@ -90,60 +166,36 @@ export class WaClient extends EventEmitter {
|
|
|
90
166
|
emit(event, ...args) {
|
|
91
167
|
return super.emit(event, ...args);
|
|
92
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns the current auth state snapshot (credentials, registration,
|
|
171
|
+
* connection flag) – useful for resuming or inspecting the client.
|
|
172
|
+
*/
|
|
93
173
|
getState() {
|
|
94
|
-
const connected = this.connectionManager.isConnected();
|
|
174
|
+
const connected = this.deps.connectionManager.isConnected();
|
|
95
175
|
this.logger.trace('wa client state requested', { connected });
|
|
96
|
-
return this.authClient.getState(connected);
|
|
176
|
+
return this.deps.authClient.getState(connected);
|
|
97
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Returns the credentials persisted for the current session, or `null` if
|
|
180
|
+
* the client has not been paired yet.
|
|
181
|
+
*/
|
|
98
182
|
getCredentials() {
|
|
99
|
-
return this.authClient.getCurrentCredentials();
|
|
183
|
+
return this.deps.authClient.getCurrentCredentials();
|
|
100
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Returns the measured skew between the local clock and the server, in
|
|
187
|
+
* milliseconds, or `null` if no handshake has completed yet.
|
|
188
|
+
*/
|
|
101
189
|
getClockSkewMs() {
|
|
102
|
-
return this.connectionManager.getClockSkewMs();
|
|
103
|
-
}
|
|
104
|
-
async sendNode(node) {
|
|
105
|
-
try {
|
|
106
|
-
await this.nodeOrchestrator.sendNode(node);
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
const normalized = toError(error);
|
|
110
|
-
if (this.receiptQueue.shouldQueue(node, normalized)) {
|
|
111
|
-
this.receiptQueue.enqueue(node);
|
|
112
|
-
this.logger.warn('queued dangling receipt after send failure', {
|
|
113
|
-
id: node.attrs.id,
|
|
114
|
-
to: node.attrs.to,
|
|
115
|
-
message: normalized.message,
|
|
116
|
-
queueSize: this.receiptQueue.size()
|
|
117
|
-
});
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
throw normalized;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
async sendPresence(type) {
|
|
124
|
-
const credentials = this.authClient.getCurrentCredentials();
|
|
125
|
-
await this.nodeOrchestrator.sendNode(buildPresenceNode({ type, name: credentials?.meDisplayName ?? undefined }), false);
|
|
126
|
-
}
|
|
127
|
-
async query(node, timeoutMs = this.options.iqTimeoutMs ?? WA_DEFAULTS.IQ_TIMEOUT_MS, options = {}) {
|
|
128
|
-
if (!this.connectionManager.isConnected()) {
|
|
129
|
-
throw new Error('client is not connected');
|
|
130
|
-
}
|
|
131
|
-
this.logger.debug('wa client query', { tag: node.tag, id: node.attrs.id, timeoutMs });
|
|
132
|
-
return this.nodeOrchestrator.query(node, timeoutMs, options);
|
|
133
|
-
}
|
|
134
|
-
registerIncomingHandler(registration) {
|
|
135
|
-
return this.incomingNode.registerIncomingHandler(registration);
|
|
136
|
-
}
|
|
137
|
-
unregisterIncomingHandler(registration) {
|
|
138
|
-
return this.incomingNode.unregisterIncomingHandler(registration);
|
|
190
|
+
return this.deps.connectionManager.getClockSkewMs();
|
|
139
191
|
}
|
|
140
192
|
bindNodeTransportEvents() {
|
|
141
|
-
this.nodeTransport.on('frame_in', (frame) => this.emit('
|
|
142
|
-
this.nodeTransport.on('frame_out', (frame) => this.emit('
|
|
143
|
-
this.nodeTransport.on('node_in', (node, frame) => this.emit('
|
|
144
|
-
this.nodeTransport.on('node_out', (node, frame) => this.emit('
|
|
145
|
-
this.nodeTransport.on('decode_error', (error, frame) => {
|
|
146
|
-
this.emit('
|
|
193
|
+
this.deps.nodeTransport.on('frame_in', (frame) => this.emit('debug_transport_frame_in', { frame }));
|
|
194
|
+
this.deps.nodeTransport.on('frame_out', (frame) => this.emit('debug_transport_frame_out', { frame }));
|
|
195
|
+
this.deps.nodeTransport.on('node_in', (node, frame) => this.emit('debug_transport_node_in', { node, frame }));
|
|
196
|
+
this.deps.nodeTransport.on('node_out', (node, frame) => this.emit('debug_transport_node_out', { node, frame }));
|
|
197
|
+
this.deps.nodeTransport.on('decode_error', (error, frame) => {
|
|
198
|
+
this.emit('debug_transport_decode_error', { error, frame });
|
|
147
199
|
this.handleError(error);
|
|
148
200
|
});
|
|
149
201
|
}
|
|
@@ -156,13 +208,23 @@ export class WaClient extends EventEmitter {
|
|
|
156
208
|
void persistIncomingMailboxEntities({
|
|
157
209
|
logger: this.logger,
|
|
158
210
|
writeBehind: this.writeBehind,
|
|
159
|
-
messageSecretStore: this.
|
|
211
|
+
messageSecretStore: this.stores.messageSecret,
|
|
160
212
|
event
|
|
161
213
|
});
|
|
162
|
-
if (this.options.addons?.autoDecrypt && event.message) {
|
|
163
|
-
void this.tryDecryptAddon(event).catch((err) => {
|
|
214
|
+
if (this.options.addons?.autoDecrypt !== false && event.message) {
|
|
215
|
+
void this.deps.messageCoordinator.tryDecryptAddon(event).catch((err) => {
|
|
164
216
|
this.logger.warn('addon auto-decrypt failed', {
|
|
165
|
-
id: event.
|
|
217
|
+
id: event.key.id,
|
|
218
|
+
message: toError(err).message
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
// Decode unconditionally – chunks whose parent prompt we never sent
|
|
223
|
+
// are skipped by the secret-store lookup downstream.
|
|
224
|
+
if (event.message) {
|
|
225
|
+
void this.deps.botCoordinator.tryDecryptChunk(event).catch((err) => {
|
|
226
|
+
this.logger.warn('bot chunk auto-decrypt failed', {
|
|
227
|
+
id: event.key.id,
|
|
166
228
|
message: toError(err).message
|
|
167
229
|
});
|
|
168
230
|
});
|
|
@@ -179,36 +241,62 @@ export class WaClient extends EventEmitter {
|
|
|
179
241
|
const protocolType = protocolMessage.type;
|
|
180
242
|
if (protocolType === null || protocolType === undefined) {
|
|
181
243
|
this.logger.debug('incoming protocol message without type', {
|
|
182
|
-
id: event.
|
|
183
|
-
from: event.
|
|
244
|
+
id: event.key.id,
|
|
245
|
+
from: event.key.remoteJid
|
|
184
246
|
});
|
|
185
247
|
return;
|
|
186
248
|
}
|
|
187
249
|
if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_REQUEST) {
|
|
188
|
-
await this.
|
|
250
|
+
await this.appStateSync.handleIncomingKeyRequest(event.key, protocolMessage);
|
|
189
251
|
return;
|
|
190
252
|
}
|
|
191
253
|
if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE) {
|
|
192
|
-
await this.
|
|
254
|
+
await this.appStateSync.handleIncomingKeyShare(event.key, protocolMessage);
|
|
193
255
|
return;
|
|
194
256
|
}
|
|
195
257
|
if (protocolType === proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION) {
|
|
196
|
-
if (this.options.history?.enabled
|
|
197
|
-
|
|
258
|
+
if (this.options.history?.enabled !== false &&
|
|
259
|
+
protocolMessage.historySyncNotification) {
|
|
260
|
+
const peerRemoteJid = event.key.remoteJid;
|
|
261
|
+
const peerStanzaId = event.key.id;
|
|
262
|
+
await runHistorySyncNotification({
|
|
263
|
+
logger: this.logger,
|
|
264
|
+
mediaTransfer: this.mediaTransfer,
|
|
265
|
+
writeBehind: this.writeBehind,
|
|
266
|
+
emitEvent: this.emit.bind(this),
|
|
267
|
+
onPrivacyTokens: (conversations) => this.deps.trustedContactToken.hydrateFromHistorySync(conversations),
|
|
268
|
+
onNctSalt: (salt) => this.deps.trustedContactToken.hydrateNctSaltFromHistorySync(salt),
|
|
269
|
+
onProcessed: peerRemoteJid && peerStanzaId
|
|
270
|
+
? async () => {
|
|
271
|
+
try {
|
|
272
|
+
await this.message.sendReceipt(peerRemoteJid, peerStanzaId, {
|
|
273
|
+
type: WA_MESSAGE_TYPES.RECEIPT_TYPE_HISTORY_SYNC
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
this.logger.warn('failed to send hist_sync receipt', {
|
|
278
|
+
id: peerStanzaId,
|
|
279
|
+
to: peerRemoteJid,
|
|
280
|
+
message: toError(err).message
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
: undefined
|
|
285
|
+
}, protocolMessage.historySyncNotification);
|
|
198
286
|
}
|
|
199
287
|
return;
|
|
200
288
|
}
|
|
201
289
|
if (SYNC_RELATED_PROTOCOL_TYPES.has(protocolType)) {
|
|
202
290
|
this.logger.info('incoming sync-related protocol message', {
|
|
203
|
-
id: event.
|
|
204
|
-
from: event.
|
|
291
|
+
id: event.key.id,
|
|
292
|
+
from: event.key.remoteJid,
|
|
205
293
|
protocolType
|
|
206
294
|
});
|
|
207
295
|
return;
|
|
208
296
|
}
|
|
209
297
|
this.logger.debug('incoming protocol message received', {
|
|
210
|
-
id: event.
|
|
211
|
-
from: event.
|
|
298
|
+
id: event.key.id,
|
|
299
|
+
from: event.key.remoteJid,
|
|
212
300
|
protocolType
|
|
213
301
|
});
|
|
214
302
|
}
|
|
@@ -216,189 +304,60 @@ export class WaClient extends EventEmitter {
|
|
|
216
304
|
this.leaveIncomingHandler();
|
|
217
305
|
}
|
|
218
306
|
}
|
|
219
|
-
async handleIncomingAppStateSyncKeyShare(event, protocolMessage) {
|
|
220
|
-
const share = protocolMessage.appStateSyncKeyShare;
|
|
221
|
-
if (!share) {
|
|
222
|
-
this.logger.warn('incoming app-state key share protocol message without payload', {
|
|
223
|
-
id: event.stanzaId,
|
|
224
|
-
from: event.chatJid
|
|
225
|
-
});
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
try {
|
|
229
|
-
const imported = await this.appStateSync.importSyncKeyShare(share);
|
|
230
|
-
this.logger.info('imported app-state sync key share from protocol message', {
|
|
231
|
-
id: event.stanzaId,
|
|
232
|
-
from: event.chatJid,
|
|
233
|
-
imported
|
|
234
|
-
});
|
|
235
|
-
if (imported > 0) {
|
|
236
|
-
void this.syncAppState().catch((error) => {
|
|
237
|
-
this.logger.warn('failed to sync app-state after key share import', {
|
|
238
|
-
id: event.stanzaId,
|
|
239
|
-
from: event.chatJid,
|
|
240
|
-
message: toError(error).message
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
catch (error) {
|
|
246
|
-
this.logger.warn('failed to import app-state sync key share from protocol message', {
|
|
247
|
-
id: event.stanzaId,
|
|
248
|
-
from: event.chatJid,
|
|
249
|
-
message: toError(error).message
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
async handleIncomingAppStateSyncKeyRequest(event, protocolMessage) {
|
|
254
|
-
const request = protocolMessage.appStateSyncKeyRequest;
|
|
255
|
-
if (!request) {
|
|
256
|
-
this.logger.warn('incoming app-state key request protocol message without payload', {
|
|
257
|
-
id: event.stanzaId,
|
|
258
|
-
from: event.chatJid
|
|
259
|
-
});
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
const requesterRaw = event.senderJid ?? event.chatJid;
|
|
263
|
-
if (!requesterRaw) {
|
|
264
|
-
this.logger.warn('incoming app-state key request missing sender jid', {
|
|
265
|
-
id: event.stanzaId
|
|
266
|
-
});
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
let requesterDeviceJid;
|
|
270
|
-
try {
|
|
271
|
-
requesterDeviceJid = normalizeDeviceJid(requesterRaw);
|
|
272
|
-
}
|
|
273
|
-
catch (error) {
|
|
274
|
-
this.logger.warn('incoming app-state key request has malformed sender jid', {
|
|
275
|
-
id: event.stanzaId,
|
|
276
|
-
from: requesterRaw,
|
|
277
|
-
message: toError(error).message
|
|
278
|
-
});
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
if (!this.isOwnAccountDeviceJid(requesterDeviceJid)) {
|
|
282
|
-
this.logger.warn('incoming app-state key request ignored: sender is not own account', {
|
|
283
|
-
id: event.stanzaId,
|
|
284
|
-
from: requesterDeviceJid
|
|
285
|
-
});
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
const requestedKeyIds = this.extractAppStateSyncKeyRequestIds(request);
|
|
289
|
-
if (requestedKeyIds.length === 0) {
|
|
290
|
-
this.logger.warn('incoming app-state key request has no valid key ids', {
|
|
291
|
-
id: event.stanzaId,
|
|
292
|
-
from: requesterDeviceJid
|
|
293
|
-
});
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
const requestedKeys = await this.appStateStore.getSyncKeysBatch(requestedKeyIds);
|
|
297
|
-
const availableKeys = [];
|
|
298
|
-
const missingKeyIds = [];
|
|
299
|
-
for (let i = 0; i < requestedKeys.length; i += 1) {
|
|
300
|
-
const key = requestedKeys[i];
|
|
301
|
-
if (key !== null) {
|
|
302
|
-
availableKeys.push(key);
|
|
303
|
-
}
|
|
304
|
-
else {
|
|
305
|
-
missingKeyIds.push(requestedKeyIds[i]);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
try {
|
|
309
|
-
await this.messageDispatch.sendAppStateSyncKeyShare(requesterDeviceJid, availableKeys, missingKeyIds);
|
|
310
|
-
this.logger.info('responded to app-state key request', {
|
|
311
|
-
id: event.stanzaId,
|
|
312
|
-
to: requesterDeviceJid,
|
|
313
|
-
requested: requestedKeyIds.length,
|
|
314
|
-
shared: availableKeys.length,
|
|
315
|
-
missing: missingKeyIds.length
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
this.logger.warn('failed to respond to app-state key request', {
|
|
320
|
-
id: event.stanzaId,
|
|
321
|
-
to: requesterDeviceJid,
|
|
322
|
-
requested: requestedKeyIds.length,
|
|
323
|
-
shared: availableKeys.length,
|
|
324
|
-
missing: missingKeyIds.length,
|
|
325
|
-
message: toError(error).message
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
extractAppStateSyncKeyRequestIds(request) {
|
|
330
|
-
const deduped = new Map();
|
|
331
|
-
for (const key of request.keyIds ?? []) {
|
|
332
|
-
try {
|
|
333
|
-
const keyId = decodeProtoBytes(key.keyId, 'appStateSyncKeyRequest.keyIds[].keyId');
|
|
334
|
-
const keyHex = bytesToHex(keyId);
|
|
335
|
-
if (deduped.has(keyHex)) {
|
|
336
|
-
continue;
|
|
337
|
-
}
|
|
338
|
-
deduped.set(keyHex, keyId);
|
|
339
|
-
}
|
|
340
|
-
catch (error) {
|
|
341
|
-
this.logger.trace('ignoring malformed app-state key id request entry', {
|
|
342
|
-
message: toError(error).message
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
return [...deduped.values()];
|
|
347
|
-
}
|
|
348
|
-
isOwnAccountDeviceJid(candidateJid) {
|
|
349
|
-
const credentials = this.authClient.getCurrentCredentials();
|
|
350
|
-
if (!credentials) {
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
353
|
-
const candidateUser = toUserJid(candidateJid);
|
|
354
|
-
return ((!!credentials.meJid && toUserJid(credentials.meJid) === candidateUser) ||
|
|
355
|
-
(!!credentials.meLid && toUserJid(credentials.meLid) === candidateUser));
|
|
356
|
-
}
|
|
357
|
-
async handleHistorySyncNotification(notification) {
|
|
358
|
-
try {
|
|
359
|
-
await processHistorySyncNotification({
|
|
360
|
-
logger: this.logger,
|
|
361
|
-
mediaTransfer: this.mediaTransfer,
|
|
362
|
-
writeBehind: this.writeBehind,
|
|
363
|
-
emitEvent: this.emit.bind(this),
|
|
364
|
-
onPrivacyTokens: (conversations) => this.trustedContactToken.hydrateFromHistorySync(conversations),
|
|
365
|
-
onNctSalt: (salt) => this.trustedContactToken.hydrateNctSaltFromHistorySync(salt)
|
|
366
|
-
}, notification);
|
|
367
|
-
}
|
|
368
|
-
catch (error) {
|
|
369
|
-
this.logger.warn('failed to process history sync notification', {
|
|
370
|
-
syncType: notification.syncType,
|
|
371
|
-
chunkOrder: notification.chunkOrder,
|
|
372
|
-
message: toError(error).message
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
307
|
async queryWithContext(context, node, timeoutMs = this.options.iqTimeoutMs ?? WA_DEFAULTS.IQ_TIMEOUT_MS, contextData = {}, options = {}) {
|
|
377
|
-
return queryNodeWithContext(async (queryNode, queryTimeoutMs) => this.query(queryNode, queryTimeoutMs, options), this.logger, context, node, timeoutMs, contextData);
|
|
308
|
+
return queryNodeWithContext(async (queryNode, queryTimeoutMs) => this.deps.lowLevelCoordinator.query(queryNode, queryTimeoutMs, options), this.logger, context, node, timeoutMs, contextData);
|
|
378
309
|
}
|
|
379
310
|
async handleIncomingFrame(frame) {
|
|
380
311
|
try {
|
|
381
|
-
await this.nodeTransport.dispatchIncomingFrame(frame, async (node) => this.incomingNode.handleIncomingNode(node));
|
|
312
|
+
await this.deps.nodeTransport.dispatchIncomingFrame(frame, async (node) => this.deps.incomingNode.handleIncomingNode(node));
|
|
382
313
|
}
|
|
383
314
|
catch (error) {
|
|
384
315
|
this.handleError(toError(error));
|
|
385
316
|
}
|
|
386
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* Opens the transport and runs the noise/auth handshake. If a connection
|
|
320
|
+
* is already in flight, the in-flight promise is reused. Resolves once the
|
|
321
|
+
* client is fully ready; pairing prompts are surfaced via the `auth_qr`
|
|
322
|
+
* and `auth_pairing_code` events while this awaits.
|
|
323
|
+
*
|
|
324
|
+
* **First-time pairing:** the promise stays pending until the user scans a
|
|
325
|
+
* QR or types the pairing code. Subscribe to `auth_qr` / `auth_pairing_code`
|
|
326
|
+
* *before* awaiting – they fire while `connect()` is still running.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```ts
|
|
330
|
+
* // QR pairing (default – works headless)
|
|
331
|
+
* client.on('auth_qr', ({ qr }) => console.log('scan:', qr))
|
|
332
|
+
* client.on('auth_paired', ({ credentials }) => console.log('paired:', credentials.meJid))
|
|
333
|
+
* await client.connect()
|
|
334
|
+
*
|
|
335
|
+
* // Link-code pairing – call requestPairingCode while connect() is running
|
|
336
|
+
* void client.connect()
|
|
337
|
+
* await new Promise((r) => client.once('auth_pairing_required', r))
|
|
338
|
+
* const code = await client.auth.requestPairingCode('5511999999999')
|
|
339
|
+
* console.log('enter code on phone:', code)
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
387
342
|
async connect() {
|
|
388
343
|
if (this.connectPromise) {
|
|
389
344
|
this.logger.trace('wa client connect already in-flight');
|
|
390
345
|
return this.connectPromise;
|
|
391
346
|
}
|
|
347
|
+
this.writeBehind.restart();
|
|
392
348
|
this.acceptingIncomingEvents = true;
|
|
393
|
-
this.connectPromise = this.connectionManager
|
|
349
|
+
this.connectPromise = this.deps.connectionManager
|
|
394
350
|
.connect((frame) => this.handleIncomingFrame(frame))
|
|
395
351
|
.then(() => {
|
|
352
|
+
if (!this.deps.authClient.getCurrentCredentials()?.meJid) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
396
355
|
this.emit('connection', {
|
|
397
356
|
status: 'open',
|
|
398
357
|
reason: 'connected',
|
|
399
358
|
code: null,
|
|
400
359
|
isLogout: false,
|
|
401
|
-
isNewLogin:
|
|
360
|
+
isNewLogin: false
|
|
402
361
|
});
|
|
403
362
|
})
|
|
404
363
|
.finally(() => {
|
|
@@ -406,6 +365,14 @@ export class WaClient extends EventEmitter {
|
|
|
406
365
|
});
|
|
407
366
|
return this.connectPromise;
|
|
408
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Closes the transport gracefully: pauses incoming events, flushes the
|
|
370
|
+
* write-behind persistence queue, and emits a `connection` close event
|
|
371
|
+
* with reason `client_disconnected`. Does not clear stored credentials -
|
|
372
|
+
* call {@link connect} again to resume the same session. There is no
|
|
373
|
+
* built-in auto-reconnect; subscribe to `connection: { status: 'close' }`
|
|
374
|
+
* and decide your own backoff.
|
|
375
|
+
*/
|
|
409
376
|
async disconnect() {
|
|
410
377
|
await this.pauseIncomingEventsAndWaitDrain();
|
|
411
378
|
const writeBehindFlush = await this.writeBehind.flush(this.options.writeBehind?.flushTimeoutMs);
|
|
@@ -414,7 +381,7 @@ export class WaClient extends EventEmitter {
|
|
|
414
381
|
remaining: writeBehindFlush.remaining
|
|
415
382
|
});
|
|
416
383
|
}
|
|
417
|
-
await this.connectionManager.disconnect();
|
|
384
|
+
await this.deps.connectionManager.disconnect();
|
|
418
385
|
this.emit('connection', {
|
|
419
386
|
status: 'close',
|
|
420
387
|
reason: 'client_disconnected',
|
|
@@ -423,65 +390,112 @@ export class WaClient extends EventEmitter {
|
|
|
423
390
|
isNewLogin: false
|
|
424
391
|
});
|
|
425
392
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
393
|
+
/**
|
|
394
|
+
* Drops matching inbound stanzas before any handler runs. Server still
|
|
395
|
+
* gets the ack so it stops re-delivering. Returns an `unregister` function.
|
|
396
|
+
*
|
|
397
|
+
* Accepts either a declarative descriptor or a predicate. The descriptor
|
|
398
|
+
* matches by `remoteJid`/`fromMe`/`id`/`participant` (PN ↔ LID alt-attrs
|
|
399
|
+
* resolved automatically) and throws when no match field is given or
|
|
400
|
+
* arrays are empty. The predicate receives a parsed
|
|
401
|
+
* {@link WaIgnoreKeyContext} and returns `true` to drop the stanza.
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```ts
|
|
405
|
+
* client.ignoreKey({ remoteJid: spammerJid })
|
|
406
|
+
* client.ignoreKey({ fromMe: true, only: ['message'] })
|
|
407
|
+
* client.ignoreKey((m) => m.kind === 'message' && isGroupJid(m.remoteJid ?? ''))
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
ignoreKey(input) {
|
|
411
|
+
if (typeof input !== 'function') {
|
|
412
|
+
validateIgnoreKey(input);
|
|
413
|
+
}
|
|
414
|
+
const filter = createIgnoreKeyFilter(input, () => this.deps.authClient.getCurrentCredentials()?.meJid);
|
|
415
|
+
return this.deps.incomingNode.registerIncomingStanzaFilter(filter);
|
|
416
|
+
}
|
|
417
|
+
/** Auth client: pairing, credentials, registration state. */
|
|
418
|
+
get auth() {
|
|
419
|
+
return this.deps.authClient;
|
|
420
|
+
}
|
|
421
|
+
/** Message coordinator: send/receive, receipts, addons, media download. */
|
|
422
|
+
get message() {
|
|
423
|
+
return this.deps.messageCoordinator;
|
|
424
|
+
}
|
|
425
|
+
/** Presence coordinator: own/peer presence subscriptions. */
|
|
426
|
+
get presence() {
|
|
427
|
+
return this.deps.presenceCoordinator;
|
|
428
|
+
}
|
|
429
|
+
/** Low-level coordinator: raw node send/query escape hatch. */
|
|
430
|
+
get lowlevel() {
|
|
431
|
+
return this.deps.lowLevelCoordinator;
|
|
432
|
+
}
|
|
433
|
+
/** App-state mutation coordinator: chat-side settings (mute, pin, etc.). */
|
|
434
|
+
get chat() {
|
|
435
|
+
return this.deps.chatCoordinator;
|
|
432
436
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}
|
|
437
|
-
this.logger.trace('wa client fetch pairing country code iso');
|
|
438
|
-
return this.authClient.fetchPairingCountryCodeIso();
|
|
437
|
+
/** Group coordinator: create/query/manage WhatsApp groups and communities. */
|
|
438
|
+
get group() {
|
|
439
|
+
return this.deps.groupCoordinator;
|
|
439
440
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
const normalizedPhoneJids = new Array(phoneNumbers.length);
|
|
445
|
-
for (let index = 0; index < phoneNumbers.length; index += 1) {
|
|
446
|
-
normalizedPhoneJids[index] = parsePhoneJid(phoneNumbers[index]);
|
|
447
|
-
}
|
|
448
|
-
this.logger.trace('wa client query lids by phone numbers', {
|
|
449
|
-
phones: normalizedPhoneJids.length
|
|
450
|
-
});
|
|
451
|
-
return this.signalDeviceSync.queryLidsByPhoneJids(normalizedPhoneJids);
|
|
452
|
-
}
|
|
453
|
-
sendMessage(to, content, options = {}) {
|
|
454
|
-
return this.messageDispatch.sendMessage(to, content, options);
|
|
455
|
-
}
|
|
456
|
-
async syncSignalSession(jid, reasonIdentity = false) {
|
|
457
|
-
await this.messageDispatch.syncSignalSession(jid, reasonIdentity);
|
|
458
|
-
if (reasonIdentity) {
|
|
459
|
-
this.trustedContactToken.reissueOnIdentityChange(jid).catch((err) => this.logger.warn('tc token reissue on identity change failed', {
|
|
460
|
-
jid,
|
|
461
|
-
message: toError(err).message
|
|
462
|
-
}));
|
|
463
|
-
}
|
|
441
|
+
/** Status coordinator: status broadcast send and reactions. */
|
|
442
|
+
get status() {
|
|
443
|
+
return this.deps.statusCoordinator;
|
|
464
444
|
}
|
|
465
|
-
|
|
466
|
-
|
|
445
|
+
/**
|
|
446
|
+
* Broadcast-list coordinator: list management and broadcast sends.
|
|
447
|
+
* **Business-only** - the underlying app-state schema rejects regular
|
|
448
|
+
* accounts. See {@link WaBroadcastListCoordinator}.
|
|
449
|
+
*/
|
|
450
|
+
get broadcastList() {
|
|
451
|
+
return this.deps.broadcastListCoordinator;
|
|
467
452
|
}
|
|
468
|
-
|
|
469
|
-
|
|
453
|
+
/** Newsletter coordinator: create/query/follow/admin/send for channels. */
|
|
454
|
+
get newsletter() {
|
|
455
|
+
return this.deps.newsletterCoordinator;
|
|
470
456
|
}
|
|
457
|
+
/** Privacy coordinator: privacy categories, blocklist, disallowed list. */
|
|
471
458
|
get privacy() {
|
|
472
|
-
return this.privacyCoordinator;
|
|
459
|
+
return this.deps.privacyCoordinator;
|
|
473
460
|
}
|
|
461
|
+
/** Profile coordinator: own/peer profile fields (picture, status, username). */
|
|
474
462
|
get profile() {
|
|
475
|
-
return this.profileCoordinator;
|
|
476
|
-
}
|
|
463
|
+
return this.deps.profileCoordinator;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Business coordinator: business profile, verified-name lookups. Reads
|
|
467
|
+
* work from any account; **writes (`editBusinessProfile`,
|
|
468
|
+
* `updateCoverPhoto`, `deleteCoverPhoto`) are business-only** and throw
|
|
469
|
+
* on regular accounts. See {@link WaBusinessCoordinator}.
|
|
470
|
+
*/
|
|
477
471
|
get business() {
|
|
478
|
-
return this.businessCoordinator;
|
|
472
|
+
return this.deps.businessCoordinator;
|
|
479
473
|
}
|
|
480
|
-
|
|
481
|
-
|
|
474
|
+
/** Bot coordinator: Meta-AI bot profiles, prompt/chunk decryption. */
|
|
475
|
+
get bot() {
|
|
476
|
+
return this.deps.botCoordinator;
|
|
482
477
|
}
|
|
478
|
+
/**
|
|
479
|
+
* Email coordinator: bind/unbind/verify email on the account.
|
|
480
|
+
* **Mobile-only** - every method throws unless the client is connected
|
|
481
|
+
* via `options.mobileTransport`. See {@link WaEmailCoordinator}.
|
|
482
|
+
*/
|
|
483
|
+
get email() {
|
|
484
|
+
return this.deps.emailCoordinator;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Unpairs this companion device by removing it server-side. Requires an
|
|
488
|
+
* authenticated session; throws when no `meJid` is present.
|
|
489
|
+
*
|
|
490
|
+
* **Does not** disconnect the socket or clear local stores by itself -
|
|
491
|
+
* the server initiates the close after accepting the IQ, which surfaces
|
|
492
|
+
* via a `connection` event with `isLogout: true`. That close handler is
|
|
493
|
+
* what wipes the persisted state, honoring `options.logoutStoreClear`.
|
|
494
|
+
* The {@link WaClient} instance is single-shot after logout: create a
|
|
495
|
+
* fresh one (with a fresh `sessionId` or pre-cleared store) to re-pair.
|
|
496
|
+
*/
|
|
483
497
|
async logout(reason = WA_LOGOUT_REASONS.USER_INITIATED) {
|
|
484
|
-
const meJid = this.authClient.getCurrentCredentials()?.meJid;
|
|
498
|
+
const meJid = this.deps.authClient.getCurrentCredentials()?.meJid;
|
|
485
499
|
if (!meJid) {
|
|
486
500
|
throw new Error('cannot logout: client is not authenticated');
|
|
487
501
|
}
|
|
@@ -493,201 +507,56 @@ export class WaClient extends EventEmitter {
|
|
|
493
507
|
});
|
|
494
508
|
assertIqResult(result, 'client.logout');
|
|
495
509
|
}
|
|
496
|
-
sendReceipt(input) {
|
|
497
|
-
return this.messageDispatch.sendReceipt(input);
|
|
498
|
-
}
|
|
499
|
-
flushAppStateMutations() {
|
|
500
|
-
return this.chatCoordinator.flushMutations();
|
|
501
|
-
}
|
|
502
|
-
flushWriteBehind(timeoutMs) {
|
|
503
|
-
return this.writeBehind.flush(timeoutMs);
|
|
504
|
-
}
|
|
505
|
-
async exportAppState() {
|
|
506
|
-
return this.appStateSync.exportState();
|
|
507
|
-
}
|
|
508
|
-
async syncAppState(options = {}) {
|
|
509
|
-
if (!this.connectionManager.isConnected()) {
|
|
510
|
-
throw new Error('client is not connected');
|
|
511
|
-
}
|
|
512
|
-
const syncResult = await this.executeAppStateSync(options);
|
|
513
|
-
const blockedCollections = this.getBlockedAppStateCollections(syncResult);
|
|
514
|
-
if (blockedCollections.length > 0) {
|
|
515
|
-
this.logger.warn('app-state sync has blocked collections', {
|
|
516
|
-
blockedCollections: blockedCollections.join(',')
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
this.emitChatEventsFromAppStateSyncResult(syncResult);
|
|
520
|
-
return syncResult;
|
|
521
|
-
}
|
|
522
|
-
async executeAppStateSync(options) {
|
|
523
|
-
return options.downloadExternalBlob
|
|
524
|
-
? this.appStateSync.sync(options)
|
|
525
|
-
: this.appStateSync.sync({
|
|
526
|
-
...options,
|
|
527
|
-
downloadExternalBlob: async (_collection, _kind, reference) => downloadExternalBlobReference(this.mediaTransfer, reference)
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
getBlockedAppStateCollections(syncResult) {
|
|
531
|
-
const blocked = [];
|
|
532
|
-
for (const entry of syncResult.collections) {
|
|
533
|
-
if (entry.state === WA_APP_STATE_COLLECTION_STATES.BLOCKED) {
|
|
534
|
-
blocked.push(entry.collection);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
return blocked;
|
|
538
|
-
}
|
|
539
|
-
emitChatEventsFromAppStateSyncResult(syncResult) {
|
|
540
|
-
const shouldEmitSnapshotMutations = this.options.chatEvents?.emitSnapshotMutations === true;
|
|
541
|
-
for (const collectionResult of syncResult.collections) {
|
|
542
|
-
const mutations = collectionResult.mutations ?? [];
|
|
543
|
-
const lastMutationIndexByKey = new Map();
|
|
544
|
-
for (let mutationIndex = 0; mutationIndex < mutations.length; mutationIndex += 1) {
|
|
545
|
-
const mutation = mutations[mutationIndex];
|
|
546
|
-
if (!shouldEmitSnapshotMutations && mutation.source === 'snapshot') {
|
|
547
|
-
continue;
|
|
548
|
-
}
|
|
549
|
-
lastMutationIndexByKey.set(`${mutation.collection}\u0001${mutation.index}`, mutationIndex);
|
|
550
|
-
}
|
|
551
|
-
for (let mutationIndex = 0; mutationIndex < mutations.length; mutationIndex += 1) {
|
|
552
|
-
const mutation = mutations[mutationIndex];
|
|
553
|
-
if (!shouldEmitSnapshotMutations && mutation.source === 'snapshot') {
|
|
554
|
-
continue;
|
|
555
|
-
}
|
|
556
|
-
const coalesceKey = `${mutation.collection}\u0001${mutation.index}`;
|
|
557
|
-
if (lastMutationIndexByKey.get(coalesceKey) !== mutationIndex) {
|
|
558
|
-
continue;
|
|
559
|
-
}
|
|
560
|
-
try {
|
|
561
|
-
this.handleNctSaltMutation(mutation);
|
|
562
|
-
const event = parseChatEventFromAppStateMutation(mutation);
|
|
563
|
-
if (!event) {
|
|
564
|
-
continue;
|
|
565
|
-
}
|
|
566
|
-
this.emit('chat_event', event);
|
|
567
|
-
}
|
|
568
|
-
catch (error) {
|
|
569
|
-
this.logger.debug('failed to parse chat event from app-state mutation', {
|
|
570
|
-
collection: mutation.collection,
|
|
571
|
-
source: mutation.source,
|
|
572
|
-
index: mutation.index,
|
|
573
|
-
message: toError(error).message
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
handleNctSaltMutation(mutation) {
|
|
580
|
-
const nctAction = mutation.value?.nctSaltSyncAction;
|
|
581
|
-
if (!nctAction) {
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
if (mutation.operation === 'set' && nctAction.salt) {
|
|
585
|
-
this.trustedContactToken.handleNctSaltSync(nctAction.salt).catch((err) => this.logger.warn('nct salt sync set failed', {
|
|
586
|
-
message: toError(err).message
|
|
587
|
-
}));
|
|
588
|
-
}
|
|
589
|
-
else if (mutation.operation === 'remove') {
|
|
590
|
-
this.trustedContactToken.handleNctSaltSync(null).catch((err) => this.logger.warn('nct salt sync remove failed', {
|
|
591
|
-
message: toError(err).message
|
|
592
|
-
}));
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
510
|
async clearStoredState() {
|
|
596
511
|
await this.pauseIncomingEventsAndWaitDrain();
|
|
597
512
|
const writeBehindDestroy = await this.writeBehind.destroy(this.options.writeBehind?.flushTimeoutMs);
|
|
598
513
|
if (writeBehindDestroy.remaining > 0) {
|
|
599
514
|
throw new Error(`clear stored state aborted: write-behind did not fully drain (remaining=${writeBehindDestroy.remaining})`);
|
|
600
515
|
}
|
|
601
|
-
const danglingReceipts = this.receiptQueue.take();
|
|
516
|
+
const danglingReceipts = this.deps.receiptQueue.take();
|
|
602
517
|
if (danglingReceipts.length > 0) {
|
|
603
518
|
this.logger.debug('cleared dangling receipts while clearing stored state', {
|
|
604
519
|
count: danglingReceipts.length
|
|
605
520
|
});
|
|
606
521
|
}
|
|
607
522
|
const s = this.options.logoutStoreClear;
|
|
608
|
-
const
|
|
523
|
+
const isMailbox = (key) => key === 'messages' || key === 'threads' || key === 'contacts';
|
|
524
|
+
const shouldClear = (key) => {
|
|
525
|
+
const explicit = s?.[key];
|
|
526
|
+
if (explicit !== undefined)
|
|
527
|
+
return explicit;
|
|
528
|
+
return !isMailbox(key);
|
|
529
|
+
};
|
|
609
530
|
if (shouldClear('auth'))
|
|
610
|
-
await this.authClient.clearStoredCredentials();
|
|
531
|
+
await this.deps.authClient.clearStoredCredentials();
|
|
611
532
|
if (shouldClear('appState'))
|
|
612
|
-
await this.
|
|
533
|
+
await this.stores.appState.clear();
|
|
613
534
|
if (shouldClear('contacts'))
|
|
614
|
-
await this.
|
|
535
|
+
await this.stores.contacts.clear();
|
|
615
536
|
if (shouldClear('messages'))
|
|
616
|
-
await this.
|
|
537
|
+
await this.stores.messages.clear();
|
|
617
538
|
if (shouldClear('messageSecret'))
|
|
618
|
-
await this.
|
|
619
|
-
if (shouldClear('
|
|
620
|
-
await this.
|
|
539
|
+
await this.stores.messageSecret.clear();
|
|
540
|
+
if (shouldClear('groupMetadata'))
|
|
541
|
+
await this.stores.groupMetadata.clear();
|
|
621
542
|
if (shouldClear('deviceList'))
|
|
622
|
-
await this.
|
|
543
|
+
await this.stores.deviceList.clear();
|
|
623
544
|
if (shouldClear('retry'))
|
|
624
|
-
await this.
|
|
545
|
+
await this.stores.retry.clear();
|
|
625
546
|
if (shouldClear('signal'))
|
|
626
|
-
await this.
|
|
547
|
+
await this.stores.signal.clear();
|
|
627
548
|
if (shouldClear('preKey'))
|
|
628
|
-
await this.
|
|
549
|
+
await this.stores.preKey.clear();
|
|
629
550
|
if (shouldClear('session'))
|
|
630
|
-
await this.
|
|
551
|
+
await this.stores.session.clear();
|
|
631
552
|
if (shouldClear('identity'))
|
|
632
|
-
await this.
|
|
553
|
+
await this.stores.identity.clear();
|
|
633
554
|
if (shouldClear('senderKey'))
|
|
634
|
-
await this.
|
|
555
|
+
await this.stores.senderKey.clear();
|
|
635
556
|
if (shouldClear('threads'))
|
|
636
|
-
await this.
|
|
557
|
+
await this.stores.threads.clear();
|
|
637
558
|
if (shouldClear('privacyToken'))
|
|
638
|
-
await this.
|
|
639
|
-
}
|
|
640
|
-
async tryDecryptAddon(event) {
|
|
641
|
-
const message = event.message;
|
|
642
|
-
if (!message)
|
|
643
|
-
return;
|
|
644
|
-
const addon = identifyEncryptedAddon(message);
|
|
645
|
-
if (!addon)
|
|
646
|
-
return;
|
|
647
|
-
const targetMessageId = addon.targetMessageKey.id;
|
|
648
|
-
if (!targetMessageId)
|
|
649
|
-
return;
|
|
650
|
-
const parentEntry = await resolveParentMessageSecret(targetMessageId, this.messageSecretStore, this.messageStore);
|
|
651
|
-
if (!parentEntry) {
|
|
652
|
-
this.logger.debug('addon parent message secret not found', {
|
|
653
|
-
id: event.stanzaId,
|
|
654
|
-
targetId: targetMessageId
|
|
655
|
-
});
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
const parentMsgOriginalSender = parentEntry.senderJid;
|
|
659
|
-
const modificationSender = event.senderJid ?? '';
|
|
660
|
-
const plaintext = await decryptAddonPayload({
|
|
661
|
-
messageSecret: parentEntry.secret,
|
|
662
|
-
stanzaId: targetMessageId,
|
|
663
|
-
parentMsgOriginalSender,
|
|
664
|
-
modificationSender,
|
|
665
|
-
modificationType: addon.modificationType,
|
|
666
|
-
ciphertext: addon.encPayload,
|
|
667
|
-
iv: addon.encIv,
|
|
668
|
-
additionalData: shouldUseAddonAdditionalData(addon.modificationType)
|
|
669
|
-
? buildAddonAdditionalData(targetMessageId, modificationSender)
|
|
670
|
-
: undefined
|
|
671
|
-
});
|
|
672
|
-
let decrypted = decodeAddonPlaintext(addon.kind, plaintext);
|
|
673
|
-
if (decrypted.kind === 'poll_vote' && decrypted.pollVote.selectedOptions) {
|
|
674
|
-
const names = await resolvePollOptionNames(decrypted.pollVote.selectedOptions, targetMessageId, this.messageStore);
|
|
675
|
-
if (names) {
|
|
676
|
-
decrypted = { ...decrypted, selectedOptionNames: names };
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
const addonEvent = {
|
|
680
|
-
rawNode: event.rawNode,
|
|
681
|
-
stanzaId: event.stanzaId,
|
|
682
|
-
chatJid: event.chatJid,
|
|
683
|
-
stanzaType: event.stanzaType,
|
|
684
|
-
kind: addon.kind,
|
|
685
|
-
targetMessageId,
|
|
686
|
-
senderJid: modificationSender,
|
|
687
|
-
decrypted,
|
|
688
|
-
raw: message
|
|
689
|
-
};
|
|
690
|
-
this.emit('message_addon', addonEvent);
|
|
559
|
+
await this.stores.privacyToken.clear();
|
|
691
560
|
}
|
|
692
561
|
tryEnterIncomingHandler() {
|
|
693
562
|
if (!this.acceptingIncomingEvents) {
|
|
@@ -731,6 +600,6 @@ export class WaClient extends EventEmitter {
|
|
|
731
600
|
}
|
|
732
601
|
handleError(error) {
|
|
733
602
|
this.logger.error('wa client error', { message: error.message });
|
|
734
|
-
this.emit('
|
|
603
|
+
this.emit('debug_client_error', { error });
|
|
735
604
|
}
|
|
736
605
|
}
|