Skip to content

unibrix/solana-staking

Repository files navigation

Solana Staking Program

This is the backend part of the project using Anchor framework for Solana. It includes the smart contract (program), IDL generation, and utility scripts.

Desktop UI Experience

Home Screen — Connect Wallet & Start Staking

Users can connect their Solana wallet and begin staking tokens. Desktop — Connect Wallet Desktop — Connect Wallet

Staking Process — Rewards Accumulation & Claim

After staking, users can view their staked amount, accumulated rewards, and perform actions such as claiming tokens. Desktop — Staking Process

Final State — Unstake Tokens

Users can unstake their tokens and see updated balances. Desktop — Unstake

Mobile UI Experience

Mobile-Optimized UI

The interface is fully responsive and works seamlessly on mobile devices. Users can connect their wallet, stake tokens, claim rewards, and unstake — all from a mobile screen.

mobile-connect-wallet mobile-ui

Environment Setup

Add Public and Private Keys

You must add a public-key.json file with your wallet's public and private keys to the following path:

./keys/

For example:

./keys/bosueYqFVaFYyAbMzUdsVPyY9D7kErzmXKYHnMViRky.json

This key will be used to:

  • deploy the program
  • sign transactions
  • interact with PDAs (Program Derived Addresses).

⚠️ Keep this file secure and do not commit it to version control!

You can Generate a Keypair (if you don’t have one)

View instructions at Generate Keypair Script file section

Update Anchor.toml

To ensure your Anchor program works properly, make sure to update your Anchor.toml file with your wallet path and target cluster.

Set Your Wallet Path

In the [provider] section, set the wallet field to the path of your generated keypair file. This should match the path where your full keypair JSON was saved (inside ./keys/).

wallet = "./keys/{YOUR_PUBLIC_KEY}.json"

Replace {YOUR_PUBLIC_KEY} with your actual public key filename.

⚠️ Important: Do not commit your public key into version control.

Set the Cluster

Also in the [provider] section, configure the cluster to deploy to.

Example:

cluster = "devnet"

You can choose one of the official Solana RPC endpoints to connect to.

⚠️ Make sure this matches your ANCHOR_PROVIDER_URL in the .env file.

Set Program ID

After building and deploying your program, Anchor should automatically update the Anchor.toml with the received program ID under the [programs.<cluster>] section. However, if for any reason the program ID is not set automatically, update Anchor.toml with received program ID manually

⚠️ Important: Do not commit your real deployed program ID into version control

⚠️ View more important instructions at Program ID Consistency file section

Configure Environment Variables

Create a .env file in the root directory with the required environment variables. For convenience, you can preview .env.example file.

ANCHOR_PROVIDER_URL

  • Description: The Solana RPC endpoint to connect to.
  • Example:
ANCHOR_PROVIDER_URL=https://api.devnet.solana.com

ANCHOR_WALLET

  • Description: Path to your local wallet keypair file used to sign transactions.
  • Example:
ANCHOR_WALLET=./keys/{PUBLIC_KEY}.json

MINT_ADDRESS

  • Description: The address of the token mint that will be used in the airdrop.
  • Note: If you don't have a token mint yet, you need to create one. To do that, view instructions at Create Token Script file section. After generating a new token mint and output the mint address in the console. You can then set it in your .env file like this:
MINT_ADDRESS=YourNewTokenMintAddressHere

Generate Keypair Script

This script generates a new Solana keypair (public/private keys) and saves it to a JSON file.

Run the script:

yarn generate-key

Script location:

programs/spl_token_staking/src/scripts/generate-keypair.ts

What it does:

  • Generates a new Solana wallet (keypair)
  • Saves the full keypair to a JSON file at the path:

./keys/{PUBLIC_KEY}.json

  • The file is named after the generated public key.

⚠️ Important: This file contains both the public and private keys. Keep it secure and never commit it to version control!

Create Token Script

This script creates a new fungible token on Solana using the Token 2022 program and attaches on-chain metadata to it using the Metaplex Token Metadata program.

Run the script:

yarn create-token-with-meta

Script location:

programs/spl_token_staking/src/scripts/create-token-with-meta.ts

