Skip to content

jito-foundation/jito-stake-unstake-reference

Repository files navigation

JitoSOL Stake/Unstake Reference UI

This is a reference UI implementation for staking SOL to the Jito stake pool to receive JitoSOL tokens, and unstaking JitoSOL back to SOL. It demonstrates both assisted methods (using the SPL stake-pool library) and manual methods (building transactions manually) via a Next.js interface.

Overview

This reference implementation demonstrates how to build a user interface for interacting with the Jito stake pool, showing:

  1. Stake SOL to receive JitoSOL (Assisted & Manual)
  2. Unstake JitoSOL to receive SOL (Assisted & Manual)
    • Assisted Unstake
      • Initiating a withdraw into a stake account.
      • Via use reserve option: using the pool's reserve for instant SOL withdrawal (subject to iquidity and is usually blocked by our chain program in favor of stake).
      • Advanced options for specifying validator and destination stake account for delayed unstake.
    • Manual Unstake: Creates a new stake account for the unstaked amount.
  3. Displaying Stake Pool Details: Shows key metrics about the Jito stake pool.
  4. Wallet Integration: Connects to user wallets via Wallet Adapter.
  5. Network Switching: Allows users to switch between Mainnet and Testnet, inside both of which a JitoSOL pool exists.

By offering both Assisted (library) and Manual (direct) methods for staking and unstaking, it helps show the underlying instructions used to build the stake pool transactions. The idea is to help developers understand, customize, and build upon these interactions.

Getting Started

Prerequisites

  • Node.js v18+ and npm or yarn
  • A Solana wallet (e.g., Phantom, Solflare) for interacting with the UI.

Installation

  1. Clone the repository:

    git clone https://github.com/jito-foundation/jito-stake-unstake-reference
    cd jito-stake-unstake-reference
  2. Install dependencies:

    npm install
    # or
    yarn install
  3. (Optional) Set up environment variables: Create a .env.local file in the root directory. You can specify a custom Mainnet RPC endpoint if needed:

    NEXT_PUBLIC_RPC_URL=YOUR_CUSTOM_MAINNET_RPC_ENDPOINT
    

    If not set, the default Solana public RPC for the selected network will be used.

  4. Run the development server:

    npm run dev
    # or
    yarn dev
  5. Open http://localhost:3000 in your browser.

Key Components

UI Components (components/)

  • Navbar.tsx: Top navigation bar with network selection and wallet connection button.
  • StakePoolDetails.tsx: Displays fetched details about the Jito stake pool (e.g., total staked, conversion rate, fees) with an expandable view and copy-to-clipboard for addresses.
  • StakeTab.tsx: Form for staking SOL, allowing selection between Assisted and Manual methods.
  • UnstakeTab.tsx: Form for unstaking JitoSOL, allowing selection between Assisted and Manual methods, including options for reserve withdrawal and advanced settings.
  • Button.tsx: Reusable button component.
  • WalletContextProvider.tsx: Configures the Solana Wallet Adapter, handling connection logic and network endpoints.
  • NetworkProvider.tsx: Context provider to manage the selected network state (Mainnet/Testnet).

Hooks (hooks/)

These hooks encapsulate the core logic for interacting with the stake pool. The Manual hooks are particularly useful for understanding how the underlying Solana transactions and instructions are constructed, providing a clear basis for further customization.

  • useStakePoolInfo.ts: Fetches and processes data about the Jito stake pool.
  • useAssistedStake.ts: Implements staking using the @solana/spl-stake-pool library (depositSol).
  • useManualStake.ts: Implements staking by manually constructing the DepositSol transaction instruction. Demonstrates the steps involved in creating the instruction, handling accounts (like the associated token account), and sending the transaction. Ideal for learning or customizing the staking process.
  • useAssistedUnstake.ts: Implements unstaking using the @solana/spl-stake-pool library (withdrawSol or withdrawStake), handling reserve and delayed options.
  • useManualUnstake.ts: Implements unstaking by manually constructing the WithdrawStake transaction instruction, creating a new stake account for the user. Shows how to find validator stake accounts, manage temporary accounts, build the instruction manually, and handle necessary signers. Serves as a detailed example for custom unstaking flows. Note: This hook replicates some helper functions from the SPL library for instruction creation..

Constants (constants/index.ts)

Defines key addresses and values:

// Jito Stake Pool Address (Mainnet-beta)
export const JITO_STAKE_POOL_ADDRESS = new PublicKey('Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb');

// Jito SOL Mint Address (JitoSOL)
export const JITO_MINT_ADDRESS = new PublicKey('J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn');

// Stake Pool Program ID
export const STAKE_POOL_PROGRAM_ID = new PublicKey('SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy');

// Other constants like LAMPORTS_PER_SOL...

Staking & Unstaking Logic

Staking

Assisted Method

  • Uses depositSol from @solana/spl-stake-pool

Manual Method

  • Manually creates the DepositSol instruction
  • Includes finding/creating the associated token account for JitoSOL

Unstaking

Assisted Methods

  1. Withdraw Stake

    • Uses withdrawStake from @solana/spl-stake-pool
    • Converts JitoSOL into a stake account owned by the user
    • Represents user's share of the underlying SOL
    • Requires stake account deactivation (takes 1 epoch) before SOL can be withdrawn
    • Avoids reserve fees but takes longer to complete
  2. Via Use Reserve (Not recommended)

    • Uses withdrawSol from @solana/spl-stake-pool
    • Instantly swaps JitoSOL for SOL directly from the pool's liquid reserve
    • Subject to available liquidity
    • Usually blocked by the Jito pool in favor of withdrawing stake

Manual Method

  • Withdraw Stake
    • Manually creates the WithdrawStake instruction
    • Finds a suitable validator stake account within the pool to withdraw from
    • Creates a new stake account for the user to receive the withdrawn stake
    • Also requires deactivation before the SOL is fully liquid

Important Considerations

  1. Account Rent & Fees: Transactions require SOL for network fees and potentially rent-exemption for new accounts.
  2. Stake Account Deactivation: Funds withdrawn as stake accounts (via Assisted useReserve=false or Manual) are only fully liquid after the stake account deactivates (typically 1-2 epochs).
  3. Reserve Withdrawal: Using the reserve (useReserve=true) is subject to available liquidity and incurs fees defined by the stake pool.
  4. Testnet vs Mainnet: Pool parameters, minimum balances, and behavior differ between networks.

References

Contributing

Contributions are welcome! Please open an issue or pull request for any improvements or bug fixes.

License

This project is licensed under the MIT License - see the LICENSE file for details.