Pular para o conteúdo principal
O zapo conecta-se como um dispositivo complementar (companion device) — exatamente como vincular o WhatsApp Web ou o Desktop. A primeira conexão pareia o dispositivo; depois disso, as credenciais armazenadas na sua store são reutilizadas automaticamente.

O fluxo de pareamento

O pareamento é conduzido inteiramente por eventos emitidos durante o connect(): Assim que auth_paired dispara, as credenciais são gravadas na store e reutilizadas em todo connect() subsequente — você não verá auth_qr novamente, a menos que a sessão seja desvinculada ou limpa.
Pareado. As credenciais agora vivem na sua store — reinicie o processo e o connect() retoma a sessão sem um novo QR.

Pareamento com um QR code

Este é o fluxo padrão. Renderize a string qr como uma imagem de QR e escaneie a partir de WhatsApp → Aparelhos conectados → Conectar um aparelho.
O QR rotaciona automaticamente; auth_qr dispara novamente com um valor novo a cada vez, então sempre renderize o mais recente.

Pareamento com um código

Prefere digitar um código de 8 caracteres no telefone em vez de escanear? Solicite um através de client.auth depois que a conexão estiver estabelecida. Escute o auth_pairing_required e então solicite o código para o número de telefone alvo (apenas dígitos, com código do país):
requestPairingCode(phoneNumber, shouldShowPushNotification?, customCode?) requer uma conexão ativa e retorna o código como uma string. No telefone, abra Aparelhos conectados → Conectar com número de telefone.

Linking com passkey (Shortcake)

Para algumas contas, o servidor do WhatsApp recusa o fluxo normal de QR / código de pareamento e exige uma assertion WebAuthn de passkey do authenticator do dono da conta antes de um companion conseguir linkar. O protocolo de fio por trás disso está documentado em detalhe em WhatsApp passkey & Shortcake linking; esta seção cobre como opt-in no lado do client. O gatilho é server-driven. Quando dispara, o zapo emite auth_passkey_required como aviso (hasSigner diz se o handshake de fato prossegue) e depois roda o handshake Shortcake internamente — desde que você tenha configurado um signer.

O signer

Defina signPasskeyAssertion em WaClientOptions. O zapo te entrega o request options WebAuthn bruto do servidor, e você devolve a assertion + credential id:
A source da credencial fica fora da lib — um authenticator real (hardware/OS), um virtual, ou um relay pra outro processo — o zapo nunca toca material de passkey diretamente.
Não há bypass headless. Sem um signer que produza uma assertion que o próprio authenticator do dono da conta assinaria (veja a página de reverse-engineering pra entender por que a parede segura), o link não completa numa conta com passkey. Quando hasSigner é false no auth_passkey_required, a lib ackeia o prologue mas o handshake para — mostre um prompt de UI dizendo que uma passkey é necessária, e configure um signer pra próxima tentativa ou caia num device que consiga completar.
auth_paired ainda dispara no sucesso — o handshake Shortcake é só um passo adicional encaixado no fluxo normal de pareamento (normalmente logo após pair-device ou um companion_finish de código). Nenhum evento “pareado” novo é introduzido.

Credenciais

Após o pareamento, as credenciais atuais ficam disponíveis de forma síncrona:
WaAuthCredentials contém as chaves secretas do dispositivo. Está marcado como @sensitive por um motivo: qualquer coisa que consiga ler isso pode se passar pelo dispositivo. Se você persistir essas credenciais fora da store embutida, criptografe-as em repouso.

Fazendo logout

O logout() desvincula o dispositivo complementar no servidor (ele remove este dispositivo dos aparelhos conectados da conta). Requer uma sessão autenticada:
Por padrão, isso também limpa o estado armazenado. Você pode controlar exatamente quais domínios da store são apagados no logout através da opção logoutStoreClear — veja Configuração.

Disconnect vs. logout

Use disconnect() para um encerramento gracioso que você pretende retomar; use logout() para desvincular permanentemente.

A seguir

Stores

Onde as credenciais e o estado do Signal são persistidos.

Reconexão

Trate o connection: close e reconecte.
Última modificação em 2 de julho de 2026