What it does:

  • Prompts the user to input the following token information:
    • Token name (e.g., ‘MyToken’)
    • Token symbol (up to 10 characters, e.g., "MTK")
    • Metadata URI (link to a JSON metadata file,
      e.g., link from Tusky/Filebase/Irys/Metaboss/NFT Storage/Pinata/ShadowDrive/web3.storage)
    • Royalty percentage (e.g., 2.5% for secondary sales)
    • Number of decimals (e.g., 0 for indivisible tokens, 9 for high precision)
    • Initial token supply (in an understandable format, e.g., 1000)
  • Creates a new fungible token using the Token 2022 program.
  • Uploads the token metadata to the blockchain using the Metaplex Token Metadata program.
  • Mints the specified initial supply of tokens to the wallet's Associated Token Account (ATA).

Metadata URI JSON File Requirements:

The value you enter in the Metadata URI prompt should point to a valid public JSON file that contains the token's metadata. This file is typically hosted on decentralized storage (e.g., Tusky, Filebase, Irys, Metaboss, NFT Storage, Pinata, ShadowDrive, web3.storage) or a trusted centralized server.

The JSON file must contain the following fields: name, symbol, description, image

JSON File Content Example:

{
   "name": "My Token",
   "symbol": "MYT",
   "description": "This is a description of the token.",
   "image": "https://example.com/token-image.png"
}

Field descriptions:

  • name: The full name of the token.
  • symbol: The ticker or symbol (e.g., "MYT").
  • description: A human-readable description of the token.
  • image: A publicly accessible URL pointing to an image representing the token.
    • The image should ideally be in PNG or SVG format.
    • The URL must be HTTPS and reachable at the time of metadata creation.

⚠️ Important: If the URI or image URL is invalid or unreachable, the metadata creation will fail

⚠️ Attention: All transactions are signed with a key that is loaded from ANCHOR_WALLET. This key must have enough SOL to cover the fees.

Scripts For SPL Token Staking

Initialize Staking Script

yarn init-staking <APR>

Description: Initializes the staking state account (stake_state PDA) with the specified APR (Annual Percentage Rate).

Example:

yarn init-staking 10

This will initialize staking with 10% APR.

Fund Reward Vault Script

yarn fund-reward-vault <amount>

Description: Funds the reward_vault PDA with the specified amount of SPL tokens. Automatically creates the associated token account (ATA) if it doesn’t exist.

Example:

yarn fund-reward-vault 10000

This step is required for enabling users to claim reward tokens from the Vault via the dApp.

Close Staking Script

yarn close-staking

Description: Closes the stake_state PDA and reclaims lamports (SOL). Use only when you're certain the staking program should be reset or terminated or for testing cases only.

Example:

yarn close-staking

Build and Deploy the Program

Before deploying, make sure your Solana CLI is configured correctly

Build the program

anchor build

This will:

  • Compile the smart contract to .so (shared object) binary
  • Generates target/idl/spl_token_staking.json (for frontend integration)
  • Generates TypeScript types in target/types/spl_token_staking.ts

Deploy to the network

anchor deploy

This will:

  • Deploy the compiled program to the specified Solana cluster (e.g., Devnet)
  • Output the program ID, which should match the one expected by your frontend

Program ID Consistency

After building and deploying your program, Anchor should automatically update the Anchor.toml with the received program ID under the [programs.<cluster>] section and the lib.rs at declare_id!(" ") part.

However, if for any reason the program ID is not set automatically, after deploying your program, you must manually update both Anchor.toml and lib.rs with received program ID:

  1. Anchor.toml:
    spl_token_staking = "YourStakingProgramId"
    • ./programs/spl_token_staking/src/lib.rs:
    declare_id!("YourStakingProgramId");

⚠️ Both values must be the same, otherwise Anchor will throw errors during testing or interaction.

⚠️ Important: Do not commit your real deployed program ID into version control if it's specific to your development environment.

Testing the Program

To run tests, defined in tests directory, run:

anchor test

Notes

  • Make sure your wallet has enough SOL to cover transaction fees when depositing and interacting with the programme.
  • It is mandatory that ANCHOR_PROVIDER_URL and ANCHOR_WALLET variables are correctly specified at .env for anchor successful deploy.
  • Verify Programme ID to be the same in Anchor.toml and lib.rs. A mismatch will cause errors.
  • Make sure that your Vault PDA is funded before testing the frontend.
  • Do not commit public-key.json keys files or .env to version control for security reasons.
  • Always verify the program ID and network match between backend and frontend.

Learn More

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors