Pontos-chave de Integração de Wallet
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.
Resumo
- 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.
- Conceitos-chave: Wallet Standard, wallet adapter / wallet-ui, connect / disconnect / select, sessão publicKey, signTransaction / signAllTransactions / signMessage, ponte TransactionSendingSigner, autoConnect, SIWS, cluster match, MWA / timeouts de hardware.
- Quando usar este modelo: Entregar um dApp React ou Next.js, conectar pipelines de message
@solana/kit7.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".
- Tópicos relacionados: Wallet Basics, Wallet Adapter, Connecting & Disconnecting, Signing Transactions & Messages, Autoconnect & Session UX, Hardware & Mobile Wallets.
Fundamentos
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.
Mecânica e interações
Setup de adapter e discovery
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.
"use client";
// Conceptual shape - wallets array + autoConnect + modal
<ConnectionProvider endpoint={rpcUrl}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>{children}</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>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.
Connect, select e disconnect
UX típica: Connect, escolha uma wallet no modal, aprove na extensão ou app, depois mostre address truncado e disconnect.
| Estado | Significado | Dever da UI |
|---|---|---|
| disconnected | Sem sessão | Connect / select wallet |
| connecting | Prompt ou autoConnect em andamento | Desabilite double-click; mostre restoring ou connecting |
| connected | publicKey disponível | Chip de account, disconnect, habilite ações de sign |
| disconnecting / error | Teardown ou falha | Retry amigável; limpe UI otimista |
const { connected, connecting, publicKey, disconnect, select } = useWallet();- Prefira um modal picker quando múltiplas wallets podem estar instaladas;
connect()nu sem adapter selecionado é ambíguo. - Disconnect deve limpar stores e caches do app keyed por pubkey para a próxima account não herdar portfolio ou estado de auth.
- Connect não aprova transactions futuras. Cada send ainda precisa de aprovação fresca da wallet.
Assinatura de transactions e messages
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.
1. connected publicKey
2. getLatestBlockhash (kit RPC)
3. createTransactionMessage + fee payer + instructions
4. optional simulate
5. wallet.signTransaction / kit sign helpers
6. send + confirmsignMessage 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 e UX de sessão
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.
Hardware e mobile
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.
Considerações avançadas e aplicações
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.
Equívocos comuns
- "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.
publicKeydo 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.
FAQs
O que uma wallet Solana faz para um dApp?
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.
Related
- Wallet Basics - Wallet Standard, lazy connect, cluster awareness
- Wallet Adapter - setup de provider e hooks
useWallet - Connecting & Disconnecting - estado de sessão e seleção multi-wallet
- Signing Transactions & Messages - pipeline de message kit e sign da wallet
- Autoconnect & Session UX - restaurar sessão sem modais surpresa
- Hardware & Mobile Wallets - Ledger, MWA, timeouts
- Wallet Integration Best Practices - checklist de produção
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.