npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rakurai/rakurai-stake-sdk

v1.3.0

Published

TypeScript SDK for Rakurai liquid SOL staking on Solana. Ships a ready-made React modal and a framework-agnostic core for custom integrations.

Readme

@rakurai/rakurai-stake-sdk

A TypeScript SDK for Rakurai staking on Solana. It provides two things:

  1. Liquid staking (raiSOL). Helper functions and a ready-made React modal for staking and unstaking SOL through Rakurai's liquid staking pool.
  2. Auto-compound. Tools for validators running the Rakurai client to let their stakers turn on auto-compounding, which restakes rewards automatically every epoch.

You keep full control of signing and sending transactions. The SDK never holds private keys. It calls Rakurai's HTTP API where needed, hands you standard @solana/web3.js transactions, and the auto-compound instruction builder runs fully offline.

Contents

Requirements

  • @solana/web3.js ^1.98.0 (peer dependency).
  • For the React modal: React >=18, plus @solana/wallet-adapter-react, @solana/wallet-adapter-react-ui, and @solana/wallet-adapter-wallets.
  • Auto-compound works on Solana mainnet only, and only for stake delegated to a validator that runs the Rakurai client.

Installation

Core SDK (framework-agnostic, works in the browser or in Node):

npm install @rakurai/rakurai-stake-sdk @solana/web3.js

React modal (adds the wallet-adapter packages):

npm install @rakurai/rakurai-stake-sdk @solana/web3.js \
  @solana/wallet-adapter-react @solana/wallet-adapter-react-ui \
  @solana/wallet-adapter-wallets

Package entry points

The SDK ships two independent entry points. Import from the one you need.

| Import path | Contents | Environment | |---|---|---| | @rakurai/rakurai-stake-sdk | API functions, types, and the auto-compound instruction builder | Browser or Node | | @rakurai/rakurai-stake-sdk/react | The React provider, hooks, and UI components | Browser (React) | | @rakurai/rakurai-stake-sdk/react/styles.css | Stylesheet for the React components | Import once in your app |

The core entry has no React or wallet-adapter dependency, so it is safe to use in a backend. Brand images are inlined into the React bundle, so there are no asset files to copy into your project.


Liquid staking modal (React)

The modal handles wallet connection, balances, APY and price display, and the stake and unstake transactions. You wire up the provider and open the modal; the SDK does the rest.

What you can customize

You can change the title, description, and button labels; the header logo and token icons; all colors (background, text, the call-to-action gradient, borders, tabs, and overlay); the Learn More link; the default unstake mode; and your referral code.

The Powered by Rakurai footer is always shown and cannot be changed or hidden. This is the only fixed element.

Step 1: Set up wallet providers

Set up the Solana wallet adapters once, near the root of your app, and import both stylesheets. Add any wallets you want to support to the wallets array; they appear automatically in the modal's wallet picker.

// main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';
import {
  PhantomWalletAdapter,
  SolflareWalletAdapter,
  BackpackWalletAdapter,
} from '@solana/wallet-adapter-wallets';

import '@solana/wallet-adapter-react-ui/styles.css';
import '@rakurai/rakurai-stake-sdk/react/styles.css';

import { App } from './App';

const wallets = [
  new PhantomWalletAdapter(),
  new SolflareWalletAdapter(),
  new BackpackWalletAdapter(),
];

ReactDOM.createRoot(document.getElementById('root')!).render(
  <ConnectionProvider endpoint="https://api.mainnet-beta.solana.com">
    <WalletProvider wallets={wallets} autoConnect>
      <WalletModalProvider>
        <App />
      </WalletModalProvider>
    </WalletProvider>
  </ConnectionProvider>
);

The SDK works with any wallet that supports the Solana Wallet Adapter standard (Phantom, Solflare, Backpack, Glow, Ledger, Coinbase Wallet, and others). To offer more wallets, add their adapters to the wallets array. No other change is required.

Use a dedicated RPC endpoint (for example Helius, Triton, QuickNode, or Alchemy) for production. Solana's shared public endpoint (https://api.mainnet-beta.solana.com) throttles browser traffic and can return errors under load.

Step 2: Add the provider and open the modal

Wrap your app in RakuraiStakeProvider and open the modal from any component inside it.

