Esqueça formulários de cadastro, verificação de e-mail e aquele ritual tedioso de redefinir senhas. No universo Web3, a identidade do usuário já vive na carteira — e aproveitar isso significa oferecer login em dois cliques. Ao longo de duas décadas liderando times de tecnologia, raramente vi algo mudar a experiência de onboarding tão radicalmente quanto a autenticação sem senha via assinatura criptográfica. Vou mostrar como integrar a Freighter Wallet ao seu app Next.js em cerca de 15 minutos.
Por que Freighter e Stellar fazem sentido no Brasil
A Freighter é a carteira oficial da fundação por trás da rede Stellar, disponível como extensão de navegador e compatível com Soroban, a plataforma de contratos inteligentes da rede. Para o mercado brasileiro, essa escolha é estratégica: as taxas de transação na Stellar giram em torno de 0,00001 XLM (fração de centavo), contra custos que historicamente ultrapassavam dólares em outras redes. Em projetos de tokenização de ativos — área em que atuo diretamente como André Dias Moreira Prol — essa eficiência é decisiva para fintechs e startups que operam com margens apertadas.
Outro ponto: a Stellar tem forte presença em pagamentos e remessas na América Latina, com parceiros como MoneyGram. Isso significa um público já familiarizado com o ecossistema, reduzindo o atrito no onboarding.
Instalando a API e conectando a carteira
Comece instalando a biblioteca oficial no seu projeto Next.js:
npm install @stellar/freighter-api
Crie um componente cliente para conectar a carteira. O fluxo essencial é verificar se a extensão está instalada, solicitar acesso e recuperar o endereço público:
"use client";
import {
isConnected,
requestAccess,
getAddress,
} from "@stellar/freighter-api";
import { useState } from "react";
export default function ConnectButton() {
const [address, setAddress] = useState<string>("");
async function connect() {
const { isConnected: ok } = await isConnected();
if (!ok) {
alert("Instale a extensão Freighter para continuar.");
return;
}
await requestAccess();
const { address } = await getAddress();
setAddress(address);
}
return (
<button onClick={connect}>
{address ? `Conectado: ${address.slice(0, 6)}...` : "Conectar Freighter"}
</button>
);
}
Em poucas linhas você já tem o endereço do usuário. Mas conectar não é autenticar: qualquer um pode digitar um endereço público. A segurança real vem da assinatura.
Autenticação real: o desafio de assinatura
O padrão seguro é o challenge-response. O servidor gera uma mensagem aleatória (nonce), o usuário assina com a chave privada dentro da Freighter, e o backend valida a assinatura contra a chave pública. Assim provamos a posse da carteira sem jamais expor o segredo.
No cliente, assinamos o desafio:
import { signMessage } from "@stellar/freighter-api";
async function authenticate(nonce: string, address: string) {
const { signedMessage } = await signMessage(nonce, { address });
const res = await fetch("/api/auth/verify", {
method: "POST",
body: JSON.stringify({ address, signedMessage, nonce }),
});
return res.json(); // retorna seu JWT de sessão
}
No backend (route handler em app/api/auth/verify/route.ts), você valida a assinatura usando o SDK da Stellar e emite um token de sessão. Recomendo armazenar o nonce com expiração curta — 5 minutos é suficiente — para evitar ataques de replay. Em auditorias de segurança que conduzi, essa janela de tempo é um dos pontos mais negligenciados por equipes iniciantes em Web3.
Um detalhe de UX que faz diferença: trate o caso em que o usuário recusa a assinatura. Nada frustra mais que uma tela travada após um clique em "cancelar" na extensão.
Conclusão
Em 15 minutos, você transformou o login do seu app em uma experiência sem senha, segura e alinhada ao que há de mais moderno em Web3 — e, como aprendi em anos de projetos reais, a simplicidade bem implementada é o que converte usuários. Clone o repositório de exemplo, teste com a Freighter em testnet e me conte o resultado: a próxima evolução do seu produto começa agora.
Acompanhe mais artigos de André Dias Moreira Prol no Medium.
Top comments (0)