@solana/react publie un client Kit dans votre arborescence de composants via un seul fournisseur, puis les hooks lisent les données RPC, les abonnements et l'état du portefeuille depuis celui-ci. Les hooks de portefeuille navigateur se trouvent dans @solana/kit-plugin-wallet/react et lisent le même fournisseur — il n'y a pas de fournisseur de portefeuille séparé.
Installation
$npm install @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-wallet @solana/react
Construire le client
Construisez le client une seule fois, au niveau du module, en dehors de l'arborescence React. Dans le navigateur, walletSigner fait du portefeuille connecté à la fois le payeur des frais et l'identité.
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 ajoute client.wallet (découverte et connexion via Wallet Standard), et solanaRpc ajoute client.rpc ainsi que l'helper client.sendTransaction. Exportez le type du client encapsulé dans Awaited<> afin qu'il reste correct si vous ajoutez ultérieurement un plugin qui se résout de manière asynchrone, et passez cet AppClient à chaque appel useClient.
Envelopper votre arborescence une seule fois
ClientProvider publie le client. Les hooks de données (useRequest, useSubscription, useTrackedData) le lisent via useClient. Les hooks de portefeuille ci-dessous nécessitent que le même client leur soit passé explicitement en premier argument.
"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 portefeuille
Les hooks de portefeuille nécessitent un client avec un plugin de portefeuille installé (par ex. walletSigner). Récupérez-le depuis useClient<AppClient>() et passez-le en premier argument de chaque hook — cela permet à l'application d'être entièrement typée de bout en bout, plutôt que de reposer sur des recherches dans le contexte.
useWallets(client)— Portefeuilles Wallet Standard découverts pour la chaîne du client.useWalletStatus(client)—"pending" | "disconnected" | "connecting" | "connected" | "disconnecting" | "reconnecting".useConnectedWallet(client)—{ account, signer, wallet }ounull.signerestnullpour les portefeuilles en lecture seule.useConnect(client)/useDisconnect(client)— retournent unActionResultdontdispatch(etdispatchAsync) exécute l'action, et dontisRunning,status,data,erroretresetsuivent son résultat.
"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>);}
Envoyer une transaction
useClient retourne le même client que vous avez publié. Construisez les instructions avec un client de programme généré et envoyez-les via 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>);}
Passer le type AppClient exporté à useClient donne au hook le client entièrement étendu par les plugins, de sorte que client.rpc et client.sendTransaction sont typés.
Lire des données
@solana/react fournit des hooks qui lisent via le client :
useRequest(source)— lecture RPC ponctuelle ; retourne{ data, error, status, refresh }.useSubscription(source)— un abonnement en temps réel ; retourne{ data, error, reconnect, status }.useTrackedData(spec)— une valeur initialisée par RPC maintenue à jour par un abonnement.
"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>);}
Mémoïsez la source (avec useMemo, ou useCallback pour une fonction) afin que le hook ne récupère les données que lorsque ses entrées changent, plutôt qu'à chaque rendu.
Pour la mise en cache et la revalidation, les sous-chemins @solana/react/swr et @solana/react/query encapsulent les mêmes hooks pour SWR et TanStack Query.
Modèles courants pour les développeurs Solana
- Un seul fournisseur :
ClientProviderest le seul fournisseur dont vous avez besoin ; récupérez le client avecuseClient<AppClient>()et passez-le aux hooks de portefeuille. - Compatible avec les composants serveur : Marquez uniquement les composants feuilles qui appellent des hooks avec
"use client"; les lectures côté serveur peuvent utiliser un client RPC Kit standard sans portefeuille. - Tests : Publiez un client simulé via
ClientProviderpour simuler des portefeuilles et des réponses RPC.
Deux familles de hooks, mêmes noms
useSignIn et useSignMessage existent dans @solana/react (ils prennent un argument UiWalletAccount) et dans @solana/kit-plugin-wallet/react (ils prennent le client à la place et retournent un ActionResult). Utilisez les versions de @solana/kit-plugin-wallet/react avec le modèle client décrit ci-dessus ; les anciens hooks de portefeuille de @solana/react sont en cours de remplacement.
Associez ce guide à la vue d'ensemble du client Kit pour comprendre le client que chaque hook utilise.
Is this page helpful?