Skip to content

Arete documentation

Build a protocol interface with React

For the complete documentation index optimized for AI agents, see llms.txt or llms-full.txt. A markdown version of this page is available by appending .md to the URL or sending Accept: text/markdown.

For AI agents: the documentation index is at llms.txt (full corpus: llms-full.txt). A markdown source for this page is /integrating-protocols/react.md.

Use protocol hooks to display workflow state and explain which actions a connected wallet can perform. They accept a protocol client directly, including one from session.protocols.

Terminal window
npm install @usearete/react @usearete/sdk zod

Create your client or session outside the render cycle, or memoize it for its authentication and deployment inputs. Close it when its owner is disposed. A changing client identity causes hooks to start new reads and subscriptions.

In a session app, let AreteSessionProvider own the session and pass session?.protocols.<key> to the hooks. The hooks accept null or undefined and wait until the session is open. See Protocols in the session.

import {
useAllowedSteps,
useProtocolInstance,
type AnyProtocolClient,
} from "@usearete/react";
function InstancePanel({ client, instanceId, wallet }: {
client: AnyProtocolClient;
instanceId: string;
wallet: string;
}) {
const { instance, isLoading, error } = useProtocolInstance(
client, instanceId, { wallet },
);
const { data: steps, isLoading: stepsLoading, error: stepsError } = useAllowedSteps(
client, { instance: instanceId, wallet }, { refreshOnEvents: true },
);
if (error) return <p>{error.message}</p>;
if (isLoading) return <p>Loading instance…</p>;
return <section>
<p>State: {instance?.state}</p>
{stepsError ? <p role="alert">Could not load actions: {stepsError.message}</p>
: stepsLoading ? <p>Loading actions…</p>
: <ul>{steps?.map((step) => <li key={step.step}>
{step.step}: {step.allowed ? "available" : step.reason}
</li>)}</ul>}
</section>;
}

useProtocolInstance refreshes canonical state when instance stream events arrive and closes its handle on unmount. Its live result contains the protocol stack’s row when the client belongs to a session with that stack connected; it can otherwise be undefined.

useWalletActions(client, { wallet, instance?, cursor?, limit? }) returns create steps and the wallet’s related instances with typed arguments and availability. Follow data.nextCursor for another page. For a single-instance query, refreshOnEvents: true refreshes when that instance’s events arrive.

A missing wallet or instance disables the hooks that require it. Reads expose loading and error states; do not render a failed read as “no available actions.”

useProtocolParticipant(client, { instance, wallet }, options) reads that wallet’s participant state. useProtocolEvents(client, instanceId, { onEvent, onError }) follows events while mounted. Use refreshOnEvents on participant and allowed-step reads when the UI needs automatic re-reading.

These hooks read and subscribe. For mutations, use the generated client’s prepare/sign/submit flow in your event handler. An enabled button is not a guarantee that preparation will pass. Handle rejection, wallet cancellation, pending execution, and chain failure.

React SDK reference → · Compose a session in React → · Connect a frontend to the dev environment →