// App.tsx
import {
  RakuraiStakeProvider,
  useWalletAdapterBridge,
  useRakuraiStakeModal,
} from '@rakurai/rakurai-stake-sdk/react';

function StakeButton() {
  const { open } = useRakuraiStakeModal();
  return <button onClick={() => open('stake')}>Stake SOL</button>;
}

export function App() {
  const walletBridge = useWalletAdapterBridge();

  return (
    <RakuraiStakeProvider wallet={walletBridge}>
      <StakeButton />
      {/* your existing page content */}
    </RakuraiStakeProvider>
  );
}

That completes the integration. When the user opens the modal, the SDK does the following automatically:

  • Opens the wallet picker on Connect Wallet, and shows Disconnect Wallet once connected.
  • Fetches SOL and raiSOL balances, APY, and the raiSOL price.
  • Builds, signs, sends, and confirms stake and unstake transactions.
  • Refreshes balances after a successful transaction.

Call open('unstake') to open the unstake tab instead of the stake tab.

Step 3: Customize the theme (optional)

Pass a theme object to match your branding. Every field is optional; omit any you do not need.

<RakuraiStakeProvider
  wallet={walletBridge}
  theme={{
    // Text and labels
    title: 'Stake with MyApp',
    description: 'Earn raiSOL yield, compounded every epoch.',
    stakeBtnLabel: 'Stake SOL',
    unstakeBtnLabel: 'Unstake',
    connectBtnLabel: 'Connect Wallet',
    disconnectBtnLabel: 'Disconnect Wallet',
    learnMoreLabel: 'Learn More',
    learnMoreUrl: 'https://yourapp.com/staking',

    // Icons
    logoUrl: 'https://yourapp.com/logo.png',
    solTokenIconUrl: 'https://yourapp.com/sol.png',
    raiSolTokenIconUrl: 'https://yourapp.com/raisol.png',

    // Colors
    colors: {
      bg: 'hsl(222 47% 11%)',          // modal background
      text: 'hsl(210 40% 98%)',        // primary text
      textMuted: 'hsl(215 20% 65%)',   // secondary text
      ctaFrom: 'rgb(59, 130, 246)',    // CTA gradient start
      ctaTo: 'rgb(34, 197, 94)',       // CTA gradient end
      ctaText: '#ffffff',              // CTA button text
      inputBg: 'hsl(217 33% 17%)',     // input background
      borderColor: 'hsl(217 33% 20%)', // modal and input borders
      tabActiveBg: 'linear-gradient',  // active tab indicator
      overlay: 'rgba(0,0,0,0.75)',     // backdrop
      zIndex: 1000,                    // keep at 1000 so the wallet picker (1040) stays on top
    },
  }}
>
  <StakeButton />
</RakuraiStakeProvider>

To adjust the modal size, override these CSS custom properties on .rakurai-stake-modal-root in your own stylesheet:

.rakurai-stake-modal-root {
  --rakurai-modal-min-height: 600px; /* default 480px */
  --rakurai-modal-max-width: 520px;  /* default 480px */
}

The modal is responsive: it expands when content needs more room, and on small screens it reduces padding and caps its height to fit the viewport.

Step 4: Other provider props (optional)

<RakuraiStakeProvider
  wallet={walletBridge}
  unstakeMode="native"     // 'native' (unstakes over an epoch, no fee) or 'jupiter' (instant swap)
  referralCode="MYPARTNER" // reports confirmed stakes and unstakes to the Rakurai campaign API
  theme={{ /* see Step 3 */ }}
>
  <YourApp />
</RakuraiStakeProvider>

Next.js (App Router)

Add "use client" to any file that imports from the SDK, and place the wallet and Rakurai providers in a client component.

// components/Providers.tsx
'use client';

import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';
import {
  PhantomWalletAdapter,
  SolflareWalletAdapter,
  BackpackWalletAdapter,
} from '@solana/wallet-adapter-wallets';
import { RakuraiStakeProvider, useWalletAdapterBridge } from '@rakurai/rakurai-stake-sdk/react';

import '@solana/wallet-adapter-react-ui/styles.css';
import '@rakurai/rakurai-stake-sdk/react/styles.css';

const wallets = [
  new PhantomWalletAdapter(),
  new SolflareWalletAdapter(),
  new BackpackWalletAdapter(),
];

