@avax_suzaku/lst-widget-react
v1.0.0
Published
Drop-in Suzaku staking widget for React apps.
Downloads
95
Readme
@avax_suzaku/lst-widget-react
Drop-in Suzaku staking widget for React apps.
- No iframe
- No Tailwind required in the host app (this package ships a compiled, scoped CSS bundle)
- Host app controls the wallet (widget uses the host’s
wagmicontext)
Install
npm i @avax_suzaku/lst-widget-reactThis automatically installs @avax_suzaku/widget-core as a dependency.
1) Import the widget CSS (required)
Import once, globally.
Next.js (App Router)
In app/layout.tsx:
import "@avax_suzaku/lst-widget-react/styles.css";Vite / CRA / Remix
Import in your main entry file (src/main.tsx, src/index.tsx, app/root.tsx, etc.):
import "@avax_suzaku/lst-widget-react/styles.css";2) Provide required providers (host app owns wallet)
The widget expects these contexts from the host app:
WagmiProvider: requiredQueryClientProvider: required (the widget uses React Query internally)RainbowKitProvider: optional (only if you want RainbowKit UI in your host app)
Minimal provider setup:
"use client";
import { WagmiProvider } from "wagmi";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
export function AppProviders({
wagmiConfig,
children,
}: {
wagmiConfig: any;
children: React.ReactNode;
}) {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</WagmiProvider>
);
}3) Render the widget
import { SuzakuWidget } from "@avax_suzaku/lst-widget-react";
import type { SuzakuWidgetConfig } from "@avax_suzaku/lst-widget-react";
export default function Page() {
const config: SuzakuWidgetConfig = /* ... */;
return <SuzakuWidget config={config} className="" />;
}Notes:
classNameis optional.- The widget automatically applies
config.themeas CSS variables on its root element (you do not need to wrap it in another<div>to theme it).
4) Config (SuzakuWidgetConfig)
Type import:
import type { SuzakuWidgetConfig } from "@avax_suzaku/lst-widget-react";The widget takes a single config object containing:
contracts: all addresses + rewards configurationinfo: display strings and chain/explorer info (e.g. modal title, explorer URL)images(optional): logos (prefer absolute URLs)theme(optional but recommended): colors/padding/radius/fonts used to style the widget
Contracts rules
- Use
nullfor optional single addresses you don’t have:nativeRewards,merklRewards,lstWrapper
- Use
nullfor rewards token lists when that rewards system is not configured:nativeRewardsTokens: nullmerklRewardsTokens: null
- If the rewards system is configured, pass an array:
nativeRewardsTokens: []merklRewardsTokens: []format: {address, associatedCampaign, associatedDatabase} check Merkl
5) Recommended config structure (4 files)
src/
suzaku-config/
contracts.ts
info.ts
images.ts
theme.ts
widgetConfig.tssrc/suzaku-config/contracts.ts
import type { SuzakuWidgetConfig } from "@avax_suzaku/lst-widget-react";
export const contracts: SuzakuWidgetConfig["contracts"] = {
underlying: "0x...",
collateral: "0x...",
vault: "0x...",
vaultHelper: "0x...",
priceToken: "0x...",
lstWrapper: null,
nativeRewards: null, // address of the rewards contract
merklRewards: null, // address of the merkl distributor contract on this chain
nativeRewardsTokens: null, // list of rewards tokens || null
merklRewardsTokens: null, // list of struct {address, associatedCampaign, associatedDatabase} || null
};src/suzaku-config/info.ts
import type { SuzakuWidgetConfig } from "@avax_suzaku/lst-widget-react";
export const info: SuzakuWidgetConfig["info"] = {
projectId: "your-reown-project-id",
projectName: "Your Project",
appTitle: "Your Staking",
chain: "avalanche", // or "fuji"
explorer: "https://snowscan.xyz",
};src/suzaku-config/images.ts
import type { SuzakuWidgetConfig } from "@avax_suzaku/lst-widget-react";
export const images: SuzakuWidgetConfig["images"] = {
logoPoweredBy: "https://your-cdn/logo-powered-by.svg",
logoRewardsTokens: [],
};src/suzaku-config/theme.ts
import type { SuzakuWidgetConfig } from "@avax_suzaku/lst-widget-react";
export const theme: SuzakuWidgetConfig["theme"] = {
base: "#313131",
defaultFontColor: "#ffffff",
modal: "#1b1b1b",
primary: "#ff6600",
secondary: "#ff6600",
header: "#ffffff",
footer: "#313131",
font: "Source Code Pro, monospace",
fontSizes: {
basic: "1rem",
button: "0.85rem",
label: "0.85rem",
subtitle: "1.125rem",
title: "1.5rem",
},
uppercase: true,
paddings: { basic: "1.5rem", modal: "1rem", gap: "0.75rem" },
radius: { lg: "2rem", md: "1.25rem" },
};src/suzaku-config/widgetConfig.ts
import type { SuzakuWidgetConfig } from "@avax_suzaku/lst-widget-react";
import { contracts } from "./contracts";
import { info } from "./info";
import { images } from "./images";
import { theme } from "./theme";
export const widgetConfig: SuzakuWidgetConfig = {
contracts,
info,
images,
theme,
};6) Example Next.js page using RainbowKit connect button
"use client";
import "@avax_suzaku/lst-widget-react/styles.css";
import { ConnectButton } from "@rainbow-me/rainbowkit";
import { widgetConfig } from "@/suzaku/widgetConfig";
export default function Page() {
return (
<div className="flex flex-col min-h-screen w-full items-center justify-center gap-6 bg-white p-6">
<SuzakuWidget config={widgetConfig} />
<ConnectButton
showBalance={false}
accountStatus="full"
chainStatus="full"
/>
</div>
);
}Troubleshooting
Widget looks unstyled
- Ensure
@avax_suzaku/lst-widget-react/styles.cssis imported once in a global entry. - Restart the dev server after installing/updating the package.
- Ensure
Wrong network
- Ensure the host app’s
wagmiconfig uses the same chain asconfig.info.chain.
- Ensure the host app’s
Images don’t load
- Use absolute URLs (recommended), or ensure relative paths resolve in the host app.
