Assinatura no Lado do Client
Monte e envie transações no browser com kit + wallet adapters.
Receita
"use client";
import { createSolanaRpc, signTransactionMessageWithSigners } from "@solana/kit";Quando usar:
- Transações pagas pelo usuário e mints de NFT.
- Swaps DeFi que exigem aprovação da carteira.
- Qualquer ação que precise de chaves privadas do usuário.
Exemplo Prático
"use client";
import { useCallback } from "react";
import { useWallet } from "@solana/wallet-adapter-react";
import {
createSolanaRpc,
createTransactionMessage,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
signTransactionMessageWithSigners,
sendAndConfirmTransactionFactory,
createSolanaRpcSubscriptions,
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
export function SendButton({ to, lamports }: { to: string; lamports: bigint }) {
const wallet = useWallet();
const rpc = createSolanaRpc(process.env.NEXT_PUBLIC_RPC_URL!);
const rpcSubscriptions = createSolanaRpcSubscriptions(process.env.NEXT_PUBLIC_RPC_WSS_URL!);
const onSend = useCallback(async () => {
if (!wallet.publicKey) return;
const { value: bh } = await rpc.getLatestBlockhash().send();
// Bridge da carteira para kit signer (use o helper do seu template)
let msg = createTransactionMessage({ version: 0 });
// defina fee payer signer, lifetime, transfer ix...
const signed = await signTransactionMessageWithSigners(msg);
const sendAndConfirm = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
await sendAndConfirm(signed, { commitment: "confirmed" });
}, [wallet, rpc, rpcSubscriptions, to, lamports]);
return <button onClick={onSend}>Send</button>;
}O que isso demonstra:
- Todo o pipeline de assinatura roda apenas no client.
- Blockhash fresco por clique.
- Confirmação via factory WSS.
Aprofundamento
Como Funciona
- Mensagem montada no browser; carteira assina sem exportar secrets.
- Simulação opcional antes do modal da carteira.
- Next.js não serializa bytes de transação pelo servidor em fluxos de auto-custódia.
Erros Comuns
- Server Action tentando usar carteira window - falha. Correção: mantenha em client component.
- Closure obsoleta na carteira - envio após desconectar. Correção: guarde estado connected.
- Env WSS ausente - confirmação trava. Correção: forneça URL WSS pública.
- Blockhash expira durante aprovação da carteira - reconstrua e tente de novo.
- Não desabilitar botão enquanto pendente - tentativas de gasto duplo.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Tx patrocinada no servidor | Onboarding gasless | Auto-custódia total |
| Carteira embutida | UX Web2 | Usuários avançados |
FAQs
App Router?
Providers em client layout.tsx; pages misturam server + client components.
Secrets?
Env de servidor só para keypairs; NEXT_PUBLIC_ para URLs de RPC.
kit 7.0.0?
Todos os exemplos usam @solana/kit, não web3.js v1.
Carteira?
Assinatura apenas em client components.
Cache?
Revalide leituras on-chain com cuidado - a chain é fonte da verdade.
Actions?
Endpoints HTTPS retornando JSON de Solana Actions.
Mobile?
App React Native separado com MWA.
Testes?
Surfpool para integração; mock RPC em testes unitários.
Mainnet?
Arquivos env e program IDs separados.
Erros?
Decodifique logs de simulação para mensagens voltadas ao usuário.
Relacionado
- Assinando Transações e Mensagens - assinatura de carteira
- UX de Transação - feedback
- Montando Mensagens de Transação - compor
Versões da stack: Esta página foi escrita para 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 e LiteSVM 0.6.x.