React SDK
The@yativo/crypto-sdk-react package wraps the TypeScript SDK with React hooks and pre-built components, giving you managed authentication state, data-fetching hooks, and drop-in UI widgets.
Installation
npm install @yativo/crypto-sdk-react
# or
yarn add @yativo/crypto-sdk-react
@yativo/crypto-sdk) is installed automatically as a peer dependency.
Provider Setup
Wrap your application (or the relevant subtree) withYativoProvider. This creates the SDK instance and makes it available to all hooks and components below.
Never expose
apiSecret in client-side code. Do not use NEXT_PUBLIC_YATIVO_API_SECRET or any environment variable that gets bundled into the browser. For React apps, use passwordless login (sdk.auth.login + sdk.auth.verifyOTP) for client-side auth — or have your backend exchange API key credentials and return a short-lived access token to the frontend.// app.tsx (or _app.tsx in Next.js)
import { YativoProvider } from "@yativo/crypto-sdk-react";
export default function App({ children }: { children: React.ReactNode }) {
return (
<YativoProvider
config={{
baseURL: "https://crypto-api.yativo.com/api/",
// Use passwordless login (sdk.auth.login + sdk.auth.verifyOTP) for client-side auth.
// Do NOT pass apiSecret here — it would be exposed in the browser bundle.
}}
>
{children}
</YativoProvider>
);
}
useYativo() — Authentication & SDK Access
Login is passwordless and happens in two steps: send an OTP with login(email), then verify it with verifyOTP(otp, email).
import { useYativo } from "@yativo/crypto-sdk-react";
function LoginForm() {
const { sdk, user, logout } = useYativo();
const [email, setEmail] = React.useState("");
const [otp, setOtp] = React.useState("");
const [step, setStep] = React.useState<"email" | "otp">("email");
const [error, setError] = React.useState<string | null>(null);
async function handleSendOtp(e: React.FormEvent) {
e.preventDefault();
try {
await sdk.auth.login(email);
setStep("otp");
} catch (err: any) {
setError(err.message);
}
}
async function handleVerifyOtp(e: React.FormEvent) {
e.preventDefault();
try {
await sdk.auth.verifyOTP(otp, email);
} catch (err: any) {
setError(err.message);
}
}
if (user) {
return (
<div>
<p>Welcome, {user.email}</p>
<button onClick={logout}>Log out</button>
</div>
);
}
if (step === "otp") {
return (
<form onSubmit={handleVerifyOtp}>
{error && <p style={{ color: "red" }}>{error}</p>}
<p>Enter the OTP sent to {email}</p>
<input
type="text"
value={otp}
onChange={(e) => setOtp(e.target.value)}
placeholder="6-digit OTP"
/>
<button type="submit">Verify</button>
</form>
);
}
return (
<form onSubmit={handleSendOtp}>
{error && <p style={{ color: "red" }}>{error}</p>}
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
<button type="submit">Send OTP</button>
</form>
);
}
Hook Return Values
| Property | Type | Description |
|---|---|---|
sdk | YativoSDK | The underlying TypeScript SDK instance |
client | YativoSDK | Alias for sdk |
user | User | null | Currently authenticated user, or null |
logout | () => void | Clear session |
useWallets() — Create and List Wallets
import { useWallets } from "@yativo/crypto-sdk-react";
function WalletManager({ accountId }: { accountId: string }) {
const { wallets, loading, error, createWallet, refresh } = useWallets(accountId);
async function handleCreate() {
await createWallet({ asset: "USDC", network: "SOLANA" });
}
if (loading) return <p>Loading wallets...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<button onClick={handleCreate}>+ Create USDC Wallet</button>
<button onClick={refresh}>Refresh</button>
<ul>
{wallets.map((w) => (
<li key={w.id}>
{w.asset} ({w.network}): {w.address}
</li>
))}
</ul>
</div>
);
}
useTransactions() — Send and List Transactions
import { useTransactions } from "@yativo/crypto-sdk-react";
function TransactionHistory({ accountId }: { accountId: string }) {
const { transactions, total, loading, error, sendFunds, refresh } =
useTransactions({ accountId, limit: 20 });
async function handleSend() {
await sendFunds({
fromWalletId: "wallet_xyz789",
toAddress: "BjhiXKt...",
amount: "50.00",
asset: "USDC",
network: "SOLANA",
});
refresh();
}
if (loading) return <p>Loading transactions...</p>;
return (
<div>
<button onClick={handleSend}>Send 50 USDC</button>
<p>Total transactions: {total}</p>
<ul>
{transactions.map((tx) => (
<li key={tx.id}>
{tx.amount} {tx.asset} — {tx.status} — {tx.createdAt}
</li>
))}
</ul>
</div>
);
}
useBalance() — Auto-Refreshing Balance Display
import { useBalance } from "@yativo/crypto-sdk-react";
function BalanceDisplay({ assetId }: { assetId: string }) {
// Auto-refresh every 30 seconds
const { balance, asset, loading, error } = useBalance(
assetId,
true, // autoRefresh
30000 // interval in ms
);
if (loading) return <span>...</span>;
if (error) return <span>Error loading balance</span>;
return (
<div className="balance-card">
<span className="amount">{balance}</span>
<span className="asset">{asset}</span>
</div>
);
}
useCards() — Card Management
import { useCards } from "@yativo/crypto-sdk-react";
function CardDashboard({ cardholderId }: { cardholderId: string }) {
const { cards, loading, createCard, freezeCard, unfreezeCard } =
useCards();
async function handleCreateCard() {
await createCard({
cardholderId,
currency: "USD",
label: "Travel expenses",
});
}
if (loading) return <p>Loading cards...</p>;
return (
<div>
<button onClick={handleCreateCard}>Issue New Card</button>
{cards.map((card) => (
<div key={card.id} className="card-item">
<p>•••• {card.last4}</p>
<p>Expires: {card.expiry}</p>
<p>Status: {card.status}</p>
{card.status === "ACTIVE" ? (
<button onClick={() => freezeCard(card.id)}>Freeze</button>
) : (
<button onClick={() => unfreezeCard(card.id)}>Unfreeze</button>
)}
</div>
))}
</div>
);
}
useSwap() — Swap Functionality
import { useSwap } from "@yativo/crypto-sdk-react";
function SwapForm() {
const { getQuote, executeSwap, loading, quote, result } = useSwap();
const [amount, setAmount] = React.useState("100");
async function handleQuote() {
await getQuote({
fromAsset: "USDC",
toAsset: "XDC",
amount,
network: "SOLANA",
});
}
async function handleExecute() {
if (!quote) return;
await executeSwap({
quoteId: quote.id,
fromWalletId: "wallet_xyz789",
toWalletId: "wallet_xdc001",
});
}
return (
<div>
<input
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Amount USDC"
/>
<button onClick={handleQuote} disabled={loading}>
Get Quote
</button>
{quote && (
<div className="quote-box">
<p>You receive: {quote.toAmount} XDC</p>
<p>Rate: {quote.rate}</p>
<p>Fee: {quote.fee} USDC</p>
<button onClick={handleExecute} disabled={loading}>
Execute Swap
</button>
</div>
)}
{result && <p>Swap complete! Status: {result.status}</p>}
</div>
);
}
useStandaloneIban() — IBAN Management
import { useStandaloneIban } from "@yativo/crypto-sdk-react";
function IbanManager({ customerId }: { customerId: string }) {
const { ibans, loading, createIban } = useStandaloneIban();
async function handleCreate() {
await createIban({
customerId,
currency: "EUR",
label: "EU Collections",
});
}
return (
<div>
<button onClick={handleCreate}>Create EUR IBAN</button>
{ibans.map((iban) => (
<div key={iban.id}>
<p>IBAN: {iban.iban}</p>
<p>BIC: {iban.bic}</p>
</div>
))}
</div>
);
}
useGasStations() — Gas Station Management
import { useGasStations } from "@yativo/crypto-sdk-react";
function GasStationDashboard() {
const { stations, loading, createStation } = useGasStations();
async function handleCreate() {
await createStation({
network: "SOLANA",
sponsorType: "ALL_WALLETS",
});
}
return (
<div>
<button onClick={handleCreate}>Create Gas Station</button>
{stations.map((s) => (
<div key={s.id}>
<p>Network: {s.network}</p>
<p>Balance: {s.balance}</p>
<p>Status: {s.status}</p>
</div>
))}
</div>
);
}
useAutoForwarding() — Auto-Forwarding Rules
import { useAutoForwarding } from "@yativo/crypto-sdk-react";
function AutoForwardingManager() {
const { rules, loading, createRule, updateRule, deleteRule } =
useAutoForwarding();
async function handleCreate() {
await createRule({
sourceWalletId: "wallet_xyz789",
destinationAddress: "BjhiXKt...",
asset: "USDC",
network: "SOLANA",
minAmount: "10.00",
});
}
if (loading) return <p>Loading rules...</p>;
return (
<div>
<button onClick={handleCreate}>Add Forwarding Rule</button>
{rules.map((rule) => (
<div key={rule.id}>
<p>
{rule.asset} on {rule.network} → {rule.destinationAddress}
</p>
<button onClick={() => updateRule(rule.id, { minAmount: "25.00" })}>
Update Min
</button>
<button onClick={() => deleteRule(rule.id)}>Delete</button>
</div>
))}
</div>
);
}
DepositWidget — Embedded Deposit UI
The DepositWidget renders a complete deposit flow: it displays a QR code, network selector, and deposit address — with real-time confirmation updates.
import { DepositWidget } from "@yativo/crypto-sdk-react";
function DepositPage({ walletId }: { walletId: string }) {
return (
<DepositWidget
walletId={walletId}
supportedAssets={["USDC", "XDC", "ETH"]}
onDepositConfirmed={(deposit) => {
console.log("Deposit confirmed:", deposit.amount, deposit.asset);
}}
theme={{
primaryColor: "#6366f1",
backgroundColor: "#ffffff",
borderRadius: "12px",
}}
/>
);
}
YativoCardWidget — Embedded Card Display (PSE)
The card widget renders sensitive card details (PAN, CVV, expiry) inside a secure sandboxed iframe. Card data never touches your JavaScript.
The widget requires an ephemeral token from your backend — never pass API credentials to client-side components.
import { YativoCardWidget } from "@yativo/crypto-sdk-react";
// ephemeralToken must come from your backend:
// const { token } = await sdk.cards.getEphemeralToken({ yativoCardId, cardId })
function CardViewer({ ephemeralToken }: { ephemeralToken: string }) {
return (
<div style={{ width: 380, height: 240 }}>
<YativoCardWidget
ephemeralToken={ephemeralToken}
theme={{
background: "#1a1a2e",
textColor: "#ffffff",
fontFamily: "Inter, sans-serif",
borderRadius: "16px",
}}
onReady={() => console.log("Card widget ready")}
onError={(err) => console.error("Widget error:", err)}
/>
</div>
);
}
Pre-Built UI Components
The React SDK ships utility components styled to match the Yativo design system:import {
YativoButton,
YativoCard,
YativoInput,
YativoLogo,
} from "@yativo/crypto-sdk-react";
function ExamplePage() {
return (
<YativoCard padding="24px">
<YativoLogo size={48} />
<YativoInput
label="Recipient Address"
placeholder="Enter wallet address"
type="text"
/>
<YativoButton variant="primary" onClick={() => {}}>
Send Funds
</YativoButton>
<YativoButton variant="secondary" onClick={() => {}}>
Cancel
</YativoButton>
</YativoCard>
);
}
Theme Customization
Pass atheme object to YativoProvider to apply a global theme to all SDK components and widgets:
<YativoProvider
config={{ baseURL: "https://crypto-api.yativo.com/api/" }}
theme={{
primaryColor: "#6366f1", // indigo
secondaryColor: "#8b5cf6", // violet
backgroundColor: "#0f172a", // dark slate
surfaceColor: "#1e293b",
textColor: "#f1f5f9",
errorColor: "#ef4444",
successColor: "#22c55e",
borderRadius: "12px",
fontFamily: "'Inter', sans-serif",
}}
>
{children}
</YativoProvider>
theme prop which merges with (and overrides) the global theme.
Complete Example — Next.js Dashboard Page
// pages/dashboard.tsx
import {
useYativo,
useWallets,
useBalance,
useTransactions,
DepositWidget,
YativoCardWidget,
} from "@yativo/crypto-sdk-react";
const ACCOUNT_ID = "acct_abc123";
const WALLET_ID = "wallet_xyz789";
const CARD_ID = "card_mno345";
export default function Dashboard() {
const { user, logout } = useYativo();
const { wallets, loading: wLoad } = useWallets(ACCOUNT_ID);
const { balance } = useBalance(WALLET_ID, true, 15000);
const { transactions } = useTransactions({ accountId: ACCOUNT_ID, limit: 5 });
if (!user) return <p>Please log in.</p>;
return (
<main>
<header>
<h1>Hello, {user.firstName}</h1>
<button onClick={logout}>Log out</button>
</header>
<section>
<h2>USDC Balance: {balance}</h2>
</section>
<section>
<h2>Wallets ({wallets.length})</h2>
{wLoad ? (
<p>Loading...</p>
) : (
wallets.map((w) => (
<p key={w.id}>{w.asset} — {w.address}</p>
))
)}
</section>
<section>
<h2>Deposit</h2>
<DepositWidget
walletId={WALLET_ID}
supportedAssets={["USDC"]}
onDepositConfirmed={(d) => alert(`Received ${d.amount} ${d.asset}`)}
/>
</section>
<section>
<h2>My Card</h2>
<YativoCardWidget cardId={CARD_ID} />
</section>
<section>
<h2>Recent Transactions</h2>
<ul>
{transactions.map((tx) => (
<li key={tx.id}>
{tx.amount} {tx.asset} — {tx.status}
</li>
))}
</ul>
</section>
</main>
);
}

