
Seal v0.2.3
Chat peer-to-peer com criptografia de ponta a ponta. Sem caixa de entrada. Sem conta para recuperar. Ninguém está ouvindo — nem mesmo nós.
Seal
Chat peer-to-peer com criptografia de ponta a ponta.
Sem caixa de entrada. Sem conta para recuperar. Ninguém está ouvindo — nem nós.
As mensagens viajam diretamente entre pares pela libp2p e são criptografadas com os protocolos Olm/Megolm no estilo Signal (via vodozemac) antes de saírem do seu dispositivo. O único servidor envolvido é um pequeno diretório que ajuda os pares a encontrarem o endereço atual uns dos outros. Ele nunca vê o conteúdo das mensagens e pode ser apagado com um único comando.
Consulte docs/THREAT_MODEL.md e
docs/SECURITY.md para saber o que é realmente protegido
e como.
Conteúdo
- Capturas de tela
- Recursos
- Como funciona
- Estrutura do projeto
- 1. Pré-requisitos
- 2. Compilação
- 3. Executando em modo de desenvolvimento
- 4. Testes
- 5. Configuração do backend (servidor de diretório)
- 6. Usando o aplicativo
Capturas de tela
Primeira execução — escolha um nome; nada mais para configurar.
Conversas — a barra de grupos, a lista de contatos e um painel de chat com criptografia de ponta a ponta.
Configurações — sensibilidade do microfone, push-to-talk, iniciar no login, alcance de rede.
Recursos
- Criptografia de ponta a ponta, sempre — toda mensagem é lacrada com Olm (1:1) ou Megolm (grupos) antes de sair do seu dispositivo, usando o esquema estilo Double Ratchet do vodozemac: cada mensagem tem sua própria chave.
- Sem caixa de entrada, nunca — as mensagens viajam por uma conexão direta ponto a ponto (libp2p: QUIC/TCP + Noise, com relay e hole punching para NATs). Se o destinatário estiver offline, a mensagem aguarda localmente e tenta novamente — ela nunca é enfileirada na infraestrutura de terceiros.
- Um diretório, não um banco de dados — o único servidor envolvido
(
crates/directory-server) mapeia um ID de usuário para um endereço de rede atual e nada mais. Ele é estruturalmente incapaz de ler o conteúdo das mensagens: seuCargo.tomlnem sequer depende das crates que saberiam como fazer. - Várias contas, um dispositivo — identidades totalmente separadas (chaves, contatos, mensagens) entre as quais você pode alternar sem reiniciar.
- Grupos com mudanças reais de membros — canais de texto e voz por grupo; remover alguém rotaciona a chave do grupo para que essa pessoa não consiga ler nada enviado depois.
- Voz, integrada — push-to-talk com um atalho global do sistema (funciona em qualquer aplicativo, não apenas no Seal), sensibilidade de microfone ajustável e um alterador de voz opcional.
- Anexos sem os metadados — os dados EXIF (localização GPS, informações de câmera/dispositivo) são removidos das imagens antes de serem enviados, ativado por padrão.
- Um botão de pânico de verdade — Configurações → Dados e Privacidade exclui instantânea e irreversivelmente todas as chaves, contatos e mensagens deste dispositivo, com zero efeito sobre qualquer pessoa com quem você conversou.
- Iniciar no login, se você quiser — ativado por padrão, a um interruptor de distância nas Configurações.
- Uma base de código, três plataformas — janelas nativas em macOS, Windows e Linux, via Tauri.
Como funciona
Há dois tipos de identidade neste aplicativo, e eles são mantidos deliberadamente separados:
- Sua identidade de chat é um par de chaves Ed25519/Curve25519 gerado localmente
pelo vodozemac na primeira vez que você
abre o aplicativo (
identity::Identity). Seu "ID de usuário" público é apenas a impressão digital (fingerprint) dessa chave (wire_proto::user_id_from_ed25519). Ele não pode ser emitido ou revogado por nenhum servidor, porque nenhum servidor participa da sua criação. - Sua identidade de rede é um par de chaves libp2p separado (
PeerId), usado apenas na camada de transporte. Ela pode mudar entre reinicializações sem afetar em nada sua identidade de chat; as duas estão ligadas apenas por um registro de presença que você mesmo assina.
Encontrar alguém e de fato conversar com essa pessoa são duas etapas diferentes:``` ┌────────────────────────┐ │ directory server │ │ (axum + one SQLite │ │ file: users, │ │ presence, group │ │ rosters. Never │ │ message content.) │ └─────────┬───────────────┘ 1. "where is bob │ 2. "here's my current right now?" │ address" (signed, │ expires in minutes) ┌─────────┴───────────────┐ ▼ ▼ ┌───────┐ 3. direct libp2p ┌───────┐ │ alice │◄──── connection ────►│ bob │ └───────┘ (Noise + Olm/ └───────┘ Megolm encrypted)
1. Alice procura Bob no diretório pelo ID de usuário dele. Isso retorna as
chaves públicas dele e o último endereço de rede anunciado. Isso é tudo
o que o diretório contém: chaves públicas, nomes de exibição, listas de
associação a grupos e anúncios de endereço de curta duração
(`crates/directory-server`).
2. Alice conecta-se diretamente a Bob via libp2p (QUIC ou TCP+Noise, com relay +
hole-punching para peers atrás de NATs; veja `crates/net`). O diretório fica
completamente fora de cena a partir daqui.
3. A mensagem em si é criptografada com **Olm** para um chat 1:1, ou
**Megolm** para um grupo (`crates/crypto-session`), um esquema no estilo
Double-Ratchet em que cada mensagem recebe sua própria chave, antes de ser
colocada nessa conexão libp2p. Não existe caixa de entrada no servidor: se Bob
estiver offline, a mensagem aguarda localmente e é tentada novamente, não
sendo armazenada na infraestrutura de ninguém.
Tudo o que está acima é orquestrado pelo `AppService` de `crates/core`, que é
o que o backend Rust do aplicativo Tauri (`apps/desktop/src-tauri`) realmente
chama; a UI nunca fala diretamente com a rede.
## Estrutura do projeto```
crates/
wire-proto shared signed-request types for the directory API
identity vodozemac identity, OS-keychain key management
storage local encrypted store (contacts, messages, groups)
net libp2p transport + directory HTTP client
crypto-session Olm (1:1) / Megolm (group) session management
core orchestrates the above into `AppService` / `ChatNode`
directory-server the one server component (axum + SQLite)
apps/desktop the Tauri + React app
scripts/ build + backend-deployment scripts (§2, §5)
1. Pré-requisitos
Você precisa de Rust e Node.js em todas as plataformas, além de uma
toolchain específica da plataforma que o Tauri requer para compilar uma janela
nativa. storage e directory-server também compilam o SQLite a partir do
código-fonte, o que requer um compilador C simples (nenhuma OpenSSL ou outra
biblioteca criptográfica nativa é necessária em qualquer lugar deste projeto).
Comum a todas as plataformas:
- Rust (canal estável; instale via
rustup, não pelo gerenciador de pacotes do seu sistema operacional) - Node.js 20+ e npm
macOS
```sh xcode-select --install ``` É só isso. As Xcode Command Line Tools fornecem tanto o compilador C quanto os frameworks de que o backend macOS do Tauri (baseado em WKWebView) precisa.Linux
Instale um compilador C, pkg-config e os pacotes de desenvolvimento
WebKitGTK/AppIndicator com os quais o backend Linux do Tauri faz link.
Debian/Ubuntu:```sh
sudo apt update
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev pkg-config
Fedora:```sh
sudo dnf install webkit2gtk4.1-devel openssl-devel curl wget file \
libappindicator-gtk3-devel librsvg2-devel pkgconf-pkg-config
sudo dnf group install "C Development Tools and Libraries"
Arch:```sh
sudo pacman -S --needed webkit2gtk-4.1 base-devel curl wget file openssl
appmenu-gtk-module libappindicator-gtk3 librsvg pkgconf
(Os nomes dos pacotes mudam entre versões do Tauri: se uma compilação falhar procurando por um arquivo `.pc` ausente, consulte os
[pré-requisitos atuais do Tauri para Linux](https://v2.tauri.app/start/prerequisites/)
para a sua distribuição.)
</details>
<details>
<summary><strong>Windows</strong></summary>
1. Instale as **Ferramentas de Build do Microsoft C++** (Visual Studio Installer →
carga de trabalho "Desenvolvimento para desktop com C++"), necessárias tanto para o shell nativo do Tauri
quanto para compilar o SQLite embutido.
2. Instale a toolchain Rust **MSVC**: `rustup default stable-msvc`.
3. **WebView2**: já está presente no Windows 11 e na maioria das instalações atualizadas do Windows
10; se não estiver, o build do Tauri solicitará que você instale o
runtime Evergreen.
</details>
---
## 2. Compilação
Na raiz do repositório:```sh
# Rust workspace (backend crates + the directory server)
cargo build --workspace --release
# Frontend + the actual desktop app bundle (installer/.app/.exe)
cd apps/desktop
npm install
npm run tauri build
npm run tauri build gera um instalador nativo da plataforma em
target/release/bundle/ na raiz do repositório (este é um workspace do Cargo, então todos
os crates, incluindo o app Tauri, compartilham um diretório target/ de nível superior).
A compilação cruzada (por exemplo, gerar o instalador do Windows a partir do macOS) não está
configurada: compile em cada plataforma de destino ou use o fluxo de trabalho do GitHub Actions do Tauri
se você quiser releases compilados por CI.
Ou use os scripts
scripts/ tem um script de build por plataforma/saída, cada um independentemente
executável e cada um verificado para realmente produzir um artefato funcional:
| Script | Produz |
|---|---|
scripts/build-mac-dmg.sh | instalador .dmg do macOS |
scripts/build-mac-app.sh | pacote .app bruto do macOS, sem instalador |
scripts/build-linux.sh | Linux .AppImage + .deb |
scripts/build-windows.ps1 | Windows .msi + .exe (NSIS) |
Cada um apenas encapsula npm run tauri build --bundles <...> com as flags corretas
e verificação de plataforma; execute você mesmo o comando direto se quiser uma
combinação de bundle diferente (npx tauri build --help a partir de apps/desktop).
scripts/release.sh vX.Y.Z atualiza a versão em todos os lugares necessários
e marca o commit — veja docs/RELEASING.md. É executado em
macOS e Linux; não faz commit nem push.
Incorporando sua própria rede "Seal"
A tela de escolha do servidor (§3) sempre mostra três opções: Seal (sua própria rede oficial), Servidor personalizado e um pequeno Servidor de teste local link na parte inferior. "Seal" fica desabilitado (esmaecido, com "Ainda não configurado neste build") até você incorporar uma URL no momento do build:```sh SEAL_DEFAULT_DIRECTORY_URL=https://directory.example.com npm run tauri build
Depois de subir seu próprio servidor (§5) e apontar um domínio real para
ele, configure isso e recompile: toda cópia que você distribuir a partir de então mostra
"Seal" como uma opção real e selecionável usando essa URL, sem tocar em nenhum
outro código. Deixe sem configurar para builds comuns/de desenvolvimento: não há um servidor
oficial hospedado por este repositório, então "Seal" permanece desabilitado e as pessoas recorrem a
um servidor personalizado ou ao local, em vez de o aplicativo apontar silenciosamente para
um domínio placeholder que não está realmente executando nada.
---
## 3. Executando em modo de desenvolvimento```sh
cd apps/desktop
npm install
npm run tauri dev
Isto inicia o servidor de desenvolvimento Vite, compila o backend Rust em modo de depuração e abre uma janela nativa com hot-reload no frontend. A primeira compilação compila toda a árvore de dependências e leva alguns minutos; as execuções seguintes são rápidas.
Escolhendo um servidor (primeira execução)
Na primeira vez que você iniciar, o Seal pergunta qual servidor de diretório usar, nesta ordem:
- Seal: a rede oficial, se esta compilação tiver uma incorporada (ver §2). Desabilitada até que tenha; este repositório não vem apontando para um domínio provisório.
- Servidor personalizado: o de qualquer pessoa, incluindo o seu (§5).
- Servidor de teste local: um link pequeno e deliberadamente menos destacado na
parte inferior. Inicia o servidor embutido do próprio aplicativo (vincula
127.0.0.1:47100/47101, dados no diretório de dados de aplicativos do seu sistema operacional), adequado para experimentar o Seal ou testar instâncias em uma única máquina, não uma implantação real. Se uma segunda instância descobrir que essas portas já estão ocupadas, ela apenas reutiliza o servidor da primeira instância em vez de iniciar outro, que é o que permite que duas instâncias na mesma máquina se encontrem. Isto é o que é selecionado automaticamente se "Seal" não estiver configurado e você não escolher mais nada.
A escolha é salva (server.json ao lado dos outros dados locais do aplicativo) e
reutilizada silenciosamente em todos os lançamentos posteriores; altere-a em Configurações → Servidor de
diretório, que terá efeito na próxima vez que você iniciar o aplicativo, em vez de
tentar trocar a quente uma conexão em execução. Para uso com scripts/desenvolvimento, uma
variável de ambiente ignora o prompt completamente:```sh
P2P_CHAT_DIRECTORY_URL=https://directory.example.com npm run tauri dev
### Executando duas instâncias localmente (para realmente testar mensagens)
Cada instância precisa de sua própria identidade. O Seal suporta múltiplas contas
nativamente (Configurações → Contas neste dispositivo), mas para dois *processos
separados* na mesma máquina, `P2P_CHAT_PROFILE` é o caminho mais rápido: ele
cria automaticamente (primeira vez) ou retoma automaticamente (todas as vezes depois) uma conta
com esse nome, de forma não interativa, pulando completamente o seletor de contas:```sh
# terminal 1
P2P_CHAT_PROFILE=alice npm run tauri dev
# terminal 2
P2P_CHAT_PROFILE=bob npm run tauri dev
A escolha do servidor (server.json) e a lista de contas (accounts.json)
são compartilhadas entre os processos em uma mesma máquina, não por perfil. A
primeira instância que você iniciar escolhe o servidor, e todos os perfis seguintes
(incluindo bob aqui) o reutilizam silenciosamente. Ambas as janelas terminam no
mesmo servidor de diretório incorporado, então vocês podem adicionar um ao outro como contatos por ID
e trocar mensagens entre elas.
O servidor de desenvolvimento do Vite precisa de uma porta real e fixa para o webview do Tauri apontar,
o que normalmente significa que apenas um npm run tauri dev pode ser executado por vez — a
segunda instância encontraria a porta 1420 já ocupada e falharia imediatamente.
npm run tauri é, na verdade, um pequeno wrapper (apps/desktop/scripts/tauri.mjs)
que escolhe a próxima porta livre (1421, 1422, …) para cada instância após a
primeira e a conecta automaticamente, então executar os dois comandos acima
em dois terminais simplesmente funciona; você não precisa fazer nada de diferente. Ele
só altera o comportamento para dev — npm run tauri build e todo o resto
passa direto para a CLI real.
Testando contra uma build real (não modo dev)```sh
./scripts/run-two-mac-instances.sh # profiles: alice, bob ./scripts/run-two-mac-instances.sh carol dave
Mesma ideia de acima, mas inicia o aplicativo realmente compilado (saída de `build-mac-app.sh` /
`build-mac-dmg.sh`, ou uma cópia instalada em `/Applications`) duas vezes
com diferentes `P2P_CHAT_PROFILE`s em vez de `npm run tauri dev`, mais próximo
do que um usuário real executa. Mostra os PIDs e como interromper ambos.
### Depuração
- **Logs Rust**: defina `RUST_LOG` antes de iniciar, ex.:
`RUST_LOG=debug npm run tauri dev` (ou `RUST_LOG=p2p_core=debug,net=debug`
para restringir). Os campos registrados são limitados a metadados (IDs de
peer/grupo/usuário, tipos de erro); veja [`docs/SECURITY.md`](https://github.com/emn4tor/seal/blob/HEAD/docs/SECURITY.md) para saber por que
é seguro deixá-los detalhados.
- **Frontend**: a janela de desenvolvimento é um webview real; clique com o botão direito → Inspecionar
Elemento (ou abra as ferramentas de desenvolvedor) funciona como um navegador normal.
- **Crates de backend isoladamente**: cada crate tem sua própria suíte de testes que você pode
executar e iterar sem tocar na interface; veja §4.
- **Um servidor de diretório autônomo**, em vez do embutido: veja §5.
---
## 4. Testes```sh
# everything
cargo test --workspace
# one crate, e.g. the full backend-to-backend flow a Tauri command would trigger
cargo test -p p2p-core --test app_service
# lint + format check (what CI runs)
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
# dependency vulnerability scan
cargo install cargo-audit --locked # once
cargo audit
# frontend type-check + build
cd apps/desktop && npm run build
5. Configuração do backend (servidor de diretório)
Recapitulando o que isso realmente é, já que é fácil imaginar demais: um axum
processo, um arquivo SQLite, três tipos de registro (chaves públicas,
anúncios de presença de curta duração, listas de grupo), todas as escritas assinadas pela
própria chave de identidade do chamador. Ele nunca está no caminho de uma mensagem. Veja
docs/THREAT_MODEL.md para entender por que isso é verdade
estruturalmente, não apenas por política: o Cargo.toml do directory-server não
depende nem mesmo dos crates que sabem ler o conteúdo das mensagens.
Caminho mais rápido: o script de configuração```sh
sudo ./scripts/setup-backend.sh
Interativo, apenas Linux + systemd (veja o cabeçalho do script para saber o porquê). Ele
pergunta em qual família de distro você está (Debian/Ubuntu, Fedora/RHEL/Rocky/Alma,
Arch/Manjaro ou openSUSE, pré-preenchida com uma suposição de `/etc/os-release`,
então normalmente é só uma tecla para confirmar) e instala os pré-requisitos
de compilação dessa distro com uma função dedicada por família, oferece instalar o Rust
via `rustup` se estiver faltando, compila o binário de release, cria um usuário
de sistema dedicado, gera um token de administrador, pergunta se você quer que ele
configure um domínio com HTTPS automático via [Caddy](https://caddyserver.com)
(instalando o próprio Caddy, por distro, recorrendo ao binário estático oficial
do Caddy se o pacote da distro não estiver disponível), ou apenas fazer bind
em loopback/HTTP simples se você preferir expô-lo você mesmo, depois grava e
ativa o serviço systemd. Seguro para reexecutar.
Tudo abaixo é o que ele realmente faz, se você preferir fazer manualmente
ou entender antes de executá-lo.
### macOS: um servidor de teste rápido na LAN```sh
./scripts/run-mac-test-server.sh
Não é para hospedagem real: para testar o aplicativo em dois dispositivos na mesma
rede (ex.: seu Mac + outra máquina, ou duas pessoas no mesmo Wi-Fi)
sem configurar domínio, TLS ou systemd (que não existe no macOS
de qualquer forma). Ele compila o binário de release, gera um token de administrador (reutilizado em
execuções posteriores), vincula a API pública a todas as interfaces e imprime a URL a
usar: o IP LAN real do seu Mac (via ipconfig getifaddr), não apenas
127.0.0.1, para que outros dispositivos também possam alcançá-lo. A porta de administração permanece em
somente loopback. Executa em primeiro plano; Ctrl-C interrompe. Os dados ficam em
~/.seal-test-server.
Execução local rápida```sh
DIRECTORY_DB_PATH=/var/lib/seal-directory/directory.sqlite3
DIRECTORY_PUBLIC_ADDR=0.0.0.0:8080
DIRECTORY_ADMIN_ADDR=127.0.0.1:8090
DIRECTORY_ADMIN_TOKEN=$(openssl rand -hex 32)
cargo run --release -p directory-server --bin directory-server
| Variável | Obrigatório | Significado |
|---|---|---|
| `DIRECTORY_DB_PATH` | não (padrão `directory.sqlite3`, diretório de trabalho atual) | Onde o arquivo SQLite único fica. O diretório pai deve existir. |
| `DIRECTORY_PUBLIC_ADDR` | não (padrão `0.0.0.0:8080`) | A API de rendezvous com a qual os apps falam. Pode ser exposta publicamente. |
| `DIRECTORY_ADMIN_ADDR` | não (padrão `127.0.0.1:8090`) | O endpoint de purga. Mantenha-o fora da internet pública; veja abaixo. |
| `DIRECTORY_ADMIN_TOKEN` | **sim** | Token Bearer para a API de administração. O processo se recusa a iniciar sem um. Gere com `openssl rand -hex 32` ou similar; não o reutilize em nenhum outro lugar. |
O processo registra em log quais endereços ele vinculou na inicialização e avisa alto se
`DIRECTORY_ADMIN_ADDR` não for loopback.
### Apontando o aplicativo para ele
Três maneiras, na ordem em que você normalmente as usaria:
1. **Tela da primeira execução**: escolha "Custom server" e digite a URL. Veja §3.
2. **Configurações → Directory server**: altere depois; tem efeito no próximo
reinício.
3. **`P2P_CHAT_DIRECTORY_URL`**, definida antes de iniciar: pula a pergunta
completamente e substitui o que foi salvo, útil para execuções de desenvolvimento/script: ```sh
P2P_CHAT_DIRECTORY_URL=https://directory.example.com npm run tauri dev
Todos os que querem encontrar-se uns aos outros precisam de apontar para a mesma instância de diretório; é assim que se procuram uns aos outros em primeiro lugar.
Executá-lo como um serviço real (systemd)
Mostrar a unit do systemd + notas
```ini # /etc/systemd/system/seal-directory.service [Unit] Description=Seal directory server After=network.target[Service] Type=simple User=seal-directory Group=seal-directory Environment=DIRECTORY_DB_PATH=/var/lib/seal-directory/directory.sqlite3 Environment=DIRECTORY_PUBLIC_ADDR=127.0.0.1:8080 Environment=DIRECTORY_ADMIN_ADDR=127.0.0.1:8090 EnvironmentFile=/etc/seal-directory/admin-token.env ; DIRECTORY_ADMIN_TOKEN=... ExecStart=/usr/local/bin/directory-server Restart=on-failure
Sandboxing: this process needs almost nothing
ProtectSystem=strict ProtectHome=true PrivateTmp=true NoNewPrivileges=true ReadWritePaths=/var/lib/seal-directory
[Install] WantedBy=multi-user.target
Notas:
- `DIRECTORY_PUBLIC_ADDR` está vinculado a **loopback** aqui de propósito; coloque um
proxy reverso na frente para TLS (abaixo) em vez de expor o axum diretamente
à internet.
- Crie o usuário/grupo de sistema `seal-directory` e
`/var/lib/seal-directory` primeiro (`useradd --system --no-create-home
seal-directory && install -d -o seal-directory -g seal-directory
/var/lib/seal-directory`) e copie o binário `directory-server` compilado
(de `target/release/`) para `/usr/local/bin/`.
- Coloque o token de administrador em um `EnvironmentFile` legível apenas por root, não diretamente
no arquivo de unidade (arquivos de unidade geralmente são legíveis por todos).
</details>
### TLS através de um proxy reverso
<details>
<summary>Mostrar a configuração do Caddy / nginx</summary>
[Caddy](https://caddyserver.com) fornece HTTPS automático com o mínimo de
configuração:```
# /etc/caddy/Caddyfile
directory.example.com {
reverse_proxy 127.0.0.1:8080
}
caddy run (ou systemctl enable --now caddy) trata da emissão/renovação de certificados por conta própria. Se preferir usar o nginx, finalize o TLS nele e use proxy_pass http://127.0.0.1:8080;, já que o aplicativo só precisa de HTTP simples do ponto de vista do proxy.
Em relação ao firewall: apenas a porta pública precisa estar acessível de fora (8080 nos exemplos acima, atrás da 443 via proxy). A porta administrativa nunca deve estar acessível de fora; acesse-a via encaminhamento de porta SSH (ssh -L 8090:127.0.0.1:8090 seu-servidor) quando precisar executar uma purga remotamente.
Purgando```sh
cargo run --release -p directory-server --bin directory-admin --
--admin-url http://127.0.0.1:8090 --token "$DIRECTORY_ADMIN_TOKEN" purge
Isto elimina o ficheiro SQLite e recria um esquema vazio: não há instruções
`DELETE`, nem estado parcial. É seguro executar sem avisar ninguém primeiro:
cada registo nele é um cache de dados que cada cliente já possui localmente
(o seu próprio registo, presença e quaisquer listas de grupos de que seja
membro), pelo que os clientes apenas o voltam a preencher momentos após a
sua próxima ação. Não há deliberadamente nenhuma política de cópias de
segurança para esta base de dados; consulte
[`docs/SECURITY.md`](https://github.com/emn4tor/seal/blob/HEAD/docs/SECURITY.md) para saber por que razão manter uma
comprometeria todo o propósito.
---
## 6. Usar a aplicação
1. **Primeiro arranque, primeira pergunta**: qual servidor de diretório usar (§3).
O padrão é o que estiver incorporado na compilação que você está a executar (um servidor
de teste local, a menos que quem o compilou tenha configurado um oficial); escolha
"Servidor personalizado" para apontar para um que você ou alguém em quem confie hospede.
2. **Escolha um nome de exibição.** Isto gera um par de chaves privadas no seu dispositivo
(nada para lembrar e nada recuperável se perdido: isso é deliberado) e orienta-o através
de uma breve explicação na aplicação sobre como a encriptação realmente funciona. Pode
repeti-la em qualquer altura a partir das Definições. Cada arranque posterior volta a
entrar diretamente, sem qualquer pedido; isto só acontece uma vez por conta. Adicione
mais contas (identidades totalmente separadas) a partir de Definições → Contas neste
dispositivo e alterne entre elas sem reiniciar.
3. **Adicionar alguém**: clique em **+** ao lado de "Mensagens diretas" e introduza o ID da pessoa
(encontrado nas Definições → A Minha Identidade). Não há diretório para navegar, de propósito;
a ligação é feita da mesma forma que se partilharia um número de telefone.
4. **Envie-lhes uma mensagem**: escolha o nome da pessoa na lista e escreva. A primeira
mensagem para alguém estabelece automaticamente uma sessão encriptada.
5. **Iniciar um grupo**: clique em **+** na barra de ícones, dê-lhe um nome e convide pessoas
pelo ID da mesma forma. Remover alguém roda a chave do grupo para que essa pessoa não
consiga ler nada enviado posteriormente.
6. **Eliminar tudo**: Definições → Dados e Privacidade. Isto é instantâneo, apenas local e irreversível:
destrói as suas chaves, contactos e historial *neste dispositivo* e não tem qualquer efeito nas pessoas
com quem falou.