@solana/react publica um cliente Kit na sua árvore de componentes através de um
provedor, e os hooks leem dados RPC, subscrições e estado da carteira a partir dele. Os
hooks de carteira do navegador residem em @solana/kit-plugin-wallet/react e leem o mesmo
provedor — não existe um provedor de carteira separado.
Instalar
$npm install @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-wallet @solana/react
Construir o cliente
Construa o cliente uma vez, no escopo do módulo, fora da árvore React. No navegador,
walletSigner torna a carteira conectada tanto o pagador de taxas quanto a identidade.
import { createClient } from "@solana/kit";import { solanaRpc } from "@solana/kit-plugin-rpc";import { walletSigner } from "@solana/kit-plugin-wallet";export const client = createClient().use(walletSigner({ chain: "solana:devnet" })).use(solanaRpc({ rpcUrl: "https://api.devnet.solana.com" }));export type AppClient = Awaited<typeof client>;
walletSigner adiciona client.wallet (descoberta e conexão Wallet Standard),
e solanaRpc adiciona client.rpc mais o auxiliar client.sendTransaction.
Exporte o tipo do cliente encapsulado em Awaited<> para que permaneça correto se você posteriormente
adicionar um plugin que resolva de forma assíncrona, e passe esse AppClient para cada
chamada de useClient.
Envolva sua árvore uma vez
ClientProvider publica o cliente. Os hooks de dados (useRequest,
useSubscription, useTrackedData) leem-no via useClient. Os hooks de carteira
abaixo precisam do mesmo cliente passado explicitamente como primeiro argumento.
"use client";import { ClientProvider } from "@solana/react";import { client } from "./client";export function Providers({ children }: { children: React.ReactNode }) {return <ClientProvider client={client}>{children}</ClientProvider>;}
Hooks de carteira
Os hooks de carteira precisam de um cliente com um plugin de carteira instalado (ex.:
walletSigner). Obtenha-o de useClient<AppClient>() e passe-o como primeiro argumento de cada hook —
isso mantém a aplicação totalmente tipada de ponta a ponta, em vez de depender de
buscas por contexto.
useWallets(client)— Carteiras Wallet Standard descobertas para a chain do cliente.useWalletStatus(client)—"pending" | "disconnected" | "connecting" | "connected" | "disconnecting" | "reconnecting".useConnectedWallet(client)—{ account, signer, wallet }ounull.signerénullpara carteiras somente leitura.useConnect(client)/useDisconnect(client)— retornam umActionResultcujodispatch(edispatchAsync) executa a ação e cujosisRunning,status,data,erroreresetrastreiam o resultado.
"use client";import {useConnect,useConnectedWallet,useDisconnect,useWallets,useWalletStatus} from "@solana/kit-plugin-wallet/react";import { useClient } from "@solana/react";import type { AppClient } from "./client";function WalletPanel() {const client = useClient<AppClient>();const status = useWalletStatus(client);const wallets = useWallets(client);const connected = useConnectedWallet(client);const connect = useConnect(client);const disconnect = useDisconnect(client);if (status === "pending") return null; // wait out auto-reconnectif (connected) {return (<div><p>{connected.account.address}</p><button onClick={() => disconnect.dispatch()}>Disconnect</button></div>);}return (<div>{wallets.map((wallet) => (<buttonkey={wallet.name}disabled={connect.isRunning}onClick={() => connect.dispatch(wallet)}>Connect {wallet.name}</button>))}</div>);}
Enviar uma transação
useClient retorna o mesmo cliente que você publicou. Construa instruções com um
cliente de programa gerado e envie-as através de client.sendTransaction.
"use client";import { address, lamports } from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";import { useClient } from "@solana/react";import { useConnectedWallet } from "@solana/kit-plugin-wallet/react";import type { AppClient } from "./client";function SendSol({ destination }: { destination: string }) {const client = useClient<AppClient>();const connected = useConnectedWallet(client);async function handleSend() {if (!connected?.signer) return;const transfer = getTransferSolInstruction({source: connected.signer,destination: address(destination),amount: lamports(10_000_000n) // 0.01 SOL});const result = await client.sendTransaction([transfer]);console.log("sent", result.context.signature);}return (<button disabled={!connected?.signer} onClick={handleSend}>Send 0.01 SOL</button>);}
Passar o tipo AppClient exportado para useClient fornece ao hook o cliente
completo com extensão de plugins, de modo que client.rpc e client.sendTransaction são tipados.
Ler dados
@solana/react fornece hooks que leem através do cliente:
useRequest(source)— leitura RPC pontual; retorna{ data, error, status, refresh }.useSubscription(source)— uma subscrição em tempo real; retorna{ data, error, reconnect, status }.useTrackedData(spec)— um valor inicializado por RPC mantido atualizado por uma subscrição.
"use client";import { address } from "@solana/kit";import { useClient, useRequest } from "@solana/react";import { useMemo } from "react";import type { AppClient } from "./client";function Balance({ owner }: { owner: string }) {const client = useClient<AppClient>();const source = useMemo(() => client.rpc.getBalance(address(owner)),[client, owner]);const { data, status, refresh } = useRequest(source);if (status === "fetching") return <p>Loading…</p>;if (status === "error") return <p role="alert">RPC error</p>;return (<div><p>Lamports: {data?.value.toString()}</p><button onClick={() => refresh()}>Refresh</button></div>);}
Memoize a fonte (com useMemo, ou useCallback para uma função) para que o hook
rebusque apenas quando suas entradas mudarem, em vez de a cada renderização.
Para cache e revalidação, os subcaminhos @solana/react/swr e @solana/react/query
encapsulam os mesmos hooks para SWR e
TanStack Query.
Padrões comuns para devs Solana
- Um provedor:
ClientProvideré o único provedor necessário; obtenha o cliente comuseClient<AppClient>()e passe-o para os hooks de carteira. - Compatível com Server Components: Marque com
"use client"apenas os componentes folha que chamam hooks; leituras no servidor podem usar um cliente RPC Kit simples sem carteira. - Testes: Publique um cliente simulado através de
ClientProviderpara simular carteiras e respostas RPC.
Duas famílias de hooks, mesmos nomes
useSignIn e useSignMessage existem tanto em @solana/react (recebem um
argumento UiWalletAccount) quanto em @solana/kit-plugin-wallet/react (recebem o
client, retornam um ActionResult). Use as versões de
@solana/kit-plugin-wallet/react com o padrão de cliente acima; os
hooks de carteira mais antigos de @solana/react estão sendo substituídos.
Combine este guia com a visão geral do cliente Kit para compreender o cliente que cada hook lê.
Is this page helpful?