Integração de dApp Next.js
Um dApp Solana em Next.js é produto de runtime dividido: Server Components e Route Handlers no lado Node, Client Components ligados à carteira no navegador, e @solana/kit 7.0.0 falando com RPC (e frequentemente WebSocket) em cluster escolhido.
Esta página é o guarda-chuva da seção. Mapeia App Router + providers Solana, assinatura no cliente, API routes para transações, exibição de dados on-chain e cache / realtime para que os how-tos irmãos leiam como níveis de zoom de uma stack.
Resumo
- Integre Solana no Next.js App Router isolando carteira e APIs de navegador atrás de uma árvore de provider client, montando e assinando transações de autoridade do usuário só no navegador, usando Route Handlers para segredos e patrocínio, e hidratando UI a partir de RPC (com cache + assinaturas) sob política de commitment explícita.
- Por Que Importa: Misturar SSR com
window, colocar keypairs em envNEXT_PUBLIC_ou tratar sucesso desendTransactioncomo liquidação produz builds quebrados, patrocinadores drenados e UX falsa. Mapa compartilhado de responsabilidades server vs client previne esses modos de falha. - Conceitos-Chave: App Router, Server Component, Client Component, árvore de provider Solana, wallet adapter / wallet-standard, RPC @solana/kit, mensagem de transação, lifetime de blockhash, assinatura no cliente, Route Handler, fee payer / patrocínio, commitment, SWR / React Query, accountSubscribe.
- Quando Usar: Scaffolding de dApp Solana greenfield no App Router Next.js 13+; onboarding de equipe React em caminhos de escrita com carteira; decidir o que roda no servidor versus na carteira; planejar UIs de portfólio e saldos ao vivo.
- Limitações / Trade-offs: Providers client e modais de carteira não podem renderizar puramente no servidor; rotas patrocinadas precisam auth, rate limits e caps de gasto; polling agressivo queima RPC; WebSockets são visões locais de nó e ainda exigem disciplina de commitment.
- Tópicos Relacionados: Noções básicas de layout dApp, providers e App Router, assinatura no cliente, API routes para transações, exibição on-chain, cache e realtime.
Fundamentos
Next.js App Router é Server Components-first: arquivos sob app/ são server por padrão, e "use client" marca ilhas que hidratam no navegador.
SDKs de carteira precisam de window, storage e gestos do usuário que não existem durante SSR. A regra é estrutural: contexto de carteira, UI de connect e assinatura vivem em client components; shells de marketing e handlers com segredos ficam no servidor.
Providers Solana ficam em um wrapper client (por exemplo app/solana-provider.tsx) composto no layout raiz. Essa árvore tipicamente fornece:
- Config RPC / kit - URL HTTP do cluster (frequentemente
NEXT_PUBLIC_RPC_URL). - Registro de carteiras - adapters ou descoberta wallet-standard (Phantom, Solflare e outros).
- Modal / UI de connect - um provider modal para rotas aninhadas não montarem dialogs duplicados.
O layout.tsx raiz pode permanecer Server Component que só envolve children com aquele provider. Layouts aninhados não devem redeclarar a mesma stack de carteira.
@solana/kit 7.0.0 é o client recomendado para createSolanaRpc, createSolanaRpcSubscriptions, mensagens de transação e helpers de confirmação. web3.js v1 legado aparece só em migrações; trabalho novo mira kit.
Cluster e env importam desde o dia um. NEXT_PUBLIC_* vai para o navegador (URL RPC, label de cluster, program ids públicos). Keypairs patrocinadores e segredos de API privilegiados ficam server-only (sem prefixo NEXT_PUBLIC_), idealmente em gerenciador de segredos.
Commitment (processed, confirmed, finalized) alinha com o resto deste site: UI otimista pode usar níveis mais rasos; efeitos off-chain irreversíveis esperam mais profundos.
Forma mínima da stack:
app/layout.tsx (Server Component)
|
+-- SolanaProvider ("use client")
| Connection / kit config
| WalletProvider + modal
|
+-- page.tsx (Server OK for public reads / SEO)
|
+-- client islands (balance chips, send buttons)
|
+-- app/api/**/route.ts (Route Handlers)
server builds / sponsors / Actions JSON
Páginas irmãs aprofundam cada caixa; esta página mantém o diagrama inteiro em vista.
Mecânica e Interações
Providers e a fronteira do App Router
No primeiro carregamento, Server Components renderizam HTML sem estado de carteira. Após hidratação, providers anexam conexão e contexto de carteira. Hooks como useWallet ou helpers wallet-standard rodam só sob aquela fronteira client.
Regras práticas: importe CSS de carteira uma vez; estabilize adapters com useMemo; mantenha um provider raiz (duplicatas dobram modais); divida ou importe dinamicamente com ssr: false se widget ainda puxar código só de navegador para grafo server.
Veja Providers e App Router.
Assinatura no cliente
Trabalho de autoridade do usuário (transferências pagas pelo usuário, mints, aprovações DeFi) segue loop fixo de Client Component:
- Garanta que carteira está conectada e pubkey do fee payer é conhecida.
- Busque blockhash fresco (
getLatestBlockhash). - Monte mensagem de transação versionada com kit (fee payer, lifetime, instruções).
- Obtenha assinaturas Ed25519 da carteira (ponte signer kit ou caminhos adapter).
- Envie e espere commitment (
sendAndConfirmTransactionFactorycom HTTP + WSS, ou equivalente).
Segredos nunca saem da carteira. Simulação antes do modal reduz falhas evitáveis; expiração de blockhash durante aprovação lenta exige rebuild e re-prompt.
Veja Assinatura no Cliente.
API routes para transações
Route Handlers (app/api/.../route.ts) rodam no servidor quando você deve:
- Guardar keypair patrocinador / paymaster como fee payer para onboarding sem gas.
- Aplicar regras de negócio, allowlists ou inventário antes de oferecer mensagem à carteira.
- Implementar Solana Actions (JSON Actions HTTPS para carteiras e Blinks).
- Esconder API keys de terceiros usadas ao montar instruções.
Padrão comum é construção parcial: servidor monta (e pode assinar parcialmente como fee payer), retorna bytes serializados, e carteira do usuário co-assina. Assinatura puramente server só para contas que o servidor controla totalmente.
Proteja endpoints: valide JSON com schema, autentique, rate-limit, limite patrocínio, nunca retorne material de chave.
Veja API Routes para Transações.
Exibindo dados on-chain
Renderizar estado da chain é RPC de caminho de leitura mais formatação cuidadosa:
| Necessidade UI | Fonte típica |
|---|---|
| Saldo SOL | getBalance |
| Saldos SPL token | ATAs + decode token / decimais mint |
| NFTs / cNFTs | Provedor DAS (getAsset, getAssetsByOwner) quando disponível |
| Contas de programa custom | helpers fetch kit / Codama, derivação PDA |
Mantenha lamports e unidades base de token como inteiro / bigint até a string de exibição. Distinga carregando, vazio e erro. Server Components podem seedar snapshots públicos para SEO; portfólios privados de carteira ficam client-side.
Veja Exibindo Dados On-Chain.
Cache e realtime
Duas camadas frequentemente coexistem:
- Cache HTTP client - SWR ou React Query com chaves que incluem cluster + pubkey.
refreshIntervalopcional como fallback grosseiro. - Assinaturas WebSocket -
accountSubscribe(e assinaturas de signature) via kit; ao notificar,mutateo cache.
Cache RSC / Next data não é cache de carteira do navegador. Após sua própria escrita confirmada, invalide chaves relacionadas. Abort assinaturas no unmount. Faça backoff em 429.
Veja Cache e Realtime.
Caminho de escrita end-to-end (self-custody)
User clicks Send (Client Component)
|
v
kit: build message + recent blockhash
|
v
Wallet modal signs (Ed25519, secrets stay in wallet)
|
v
sendTransaction via RPC --> signature S
|
+-- WSS signatureSubscribe / confirm factory
|
v
commitment: processed -> confirmed -> finalized
|
v
invalidate SWR keys; show explorer link
Fluxos patrocinados inserem Route Handler entre clique e carteira: servidor retorna mensagem parcial; client ainda coleta assinatura do usuário quando autoridade do usuário é exigida.
Considerações Avançadas e Aplicações
Mapa de conceitos da seção
| Preocupação | Página principal | Takeaway para quem constrói |
|---|---|---|
| Layout de pastas, env, split read/write | Noções Básicas de Integração dApp | Estrutura antes de features |
| Árvore provider client, segurança SSR | Providers e App Router | Um provider raiz; shell de layout server |
| Montar, assinar, confirmar no navegador | Assinatura no Cliente | Blockhash fresco; sem carteira no servidor |
| Saldos, tokens, estado de programa na UI | Exibindo Dados On-Chain | bigint até formatar; estados explícitos |
| Txs montadas/patrocinadas no servidor | API Routes para Transações | Segredos server-only; caps e auth |
| SWR + assinaturas | Cache e Realtime | Mutate após confirm; abort no unmount |
Leituras server-side, UX de transação e melhores práticas refinam polimento; as linhas acima são o núcleo de integração.
Projetando o split: servidor vs client
| Trabalho | Prefira client | Prefira server (Route Handler / RSC) |
|---|---|---|
| Conectar carteira, assinar como usuário | Sim | Não |
| Config pública de programa para SEO | Seed opcional | Sim |
| Patrocinar fee payer | Só co-assinar | Sim para material de chave |
| API key RPC privada | Não | Sim (proxy) |
| Portfólio de carteira ao vivo | Sim + WS | Só snapshot público inicial |
Não "mova assinatura para o servidor" para simplificar React; isso redefine custódia.
Postura de produção
- Fixe cluster, program ids e URLs RPC/WSS por ambiente.
- Logue correlation ids em API routes; mostre erros de simulação decodificados, não stack traces.
- Prefira RPC pago em mainnet; alinhe rede da carteira com cluster RPC.
- Trate Actions / Blinks como produtos HTTPS de primeira classe quando expuser construção sem supervisão.
Alinhamento de ferramentas
Mire @solana/kit 7.0.0 para RPC, mensagens e confirmação. Faça ponte de signers wallet-adapter ou wallet-ui para kit em vez de stacks paralelas web3.js v1. Testes de integração podem usar Surfpool ou validador local; testes unitários mockam RPC. Programas co-desenvolvidos neste site assumem Anchor 0.32.1, Rust 1.91.1, Agave 4.1.1 e Solana CLI 3.0.10.
Conceitos Errados Comuns
- "Posso chamar useWallet de qualquer Server Component se for cuidadoso." Hooks de carteira exigem fronteira client e APIs de navegador; importá-los em grafo server quebra o build ou crasha SSR.
- "Colocar keypair patrocinador em env NEXT_PUBLIC_ é ok se o repo for privado." Env público vai para todo navegador; trate chaves patrocinadoras como segredos server-only com rotação e limites de gasto.
- "sendTransaction retornando assinatura significa que o usuário recebeu os tokens." A assinatura é handle; UX deve esperar o commitment escolhido e depois atualizar leituras em cache.
- "API routes substituem a carteira para todas as transações." Rotas podem patrocinar taxas e codificar política; autoridade do usuário para contas do usuário ainda precisa assinatura de carteira a menos que o servidor seja o owner real.
- "Polling SWR a cada segundo é o mesmo que realtime." Polling apertado bate rate limits e ainda atrasa; combine cache HTTP modesto com invalidação WebSocket para contas quentes.
- "Um React context global para saldos de todos os usuários é eficiente." Chaves de cache devem incluir identidade (e cluster); chaves compartilhadas vazam ou embaralham dados de portfólio sob sessões multi-usuário.
FAQs
Qual é o modelo de uma frase para dApp Solana Next.js?
Server Components e Route Handlers lidam com SEO, segredos e política; uma árvore de provider client única possui estado de carteira e UI RPC; kit monta mensagens que a carteira assina; cache e assinaturas mantêm contas exibidas honestas sob commitment escolhido.
Por que App Router em vez de Pages Router para dApps novos?
Trabalho greenfield deve usar App Router: Server Components, layouts aninhados e Route Handlers mapeiam limpo no split server/client que Solana exige. Pages Router permanece caminho de migração legado apenas.
Onde providers de carteira pertencem na árvore de arquivos?
Em um módulo client (por exemplo solana-provider.tsx) importado do layout raiz, não remontado em todo layout ou página aninhada.
Server Components podem ler a chain?
Sim para dados públicos via chamadas kit/RPC server-side. Não podem acessar carteira do usuário ou chaves privadas; passem props serializáveis simples para ilhas client de UI interativa.
Quando assinatura deve ficar inteiramente client-side?
Sempre que fee payer ou autoridade é o usuário final e você não está patrocinando taxas ou injetando política server-only. Esse é o padrão para DeFi, transferências e mints self-custody.
Quando preciso de API routes para transações?
Quando precisa de fee payer no servidor, checagens de inventário ou allowlist, endpoints Actions/Blinks, ou chaves de terceiros privadas durante construção de mensagem.
Como evito window is not defined?
Nunca importe entrypoints de wallet adapter em Server Components. Mantenha-os sob módulos "use client" que só carregam no grafo do navegador.
Qual biblioteca código novo deve usar: kit ou web3.js v1?
@solana/kit 7.0.0 é a baseline neste site. Use web3.js v1 só enquanto migra módulos legados.
Como saldos devem ser formatados?
Mantenha lamports e unidades base de token como inteiros/bigint pela lógica de negócio; divida por 10**decimals só ao produzir string de exibição.
Como mantenho UI fresca após envio bem-sucedido?
Confirme até seu commitment alvo, depois mutate chaves SWR/React Query (ou confie em handlers accountSubscribe) para recarregar saldos e dados de conta em cache.
NEXT_PUBLIC_RPC_URL é segredo?
Não. É endereço de endpoint público. Faça proxy de headers privilegiados do provedor no servidor se necessário, e ainda rate-limit tráfego client.
Qual commitment o dApp deve esperar?
Muitas ações de produto usam confirmed. Use finalized antes de efeitos externos irreversíveis. Trate processed como otimista apenas.
Onde devo ir a seguir nesta seção?
Comece com Noções Básicas de Integração dApp, depois Providers e App Router, Assinatura no Cliente, Exibindo Dados On-Chain, API Routes para Transações e Cache e Realtime.
Related
- Noções Básicas de Integração dApp - layout de pastas, env e exemplos de split server/client
- Providers e App Router - árvore de provider carteira e RPC sem crashes SSR
- Assinatura no Cliente - montar, assinar e confirmar no navegador com kit
- Exibindo Dados On-Chain - saldos, tokens, NFTs e estado de programa em React
- API Routes para Transações - mensagens montadas no servidor, patrocínio e backends Actions
- Cache e Realtime - padrões SWR/React Query mais invalidação WebSocket
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, and @solana/kit 7.0.0.