Esta página vai mais fundo que a visão geral da arquitetura — entrando nos subsistemas e fluxos de dados dentro doDocumentation Index
Fetch the complete documentation index at: https://zapo.to/llms.txt
Use this file to discover all available pages before exploring further.
zapo. É voltada para contribuidores e para qualquer pessoa depurando no nível do protocolo. Para o protocolo em si, veja O protocolo do WhatsApp.
Mapa de módulos
src
client
transport
signal
crypto
message
appstate
store
auth
media
retry
protocol
infra
util
| Diretório | Responsabilidade |
|---|---|
src/client/ | Orquestração do client, coordinators, ciclo de vida da conexão, roteamento de eventos. |
src/transport/ | Socket, handshake Noise, codec de binary node, orquestração de node. |
src/signal/ | Sessões Signal, ratchet (1:1), sender keys (grupos), geração de chaves. |
src/crypto/ | Primitivas: AES-GCM/CBC/CTR, SHA, HMAC, HKDF, Curve25519/Ed25519. |
src/message/ | Pipeline de build/encode de saída + parse/decrypt de entrada. |
src/appstate/ | Engine de sincronização de app-state (mutations, snapshots, crypto, MACs). |
src/store/ | Contratos de store + providers em memória; fronteira de persistência. |
src/auth/ | Fluxos de pareamento/QR/credenciais. |
src/media/ | Upload/download/criptografia de mídia. |
src/retry/ | Rastreamento de retry para envios/descriptografias que falharam. |
src/protocol/ | Constantes (node tags, tipos de IQ, xmlns) e helpers de JID. |
src/infra/ | Logging, coleções limitadas, locks, utilitários de performance. |
src/util/ | Helpers de byte/async/primitivas. |
A stack
As stores atravessam todas as camadas; o connection manager e o keep-alive ficam ao lado do transporte.Ciclo de vida da conexão
OWaConnectionManager (em src/client/connection/) conduz o connect/disconnect:
- O
WaCommsabre o socket (WaWebSocketouWaMobileTcpSocket) e executa o handshake Noise (src/transport/noise/), autenticando o servidor e derivando as chaves de sessão. - O
WaNodeTransport.bindComms()anexa o codec binário ao socket criptografado. - O
WaKeepAlive(src/transport/keepalive/) inicia ping IQs periódicos para detectar um socket morto e estimar o desvio do relógio do servidor. - O client executa tarefas passivas pós-conexão (history sync, drenagem de mensagens offline) e emite
connection.
zapo deliberadamente não reconecta automaticamente — essa política pertence ao seu app (veja Reconexão).
Pipeline de mensagem de saída
client.message.send → WaMessageDispatchCoordinator:
- Build — o conteúdo (a send union) é construído em um
Proto.IMessage, fazendo upload da mídia se necessário. - Resolver dispositivos — a lista de dispositivos do destinatário é resolvida (fanout,
src/client/messaging/), buscando prekey bundles para dispositivos sem sessão. - Criptografar — por dispositivo: 1:1 via o ratchet Signal (
SignalProtocol→msg/pkmsg), grupos viaSenderKeyManager(skmsg) mais a distribuição de sender-key aos membros que precisam. Seus próprios dispositivos recebem umdeviceSentMessage. - Montar —
src/transport/node/builders/message.tsenvolve os participantes criptografados em uma única stanza<message>com a identidade do dispositivo, o hash de participantes e oaddressing_mode(pn/lid). - Enviar e ack —
WaNodeOrchestrator.sendNode()codifica e escreve; o coordinator aguarda o<ack>do servidor e retorna umWaMessagePublishResult. Falhas são reenviadas conforme as tentativas/backoff configurados.
Pipeline de entrada
- O
WaCommsdescriptografa um frame Noise; oWaNodeTransport.dispatchIncomingFrame()o decodifica em umBinaryNode. - O
WaIncomingNodeCoordinatorroteia por tag/type para o handler certo (src/client/events/). - Para mensagens, o corpo é descriptografado (ratchet Signal ou sender key), os wrappers de device-sent são desembrulhados e o padding PKCS7 é removido (
src/message/primitives/incoming.ts). - O resultado é normalizado em um payload tipado e emitido (
message,receipt,group, …). Um filtro de stanza pode descartar stanzas antes que os handlers rodem; o coordinator ainda dá ack emmessage/receipt/notificationpara que o servidor pare de reentregar.
Engine de app-state
OWaAppStateSyncClient (src/appstate/) reconcilia as configurações por conta:
- Uma sincronização envia a última versão conhecida por coleção; o servidor retorna patches (ou um snapshot completo).
- O índice e o valor de cada mutation são verificados por MAC e o valor é descriptografado (
WaAppStateCrypto: AES-CBC + HMAC, chaves por coleção derivadas via HKDF). - As mutations verificadas são aplicadas à store
appStatee expostas como eventosmutation. - Mudanças de saída de
client.chatsão codificadas como mutations, agrupadas em lote e descarregadas.
Camada de store
A store é dividida em contratos (src/store/contracts/ — a interface que cada domínio implementa) e providers (o provider memory embutido, mais os pacotes de backend externos). É isso que permite misturar backends por domínio em createStore.
Duas fronteiras de performance ficam aqui:
- Write-behind — mensagens/threads/contatos de entrada são agrupados em lote e descarregados de forma assíncrona (ajustado via
writeBehind) para que o caminho quente não fique bloqueado no banco de dados. - Caches limitados —
retry,groupMetadata,deviceListemessageSecretsão limitados em memória com TTLs para evitar crescimento ilimitado em processos de longa duração.
Confiabilidade
- Retry tracker (
src/retry/) — mapeia ids de mensagens que falharam para metadados de retry e impõe limites de tentativa/backoff. - Fila de recibos (
WaReceiptQueue) — armazena recibos que falham ao enviar durante uma desconexão, reproduzindo-os na reconexão (limitada para evitar crescimento). - Keep-alive — ping IQs periódicos detectam sockets mortos e medem o desvio do relógio; ele pula o ping enquanto uma query já está em andamento.
Composição do client
OWaClientFactory é a raiz de composição: ele constrói o auth client, o connection manager, o transporte + orchestrator, o keep-alive, os managers de Signal/sender-key, o app-state client, as stores e cada coordinator de funcionalidade, e então os injeta no WaClient. O WaClient em si permanece enxuto — um EventEmitter que expõe os getters de coordinator e o ciclo de vida da conexão.
Crypto
Osrc/crypto/ fornece as primitivas:
- Simétrica — AES-GCM (Noise, valores de app-state), AES-CBC (sender keys), AES-CTR (mídia).
- Hash/MAC/KDF — SHA-1/256/512, HMAC, HKDF.
- Curva elíptica — Curve25519 (X25519 DH) e assinaturas Ed25519/XEdDSA.
Convenções
Estas valem em todo o código-fonte e explicam boa parte do formato da API:Uint8Arrayem todo lugar para dados binários;Bufferé evitado. Zero-copy (subarray, byte views) nos caminhos críticos.- Estruturas em memória limitadas para evitar crescimento ilimitado.
- Apenas named exports; sem default exports.
- Sem enums — as constantes usam
Object.freeze({ … } as const), expostas como os objetosWA_*. - Path aliases (
@client,@crypto,@store, …) em vez de imports relativos../.
