Skip to main content

Keyban React SDK

The Keyban React SDK provides a seamless way to integrate Keyban’s blockchain services into your React applications. It offers React hooks and components to manage accounts, perform transactions, retrieve balances, interact with NFTs, and more — designed to be used alongside the Keyban JavaScript SDK (@keyban/sdk-base).

This README is a concise, practical entry point with examples and references to the most used APIs. For the complete, TypeScript documentation, see https://docs.keyban.io/api/sdk-react


Installation

Using npm:

npm install @keyban/sdk-react @keyban/sdk-base

Using yarn:

yarn add @keyban/sdk-react @keyban/sdk-base

If you use a monorepo, prefer your workspace tooling (pnpm / yarn workspaces) to link packages locally.


Basic usage

The React SDK exposes a provider and hooks. Hooks rely on React Suspense for data fetching, so wrap consuming components in a Suspense boundary.

Example: KeybanProvider + Suspense

import React, { Suspense } from "react";
import { KeybanProvider, KeybanNetwork } from "@keyban/sdk-react";

export function App() {
return (
<Suspense fallback={<div>Loading…</div>}>
<KeybanProvider appId="your-app-id" network={KeybanNetwork.EthereumAnvil}>
{/* your components that use Keyban hooks */}
</KeybanProvider>
</Suspense>
);
}

Notes:

  • KeybanProvider accepts the same config as KeybanClient (appId, network, optional clientShareProvider).
  • If you provide a custom ClientShareProvider implement the interface from @keyban/sdk-base.

Common hooks and examples

Access the client:

import React, { useEffect } from "react";
import { useKeybanClient } from "@keyban/sdk-react";

function InitAccount() {
const client = useKeybanClient();

useEffect(() => {
let mounted = true;
client
.initialize()
.then((account) => {
if (mounted) console.log("Account address:", account.address);
})
.catch((err) => console.error("Failed to initialize account", err));
return () => {
mounted = false;
};
}, [client]);

return null;
}

Get current account:

import { useKeybanAccount } from "@keyban/sdk-react";

function AccountAddress() {
const [account, error] = useKeybanAccount();
if (error) throw error;
return <div>{account.address}</div>;
}

Get balance (native):

import {
useKeybanAccount,
useKeybanAccountBalance,
FormattedBalance,
} from "@keyban/sdk-react";

function Balance() {
const [account] = useKeybanAccount();
const [balance] = useKeybanAccountBalance(account);
return (
<FormattedBalance balance={{ raw: BigInt(balance), isNative: true }} />
);
}

Transfer native:

import { useKeybanAccount } from "@keyban/sdk-react";

async function sendOneEth() {
const [account] = useKeybanAccount();
const txHash = await account.transfer(
"0xRecipient",
1_000_000_000_000_000_000n,
);
console.log(txHash);
}

Transfer ERC-20:

const tx = await account.transferERC20({
contractAddress: "0xToken",
to: "0xRecipient",
value: 1_000_000n, // token smallest unit
});

Use formatted components/hooks:

  • FormattedBalance component and useFormattedBalance hook are provided to render balances consistently.

Short API reference (most used hooks / signatures)

  • useKeybanClient(): KeybanClient
  • useKeybanAccount(): ApiResult<KeybanAccount>
  • useKeybanAccountBalance(account): ApiResult<string>
  • useKeybanAccountTokenBalances(account, options?): ApiResult<PaginatedData<KeybanTokenBalance>, PaginationExtra>
  • useKeybanAccountNfts(account, options?): ApiResult<PaginatedData<KeybanNftBalance>, PaginationExtra>
  • useKeybanAccountTransferHistory(account, options?): ApiResult<PaginatedData<KeybanAssetTransfer>, PaginationExtra>
  • useKeybanAuth(): AuthContext
  • FormattedBalance(props: { balance: Balance; token?: KeybanToken }): JSX.Element
  • useFormattedBalance(balance, token?): string

For full types see the generated d.ts in the package or the online docs.


GraphQL / data imports

The SDK exports ready-to-use GraphQL documents via @keyban/sdk-base/graphql. Typical documents:

  • walletBalanceDocument
  • walletTokenBalancesDocument
  • tokenBalancesSubscriptionDocument
  • walletNftsDocument
  • nftBalancesSubscriptionDocument

Example: query token balances

import { walletTokenBalancesDocument } from "@keyban/sdk-base/graphql";
const { data } = await client.apolloClient.query({
query: walletTokenBalancesDocument,
variables: { walletId: account.address, first: 20 },
});

Use subscriptions to receive real-time updates; remember to unsubscribe.


Error handling

The SDK uses typed errors. Common classes/enums:

  • SdkError / SdkErrorTypes (business/domain errors)
  • CryptoError / CryptoErrorType
  • JwtError / JwtErrorType
  • IFrameApiError / IFrameApiErrorType

Example pattern:

import { SdkError, SdkErrorTypes } from "@keyban/sdk-base";

try {
await account.transfer(to, value);
} catch (err) {
if (err instanceof SdkError) {
if (err.type === SdkErrorTypes.InsufficientFunds) {
// handle
}
}
throw err;
}

When using hooks, errors are returned as the second tuple element (ApiResult). For Suspense-based hooks you may get thrown promises; wrap with error boundaries if needed.


ClientShareProvider (custom storage)

If you need to control where client shares are persisted, implement ClientShareProvider from @keyban/sdk-base and pass it to KeybanProvider.

Minimal interface:

interface ClientShareProvider {
get(key: string): Promise<string | null>;
set(key: string, clientShare: string): Promise<void | unknown>;
}

Security recommendations:

  • Protect server endpoints with auth.
  • Use per-user keys.
  • Avoid exposing raw client shares in logs.

SSR / Suspense notes

  • Hooks rely heavily on React Suspense. For SSR (Next.js), ensure data fetching strategies are compatible with your SSR approach — you may need to initialize the client on the server and hydrate on the client.
  • Components that use hooks should be wrapped in <Suspense> with sensible fallbacks.

Development & contributing (quick)

Common commands (adjust to repo tooling):

  • Build: npm run build
  • Type check: npm run typecheck
  • Tests: npm test
  • Lint: npm run lint

If the repo uses pnpm/workspaces, prefer pnpm workspace commands to link packages locally.


Compatibility & bundling

  • React 18+ required (for Suspense behavior).
  • Works with modern bundlers (Vite, webpack, rollup). Follow monorepo build scripts for packaging.
  • Node: runtime APIs used only in server-side helpers; client code targets browsers.