Na Solana, usuários guardam keys em uma wallet (extensão de browser, app mobile ou dispositivo hardware). Seu dApp nunca recebe uma private key. Ele descobre wallets, solicita conexão, monta transaction messages não assinadas e pede à wallet para assinar. A wallet mostra uma UI de aprovação legível; após o usuário confirmar, seu app envia o payload assinado para RPC e acompanha confirmação.
Esta página é o mapa conceitual de Wallet Integration - camadas de adapter, connect e disconnect, assinatura de transaction e message, UX de autoconnect e sessão, caminhos hardware e mobile, e os limites de segurança que mantêm keys fora do seu processo em stacks alinhados ao Agave 4.1.1.
Integração de wallet é uma ponte de capacidade: descubra uma wallet padrão, estabeleça sessão scoped por origin, assine apenas o que o usuário aprovar, depois transmita com seu próprio RPC e UX. Secrets ficam dentro da wallet.
Por que importa: Toda ação paga pelo usuário (swap, mint, transfer, jogada) e a maior parte da auth off-chain (SIWS) depende de estado de connect correto, identidade do fee payer, alinhamento de cluster e previews honestos. Erros produzem txs falhas, dados de account errados ou UX digna de phishing.
Quando usar este modelo: Entregar um dApp React ou Next.js, conectar pipelines de message @solana/kit 7.0.0 a signers de browser, desenhar UX de sessão, suportar Ledger ou mobile, ou auditar onde keys e assinaturas podem viver.
Limitações / trade-offs: Connect não é cheque em branco para gastos futuros; cada ação sensível precisa de aprovação. Adapters diferem por produto; mobile e hardware adicionam latência e modos de falha. Auth no servidor precisa de verificação de assinatura separada, não só "connected no React".
Uma wallet Solana é software ou hardware que guarda keypairs (ou accounts derivados de seed), acompanha contexto de cluster (mainnet, devnet, testnet) e expõe uma API estreita: connect, disconnect, sign transactions e opcionalmente sign arbitrary messages.
O dApp possui UX de produto, construção de instructions, reads RPC, simulation, submission e confirmação. Ele não deve aceitar seed phrases ou private keys se reivindica signing não custodial.
User key material | v Wallet (extension / mobile / hardware) | connect, signTransaction, signMessage v Adapter / Wallet Standard bridge | React context: publicKey, connected, signers v dApp (@solana/kit build + RPC send + UI)
Wallet Standard (e o ecossistema multi-adapter ao redor) é como browsers descobrem wallets instaladas sem hardcodar uma marca. Extensões se registram; seu app as lista para seleção do usuário. No mobile, Mobile Wallet Adapter (MWA) e deep links desempenham papel similar com plumbing diferente.
Em React, @solana/wallet-adapter-react (ConnectionProvider, WalletProvider, useWallet, modal opcional) ainda é comum. Scaffolds mais novos podem usar @wallet-ui/react. Ambos compartilham o mesmo contrato: providers client-only, adapters registrados e hooks para publicKey, connected, connecting, select, connect, disconnect e signing.
Connection significa que esta origin pode solicitar assinaturas para uma account escolhida. Não é uma transaction on-chain nem login no servidor. publicKey é a identidade de sessão do client para estado keyed por address.
Alinhamento de cluster é obrigatório: rede da wallet, URL de RPC e program IDs devem coincidir. Wallet mainnet contra RPC devnet produz falhas opacas de simulation e send. Mostre um badge de cluster e bloqueie send em mismatch quando puder detectar.
Trabalho read-only (saldos, explorers, marketing) usa RPC sem connect. Gate apenas ações que precisam de fee payer ou assinatura do usuário.
Monte providers apenas no client ("use client" no Next.js App Router). Registre wallets populares para o modal não ficar vazio. Combine signing de adapter com @solana/kit 7.0.0 para construção de message e RPC.
Adapters mapeiam eventos Wallet Standard em React context. useWallet() é a superfície do app. Registre wallet?.adapter.name em ferramentas de suporte para bugs específicos de wallet.
Seu app monta uma message não assinada: fee payer = pubkey conectado, recent blockhash, instructions (e compute budget conforme necessário). Opcionalmente simulate antes do modal da wallet. Chame a API de sign da wallet. Após assinaturas retornarem, você ainda serializa, envia via RPC e confirma.
signMessage cobre bytes off-chain (por exemplo Sign-In with Solana). A wallet retorna uma assinatura ed25519. Servidores devem verificar assinatura, domain binding e nonce ou expiry; nunca trate "client diz connected" como auth.
Modos de falha comuns: fee payer ≠ account conectada; blockhash obsoleto após aprovação lenta de hardware ou mobile (rebuild); txs oversized sem ALTs; assumir que signTransaction também confirma on-chain (signing é local; send é seu).
Faça ponte da wallet no TransactionSendingSigner do kit (ou equivalente) para que o caminho de message tipado e o adapter permaneçam um pipeline.
autoConnect restaura a última wallet escolhida no mount (frequentemente preferência em localStorage, nunca secret keys). Isso reduz fricção em visitas de retorno.
Padrão
Quando encaixa
Risco se mal usado
autoConnect + loading gate
dApps consumer, txs frequentes
Flash de UI "disconnected" se ignorar connecting
Apenas connect manual
Admin de alta segurança, ops raras
Fricção extra para usuários diários
Lazy connect
Sites de marketing; connect no primeiro intent de sign
Conversão maior que modais na landing
SIWS + cookie/JWT no servidor
Backends personalizados, APIs gated
Sessões forjadas se verificação for só no client
Mostre restoring session enquanto connecting for true. Não abra o modal completo de connect em todo load. Sempre exponha disconnect. Trate SIWS como camada separada: reconnect do adapter não re-prova identidade para sua API até você re-verificar assinatura ou sessão de servidor ainda válida.
No desktop, usuários Ledger frequentemente conectam via wallet broker que encaminha previews ao dispositivo. Código do app permanece adapter-driven; latência e confirmação multi-step aumentam. No mobile, injeção de extensão difere: use MWA, deep links ou browsers in-app injetados. Aumente timeouts. Teste em dispositivos reais. Seeker e Seed Vault mantêm a mesma regra: dApp solicita assinaturas; dispositivo guarda seeds. Agrupe instructions para uma ação de produto não significar muitos prompts no dispositivo.
Trate integração de wallet como limite de segurança, não apenas chrome de UI.
Limite
Permitido no dApp
Deve ficar na wallet / dispositivo
Private keys / seeds
Nunca
Sempre
Preferência de conexão
localStorage OK
N/A
Bytes de transaction para assinar
Montar e exibir intent
Assinar após review do usuário
Message de auth off-chain
Compor com domain + expiry
Assinar; servidor verifica
Cookies de sessão
Após verify SIWS
Não substituto para keys
Isolamento de origin: Connection é por site. Não ensine usuários a exportar seeds para "consertar" uma conexão ruim.
Honestidade de preview: Simule e resuma deltas de token e fee payer antes do prompt da wallet quando puder.
Sem armazenamento de secrets: Apenas public keys, preferência de cluster e flags de UI em browser storage.
Confiança no servidor: Verifique SIWS (ed25519, domain binding, proteção contra replay) server-side para APIs autenticadas.
Cluster e program IDs: Config não deve apontar silenciosamente uma wallet mainnet para cluster ou programa errado.
Mantenha versões de wallet-adapter ou wallet-ui alinhadas com kit e seu scaffold. Dual-stack (reads kit + sign adapter) é ok se documentado; dual send paths não são. Registre nome do adapter, cluster e pubkey truncado para suporte. QA duas wallets software mais hardware e mobile para apps consumer. Modais de connect precisam focus trap, navegação por teclado e copy amigável de reject.
Em stack alinhado ao Agave 4.1.1 (CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, @solana/kit 7.0.0), exercite connect, reject, disconnect, sign atrasado (blockhash obsoleto) e cluster mismatch antes de mainnet.
"Connect significa que o site pode gastar livremente." Connect só abre sessão para prompts posteriores. Cada transaction ainda precisa de aprovação do usuário.
"Posso guardar a private key em localStorage por conveniência." Isso transforma um produto não custodial em honeypot de malware. Nunca.
"signTransaction também landa a transaction." Signing retorna assinaturas; seu código deve enviar e confirmar.
"Uma marca de wallet basta." Usuários chegam com Phantom, Solflare, setups Ledger-brokered e wallets mobile. Descubra múltiplas opções.
"autoConnect é feature de segurança." É feature de UX. UIs admin de alta segurança podem preferir connect manual toda vez.
"Connected no React equivale a logged in no servidor." Sessões de servidor precisam de verificação SIWS. publicKey do client sozinho é forjável em requests.
"Mobile é a mesma API da extensão." Deep links e MWA mudam comportamento de sessão e timeout.
"Hardware wallets precisam de instruction bytes especiais do dApp." Geralmente a mesma message é assinada; timers e previews devem adaptar, não um segundo protocolo.
"Rede RPC e rede da wallet podem discordar se eu retry forte o suficiente." Alinhe badge de cluster, RPC e rede da wallet primeiro.
"Disconnect só esconde o chip de address." Disconnect deve derrubar sessão do adapter e limpar estado de aplicação keyed por pubkey.
Ela guarda keys, mostra UI de aprovação e retorna assinaturas. O dApp descobre a wallet, monta messages, solicita assinaturas e trata send RPC e confirmação.
O que é Wallet Standard?
Uma convenção de discovery em browser para múltiplas wallets se registrarem e dApps listarem sem hardcodar uma API de extensão.
wallet-adapter vs wallet-ui?
@solana/wallet-adapter-react permanece amplamente usado. @wallet-ui/react aparece em scaffolds mais novos. Ambos ficam acima de discovery estilo Wallet Standard; escolha um stack e mantenha versões alinhadas com kit.
Quando devo pedir ao usuário para conectar?
Prefira lazy connect: prompt quando o usuário iniciar uma ação que precisa de signing ou view específica de pubkey. Não bloqueie conteúdo puramente read. Veja Connecting & Disconnecting.
O que disconnect deve limpar?
Sessão do adapter mais caches e stores do app keyed pela publicKey anterior. Deixe dados públicos de marketing em paz.
Como assino com @solana/kit 7.0.0 e uma wallet de browser?
Monte a message com kit (fee payer, blockhash, instructions), faça ponte da wallet em um signer compatível com kit, assine, depois envie via RPC kit. Veja Signing Transactions & Messages.
signTransaction vs signMessage?
signTransaction (ou sign-all) autoriza bytes de transaction on-chain. signMessage assina bytes off-chain para auth ou attestations. Apenas assinaturas retornam à página.
Devo habilitar autoConnect?
Sim para a maioria dos apps consumer, com loading gate enquanto connecting for true e disconnect visível. Prefira connect manual para admin de alta segurança. Veja Autoconnect & Session UX.
Como SIWS se relaciona com wallet connect?
Connect dá ao client uma publicKey. SIWS prova controle dessa key ao seu backend via message com domain binding e verificação ed25519 server-side. Não são a mesma camada.
Por que usuários de hardware wallet falham mais?
Aprovações longas expiram blockhashes; timeouts curtos de UI abortam cedo; fluxos multi-prompt causam abandono. Estenda timers, rebuild messages e agrupe instructions. Veja Hardware & Mobile Wallets.
Como wallets mobile devem integrar?
Use MWA e caminhos de retorno deep-link para seu stack (web vs React Native). Teste em dispositivos. Não assuma injeção de extensão desktop.
Preciso de wallet para ler saldos?
Não. Reads RPC públicos funcionam com qualquer address. Exija connect apenas quando o usuário deve assinar ou quando você personaliza UI em torno da pubkey dele.
Qual é o principal limite de segurança?
Material de secret key nunca entra em memória ou storage do dApp. O dApp pode guardar public keys, preferências, messages não assinadas que montou e assinaturas retornadas após aprovação do usuário.
Como lidar com rejeição do usuário?
Trate cancel como normal: copy amigável, habilite retry, sem banners de stack trace. Não reenvie automaticamente em loop.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Revisado por Chris St. John·Última atualização: 15 de jul. de 2026