function RakuraiWrapper({ children }: { children: React.ReactNode }) {
  const walletBridge = useWalletAdapterBridge();
  return <RakuraiStakeProvider wallet={walletBridge}>{children}</RakuraiStakeProvider>;
}

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ConnectionProvider endpoint="https://api.mainnet-beta.solana.com">
      <WalletProvider wallets={wallets} autoConnect>
        <WalletModalProvider>
          <RakuraiWrapper>{children}</RakuraiWrapper>
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  );
}

Then wrap the body of app/layout.tsx with <Providers>.

Integration checklist

  • [ ] Installed all packages.
  • [ ] Added wallet adapters to the wallets array.
  • [ ] Imported @rakurai/rakurai-stake-sdk/react/styles.css once.
  • [ ] RakuraiStakeProvider sits inside ConnectionProvider, WalletProvider, and WalletModalProvider.
  • [ ] useWalletAdapterBridge() is called inside the wallet providers.
  • [ ] useRakuraiStakeModal() is called inside RakuraiStakeProvider.
  • [ ] Your button opens the modal, and Connect Wallet opens the wallet picker.
  • [ ] After connecting, balances and APY appear, and stake and unstake work end to end.

Auto-compound

Auto-compound restakes a user's staking rewards every epoch, so their stake grows on its own. This section is written to be followed step by step. You do not need to understand Solana internals to integrate it.

Auto-compound only works for stake delegated to a validator that runs the Rakurai client. Throughout this section, replace YOUR_VOTE_ACCOUNT with your validator's vote account. This is the address that uniquely identifies your validator; you can find it in your validator dashboard or by running solana validators.

Before you start

You will need:

  1. Your validator's vote account address (YOUR_VOTE_ACCOUNT).
  2. A connected wallet in your app, through @solana/wallet-adapter-react.
  3. The way your app already sends Solana transactions. Signing and broadcasting stay on your side. Any RPC endpoint your app already uses works; a dedicated provider gives a smoother experience than the shared public endpoint.

Choose an integration path

| Your goal | Use | |---|---| | A ready-made screen where users turn auto-compound on and off for stake they already have | Part 1: the modal | | A checkbox on your own staking form so users opt in while they stake | Part 2: the builder | | No Rakurai UI, just the logic (for example in a backend) | Part 3: headless |

You can combine more than one.

Part 1: The Manage Auto-Compound screen

A drop-in popup that lists the user's stake on your validator, lets them switch auto-compound on or off, and submits one transaction.

Step 1. Import the stylesheet once, in your app entry or root layout:

import '@rakurai/rakurai-stake-sdk/react/styles.css';

Step 2. Wrap your app with the provider. It must sit inside your wallet-adapter providers (ConnectionProvider, then WalletProvider, then WalletModalProvider). In Next.js, add 'use client' at the top of the file.

import {
  RakuraiStakeProvider,
  useWalletAdapterBridge,
} from '@rakurai/rakurai-stake-sdk/react';

function AutoCompoundProvider({ children }) {
  const wallet = useWalletAdapterBridge();
  return (
    <RakuraiStakeProvider wallet={wallet} validatorVoteAccount="YOUR_VOTE_ACCOUNT">
      {children}
    </RakuraiStakeProvider>
  );
}

Step 3. Add a button that opens the screen, anywhere inside the provider:

import { useRakuraiStakeModal } from '@rakurai/rakurai-stake-sdk/react';

function ManageButton() {
  const { openAutoCompound } = useRakuraiStakeModal();
  return <button onClick={() => openAutoCompound()}>Manage Auto-Compound</button>;
}

The popup lists the user's active stake accounts on your validator only, each with a checkbox and an Update button. The user selects the accounts they want and clicks Update, which triggers one wallet approval. The Powered by Rakurai mark is always shown.

To manage a different validator without changing the provider, pass a vote account to the call: openAutoCompound('SOME_OTHER_VOTE_ACCOUNT'). This value overrides the provider default for that open.

Part 2: An auto-compound checkbox on your own staking form

If your app already lets users stake natively, you enable auto-compound by adding one instruction to your stake transaction, right after the instruction that delegates to your validator.

Step 1 (optional). Show the branded checkbox:

import { AutoCompoundToggle } from '@rakurai/rakurai-stake-sdk/react';

<AutoCompoundToggle checked={autoCompoundOn} onChange={setAutoCompoundOn} />

Step 2. When the checkbox is on, add the instruction to your stake transaction:

import { buildEnableAutoCompoundInstruction } from '@rakurai/rakurai-stake-sdk';

// Your transaction already has: createAccount, then delegate(YOUR_VOTE_ACCOUNT).
if (autoCompoundOn) {
  tx.add(
    buildEnableAutoCompoundInstruction({
      stakeAccount,               // the stake account you just created
      stakeAuthority: userWallet, // the user's wallet, which must sign
    })
  );
}
// The user then signs the transaction and your app sends it, the same way it sends any stake transaction.

The following must all be true, or the transaction will fail:

  • The stake account is delegated to your validator's vote account.
  • The auto-compound instruction comes after the delegate instruction in the same transaction.
  • The user's wallet is the stake authority and signs the transaction. The user keeps withdraw authority.
  • Signing and sending stay on your side.

Part 3: Headless (no Rakurai UI)

Import only from @rakurai/rakurai-stake-sdk (never /react). No React, no wallet adapter, and no CSS are involved; the only dependency is @solana/web3.js.

import {
  buildEnableAutoCompoundInstruction, // enable while staking (see Part 2)
  getNativeStakeAccounts,             // list a wallet's stake and status on a validator
  updateAutoCompound,                 // turn on or off for existing accounts
} from '@rakurai/rakurai-stake-sdk';

// List the wallet's stake accounts on your validator.
const accounts = await getNativeStakeAccounts({ pubkey, voteAccount: 'YOUR_VOTE_ACCOUNT' });

// Build an unsigned transaction to turn auto-compound on or off. You sign and broadcast it.
const tx = await updateAutoCompound({
  pubkey,
  accounts: [{ stakeAccountAddress, enable: true }],
});

getNativeStakeAccounts and updateAutoCompound call Rakurai's API. buildEnableAutoCompoundInstruction does not touch the network. In all cases, you own signing and sending.

Customize colors, titles, and logos

You can rebrand the colors, titles, and logos of the auto-compound UI. Everything else is fixed, including the Powered by Rakurai mark, which is always shown. Pass a theme object to RakuraiStakeProvider:

<RakuraiStakeProvider
  wallet={wallet}
  validatorVoteAccount="YOUR_VOTE_ACCOUNT"
  theme={{
    // Titles
    autoCompoundTitle: 'Auto-Compound',
    autoCompoundDescription: 'Grow your stake automatically every epoch.',
    // Logo (the modal's header icon): any URL or imported image
    logoUrl: '/my-logo.png',
    // Colors
    colors: {
      bg: '#0b1120',              // modal background
      text: '#ffffff',           // main text
      textMuted: '#94a3b8',      // secondary text
      ctaFrom: '#6d28d9',        // gradient start (buttons and checkboxes)
      ctaTo: '#22c55e',          // gradient end
      ctaText: '#ffffff',        // button text
      inputBg: '#111827',        // row and input background
      borderColor: '#1f2937',
      overlay: 'rgba(0,0,0,0.7)', // dimmed backdrop
    },
  }}
>
  <App />
</RakuraiStakeProvider>

| What you can change | How | |---|---| | Colors | theme.colors: background, text, the gradient (buttons and checkboxes), borders, and overlay | | Titles | theme.autoCompoundTitle and theme.autoCompoundDescription | | Logo | theme.logoUrl (the modal header icon) | | Powered by Rakurai | Fixed. It cannot be changed or hidden. |

For the standalone checkbox (AutoCompoundToggle), set its label with the label prop, and its colors with className (target .rakurai-ac-toggle in your CSS) or the style prop:

<AutoCompoundToggle checked={on} onChange={setOn} label="Auto-compound rewards" className="my-toggle" />

Requirements and limits

  • Stake must be delegated to a validator's vote account that runs the Rakurai client.
  • The user's wallet is the stake authority and signs the transaction. It keeps withdraw authority.
  • In Part 2, the enable instruction must come after the delegate instruction.
  • The native staking minimum is 1 SOL.
  • Mainnet only. The program ID is fixed inside the SDK (SmArtSKbXQjHpXHDfGpzTayVtvwKnVWLSu13ha2R5uF); integrators never pass it.

Troubleshooting

| Symptom | Cause and fix | |---|---| | 403 Access forbidden when sending | Your app is sending through Solana's shared public endpoint, which throttles browser traffic. Point your ConnectionProvider at a dedicated RPC endpoint. This is on the app side, not the SDK. | | Next.js error about a Client Component | Add 'use client' at the top of the file where you use the Rakurai React components. | | Logos or icons not showing | They are inlined into the bundle, so no setup is needed. Confirm you imported @rakurai/rakurai-stake-sdk/react/styles.css. | | Modal shows "No validator selected" | Pass validatorVoteAccount on the provider, or pass a vote account to openAutoCompound('YOUR_VOTE_ACCOUNT'). | | Modal list is empty | That wallet has no active stake on that validator yet. The user needs to stake first. |


API reference

Import functions and types from the package entry:

import { liquidStake, RaiSOLStakeError } from '@rakurai/rakurai-stake-sdk';
import type { StakeParams } from '@rakurai/rakurai-stake-sdk';

All functions throw RaiSOLStakeError on failure. Handle it with instanceof RaiSOLStakeError, and read error.message and the optional error.code (an HTTP-style status when available). Amounts passed to staking functions are integers in lamports (1 SOL is 1000000000).

Liquid staking and data

liquidStake(params: StakeParams): Promise<VersionedTransaction>

Requests a liquid-stake transaction from the API and returns it as a versioned transaction.

  • Parameters: { pubkey: string; amount: number }. pubkey is the wallet address (base58); amount is in lamports.
  • After: Sign with the user's wallet and send.
const tx = await liquidStake({ pubkey, amount: 1_000_000_000 });

liquidUnstake(params: UnstakeParams): Promise<UnstakeResult>

Requests a native unstake transaction and the stake-account keypair that must co-sign it.

  • Parameters: { pubkey: string; amount: number }.
  • Returns: { transaction, stakeAccountKeypair }.
  • After: Co-sign with stakeAccountKeypair first (transaction.sign([stakeAccountKeypair]), or pass it as extraSigners to your wallet bridge), then sign with the user's wallet and send.

liquidUnstakeJupiter(params: UnstakeJupiterParams): Promise<VersionedTransaction>

Unstakes instantly through a Jupiter swap route.

  • Parameters: { pubkey: string; amount: number }.
  • After: Sign with the user's wallet and send.

updateCampaign(params: CampaignUpdateParams): Promise<CampaignUpdateResponse>

Reports a confirmed stake or unstake to the campaign and referral backend.

  • Parameters: { address, amount, txn_sig, is_stake, referral_code }. Set is_stake to true for a stake and false for an unstake.
  • Returns: { message?, error? }.

getReferral(referral_code: string): Promise<ReferralDetailsResponse>

Fetches referral stats for a code.

  • Returns: { referral_code?, no_of_referrals?, referral_staked_amount?, error? }.

getRaiSOLApy(): Promise<number>

Returns the APY for Rakurai's liquid staking pool (for example 7.11).

getRaiSOLPrice(): Promise<number>

Returns the price of 1 raiSOL in SOL (for example 1.263).

getWalletSolBalance(params: WalletBalanceParams): Promise<number>

Returns a wallet's SOL balance in SOL units. The API returns lamports; the SDK divides by 1e9 before returning.

  • Parameters: { pubkey: string }.

getWalletRaiSOLBalance(params: WalletBalanceParams): Promise<number>

Returns a wallet's raiSOL balance in raiSOL units. The API returns 9-decimal units; the SDK divides by 1e9 before returning.

  • Parameters: { pubkey: string }.

Auto-compound

For step-by-step usage, see Auto-compound above.

buildEnableAutoCompoundInstruction(params): TransactionInstruction

Builds the instruction that enables auto-compound on a native stake account. It is pure and offline: no network calls and no keypairs, so it is safe in a browser or a Node backend. The program ID is fixed inside the SDK.

  • Parameters: { stakeAccount: PublicKey | string; stakeAuthority: PublicKey | string }.
  • Returns: a TransactionInstruction (synchronous, not a promise).
  • After: Append it to your stake transaction after the delegate instruction. The user's wallet (stakeAuthority) must sign.
tx.add(buildEnableAutoCompoundInstruction({ stakeAccount, stakeAuthority: userWallet }));

getNativeStakeAccounts(params): Promise<NativeStakeAccount[]>

Lists a wallet's active native stake accounts delegated to Rakurai-powered validators, with their current auto-compound status. Pass voteAccount to restrict the result to one validator.

  • Parameters: { pubkey: string; voteAccount?: string }.
  • Returns: an array of { stakeAccountAddress, activeStake, autoCompoundEnabled, voteAccount, name, image }. activeStake is in lamports.

updateAutoCompound(params): Promise<VersionedTransaction>

Builds a transaction that enables or disables auto-compound on existing stake accounts. The enable-or-disable decision is computed server-side, because disabling depends on on-chain transient-stake state.

  • Parameters: { pubkey: string; accounts: AutoCompoundAccountUpdate[] }, where each account is { stakeAccountAddress: string; enable: boolean }.
  • Returns: an unsigned VersionedTransaction.
  • After: Sign with the owner wallet (which is the staker and withdraw authority) and broadcast.

The core entry also exports the PDA helpers deriveTurboConfigPda, deriveTurboTransientPda, and deriveTurboPositionPda, plus the constants TURBO_STAKE_PROGRAM_ID and ENABLE_AUTOCOMPOUND_DISCRIMINATOR, for advanced use.

React exports

Import from @rakurai/rakurai-stake-sdk/react.

RakuraiStakeProvider

interface RakuraiStakeProviderProps {
  children: ReactNode;
  wallet: WalletBridge;
  unstakeMode?: 'native' | 'jupiter'; // default: 'native'
  referralCode?: string;
  theme?: ThemeConfig;
  validatorVoteAccount?: string;      // default validator for the auto-compound modal
}

useRakuraiStakeModal()

const { open, close, openAutoCompound, closeAutoCompound } = useRakuraiStakeModal();

open();                              // open the stake tab
open('unstake');                     // open the unstake tab
openAutoCompound();                  // open the auto-compound modal (uses validatorVoteAccount)
openAutoCompound('VOTE_ACCOUNT');    // open it for a specific validator
close();
closeAutoCompound();

useWalletAdapterBridge(options?)

Returns a ready-made WalletBridge for @solana/wallet-adapter-react apps.

const walletBridge = useWalletAdapterBridge({
  solBalance: 2.5,    // optional: overrides the API fetch
  raisolBalance: 1.3, // optional: overrides the API fetch
});

AutoCompoundToggle

A standalone branded on/off control for your own staking form. It is presentational only; pair it with buildEnableAutoCompoundInstruction.

interface AutoCompoundToggleProps {
  checked: boolean;
  onChange: (next: boolean) => void;
  disabled?: boolean;
  label?: string;             // default: 'Auto-compound rewards'
  className?: string;
  style?: CSSProperties;
}

Endpoints called by the modal

The liquid staking modal calls these endpoints automatically.

| Trigger | Method | Endpoint | |---|---|---| | Modal opens | GET | /api/v1/price/raisol | | Modal opens | GET | /api/v1/validator/apy-liquid | | Wallet connected | POST | /api/v1/wallet/balance/sol | | Wallet connected | POST | /api/v1/wallet/balance/raisol | | User stakes | POST | /api/v1/staking/liquid/stake | | User unstakes (native) | POST | /api/v1/staking/liquid/unstake | | User unstakes (Jupiter) | POST | /api/v1/staking/liquid/jupiter/unstake | | Transaction confirmed with referral | POST | /api/v1/wallet/campaign/update |

The base URL and endpoint paths are defined as constants at the top of src/rakurai-stake-sdk.ts. Change them if you need a different environment.


Wallet integration

The React modal talks to the host app's wallet through a single interface, WalletBridge. For @solana/wallet-adapter-react apps, useWalletAdapterBridge() implements it for you. For any other setup, implement the interface yourself:

interface WalletBridge {
  readonly publicKey: string | null;
  connect(): Promise<void>;
  disconnect(): Promise<void>;
  signAndSendTransaction(
    tx: Transaction | VersionedTransaction,
    extraSigners?: Keypair[]
  ): Promise<string>;
  solBalance?: number;
  raisolBalance?: number;
}

For the native unstake flow, sign with the extra signers before the user's wallet signs (for a legacy transaction, tx.partialSign(...extraSigners)). The SDK's core functions accept only a wallet public key string and return standard @solana/web3.js transactions, so any wallet that can sign Solana transactions works.