Live Project Link: https://solana-devnet-lst.vercel.app/
- Goal: Let users deposit SOL and receive a liquid staking token (LST), request redemptions, and claim SOL after cooldown. Admin stakes vault SOL to validators and manages withdrawals.
- Program language: Rust (native Solana program, no Anchor).
- Frontend: React + Vite + Tailwind, Solana wallet adapter, Recoil state.
- Network: Defaults to
devnetin the frontend.
Complete user flow : connecting wallet → staking SOL → receiving LST → unstaking dSOL → waiting for cooldown → claiming SOL

Complete admin flow : connecting admin wallet → staking vault SOL to validator → unstaking for epoch → withdrawing from split stake → users claiming SOL
- InitialiseLST
- Creates PDAs:
lst_manager,lst_manager_vault,lst_manager_user_withdrawl_vault,lst_mint,stake_registry_record. - Sets admin (signer), initializes mint (9 decimals), seeds stake registry indices to 1.
- Creates PDAs:
- DepositSOLToVault (user)
- Transfers SOL → vault; mints LST to user ATA using dynamic exchange rate from total SOL/LST.
- Updates
total_lst_supply.
- StakeVaultSOLToValidator (admin)
- Creates stake PDA (by next stake index), funds from vault, initializes and delegates to validator vote account.
- Increments
next_stake_index; updatestotal_sol_staked.
- BurnLstToRedeemSOL (user)
- Burns LST from user ATA, computes SOL owed (rate from total SOL/LST).
- Creates/updates
user_withdraw_requestandepoch_withdrawPDAs. - Increments
total_pending_withdrawl_sol; decrementstotal_lst_supply.
- UnstakeSOLFromValidator (admin)
- For an epoch’s requests: splits a stake account into
split_stake_acc, deactivates it, marks epoch withdraw finalised. - Updates
total_sol_stakedandnext_split_index.
- For an epoch’s requests: splits a stake account into
- WithdrawFromSplitStake (admin)
- Withdraws lamports from a deactivated
split_stake_accintolst_manager_user_withdrawl_vault.
- Withdraws lamports from a deactivated
- ClaimSOLFromWithdrawVault (user)
- After cooldown (epoch >= requested_epoch + 1), transfers SOL from user withdraw vault to user and marks request
COMPLETED. - Decrements
total_pending_withdrawl_sol.
- After cooldown (epoch >= requested_epoch + 1), transfers SOL from user withdraw vault to user and marks request
LSTManager{admin: Pubkey, lst_mint: Pubkey, total_sol_staked: u64, total_lst_supply: u64, total_pending_withdrawl_sol: u64 }
StakeRegistryRecord{ next_stake_index: u64, next_split_index: u64}
UserWithdrawRequest{ user: Pubkey, sol_amount_user_gets: u64, requested_epoch: u64, withdraw_status: PENDING | COMPLETED}
EpochWithdraw{ sol_amount_to_unstake: u64 , requested_epoch: u64 , finalised: bool }["lst_manager", bump]→ LST manager state (admin, mint, totals).["lst_manager_vault", lst_manager, bump]→ SOL vault escrow.["lst_manager_user_withdrawl_vault", lst_manager, bump]→ SOL escrow for user withdrawals.["lst_mint", lst_manager, bump]→ LST mint authority set tolst_manager.["stake_registry_record", lst_manager, bump]→ Tracksnext_stake_indexandnext_split_index.["stake_acc", stake_index, lst_manager, bump]→ Stake accounts delegated to validators.["split_stake_acc", split_index, lst_manager, bump]→ Deactivated split stakes used for withdrawals.["user_withdraw_request", user, bump]→ Per-user pending withdrawal info.["epoch_withdraw", epoch, bump]→ Per-epoch aggregate withdraw request for unstaking.
- React 18, Vite, TypeScript, Tailwind CSS, Recoil, Solana wallet adapter (React UI).
- Toast notifications via
react-hot-toastwith clickable Solana Explorer links. - Defaults to
clusterApiUrl("devnet").
cd frontend
npm install
npm run dev # Vite dev server- Navbar: Connect wallet (wallet adapter UI), shows app brand with gradient logo and title.
- User Dashboard (
UserPage):- Stats grid (TVL, LST supply, APY, exchange rate, active staked SOL, pending withdrawals).
- Stake SOL:
- Sends
DepositSOLToVault; mints LST tokens to user ATA.
- Sends
- Unstake dSOL:
- Sends
BurnLstToRedeemSOL; creates/updates withdraw request and epoch withdraw PDAs.
- Sends
- Pending Withdrawals:
- Shows current request with epoch information.
- If epoch passed, enables claim button (calls
ClaimSOLFromWithdrawVault).
- Admin Dashboard (
AdminPage):- Stats grid with same metrics as user dashboard.
- Stake Vault SOL to Validator:
- Dropdown to select validator vote account (fetches all available validators).
- Select a validators and stake the vault SOL to that Validator
- Unstake SOL:
- Split a main Stake account into a split account for processing user's withdrawl Requests
- Withdraw from Split Stake:
- Withdraw amount from split stake account to user withdrawl vault from where users can requests and claim their withdrawls
- Connect wallet.
- Stake SOL → receives LST (DepositSOLToVault).
- Unstake dSOL → burns LST, creates withdraw request for current epoch (BurnLstToRedeemSOL).
- After next epoch, Claim SOL → ClaimSOLFromWithdrawVault.
- View pending request status and claim readiness in UI.
- Connect with admin wallet (matches
LSTManager.admin). - Periodically Stake Vault SOL to validator (StakeVaultSOLToValidator).
- For an epoch with pending withdrawals, Unstake SOL to create/deactivate split stake (UnstakeSOLFromValidator).
- Once split stake is inactive, Withdraw to User Vault (WithdrawFromSplitStake).
- Users can then claim from the withdraw vault.
- Build:
cargo build-bpf(orcargo build-sbfwith your toolchain). - Deploy:
solana program deploy <path/to/so>; update frontend constants with the new program ID and derived PDAs (using the same seeds and bumps). - Verify PDAs (using seeds listed above) match constants used in the frontend.
- Deposit mints LST using
sol_to_lst_rate(total_sol_in_protocol, total_lst_in_protocol). - Unstake burns LST and records SOL owed using
lst_to_sol_rate. total_pending_withdrawl_solis excluded from the available SOL when computing rates for fairness.
Main user dashboard showing stats grid, stake/unstake tabs, and pending withdrawals card.
Main admin dashboard showing stats grid, admin action tabs, and stake/split account lists.
contract/— Solana program (Rust, non-Anchor).frontend/— React + Tailwind + wallet adapter UI.README.md— This document.
