Conta docs

Stack e escolhas

As tecnologias que sustentam a Conta e o motivo de cada uma ter sido escolhida.

O quadro geral

CamadaEscolhaPor quê
FrameworkNext.js 16 (App Router, Turbopack)Server Components reduzem o JS enviado; o mesmo projeto serve UI e as poucas rotas de servidor
UIReact 19 + Tailwind 4Tailwind 4 configura o design system em CSS, sem arquivo de config JS
LinguagemTypeScript estritoSem any, com noUncheckedIndexedAccess — acesso indexado devolve T | undefined
ChainviemAPI tipada e explícita; sem a superfície de legado do ethers
Auth e carteiraPrivyPasskey + carteira embutida sem que a chave passe por nós
BancoSupabase (Postgres)Postgres gerenciado com boa DX; usado como cache, não como autoridade
ValidaçãoZodUm schema por fronteira: toda rota de API e todas as variáveis de ambiente
ObservabilidadeSentryCaptura de erro no cliente, servidor e edge
DeployVercelIntegração nativa com Next, incluindo cron

Por que Base

Uma L2 EVM com custo de transação baixo o suficiente para que patrocinar o gás de cada operação de usuário seja economicamente viável. Numa L1, o modelo de "o usuário não precisa ter ETH" seria caro demais para sustentar.

Sendo EVM, a carteira do usuário é uma EOA padrão: legível e utilizável por qualquer ferramenta do ecossistema, não um formato proprietário nosso.

Por que BRLA

Uma stablecoin ERC-20 com paridade 1:1 com o real e 18 casas decimais.

A paridade importa por um motivo prático: o usuário raciocina em reais, e o saldo dele é em reais. Não há exposição cambial escondida entre o depósito e o saque, e não há conversão de moeda para explicar na interface.

As 18 casas decimais tornam a conversão de centavos exata em aritmética inteira — nenhum arredondamento em nenhum caminho de dinheiro. Veja Dados e ledger.

Por que passkey em vez de seed phrase

Seed phrase é a maior barreira de adoção da autocustódia, e a maior fonte de perda irreversível. Passkey entrega a mesma propriedade — a chave está com o usuário, não conosco — usando um mecanismo que o sistema operacional já gerencia, sincroniza e protege com biometria.

O usuário não aprende nada novo. Ele desbloqueia com o rosto ou a digital, como já faz no resto do telefone.

Convenções de código

TypeScript estrito

Sem any. noUncheckedIndexedAccess ligado — todo acesso indexado precisa ser tratado como possivelmente indefinido.

Server Components por padrão

Client Component só quando há hook ou estado. Menos JavaScript no dispositivo.

Zod em toda fronteira

Rotas de API e variáveis de ambiente são validadas por schema. Entrada não validada não entra.

Idioma dividido

Interface em português. Código, commits e identificadores em inglês.

Ambientes

O app roda contra Base Sepolia em desenvolvimento e Base mainnet em produção. A troca é uma variável de ambiente.

Uma consequência prática: as rails de dólares dependem de contratos que só existem em mainnet, então elas não são testáveis em Sepolia. As rails de PIX funcionam nos dois.

Testes

Vitest cobre a lógica com risco de dinheiro: máquinas de estado das rails, aritmética de conversão, análise de BR Code, verificação de webhook, guards de concorrência. Praticamente todo módulo em lib/ tem um .test.ts ao lado.

O que é testado é escolhido pelo mesmo critério do resto do sistema: o que, se estiver errado, move dinheiro para o lugar errado.

On this page