An Anchor-based Solana program for staking programmable NFTs (pNFTs) and distributing configurable token rewards. The project includes the on-chain staking program, TypeScript helpers, and a command-line interface for administrator and user operations.
- Stake and unstake programmable NFTs.
- Track per-user staking state through program-derived accounts.
- Configure reward settings from an administrator wallet.
- Enable, disable, and update daily reward distribution.
- Query global pool state and user staking status from the CLI.
programs/staking/ Anchor program source code
cli/ Command-line interface commands
lib/ TypeScript transaction builders, constants, and helpers
tests/ Anchor test suite
target/idl/staking.json Generated Anchor IDL
Install the following before building or running the project:
- Node.js and Yarn
- Rust and Solana CLI
- Anchor CLI
- A funded Solana wallet keypair, for example
key.json
Clone the repository and install dependencies:
yarnThe CLI uses ANCHOR_WALLET=./key.json by default through the yarn script command. Place your wallet keypair at ./key.json, or pass a custom keypair path with -k.
The default program configuration is defined in:
Anchor.tomlfor the Anchor provider, cluster, and deployed program address.programs/staking/src/lib.rsfor the on-chaindeclare_id!.lib/constant.tsfor TypeScript-side program constants.cli/command.tsfor CLI defaults such as cluster, RPC endpoint, and keypair path.
Most CLI commands support these shared options:
yarn script <command> --env <cluster> --rpc <rpc-url> --keypair <wallet-path>Example:
yarn script status --env devnet --keypair ./key.jsonBuild the Anchor program:
anchor buildGet the generated program ID:
solana-keygen pubkey ./target/deploy/staking-keypair.jsonUpdate the program ID in both locations:
declare_id!("<PROGRAM_ID>");[programs.devnet]
staking = "<PROGRAM_ID>"Rebuild and deploy the program:
anchor build
solana program deploy ./target/deploy/staking.soAfter deployment, initialize the global staking pool:
yarn script initIf rewards are enabled, ensure the reward vault is funded with the configured reward token mint.
Initialize the global staking pool:
yarn script initView global pool information and reward vault state:
yarn script statusTransfer administrator authority:
yarn script change-admin --new_admin <NEW_ADMIN_ADDRESS>Enable or disable rewards:
yarn script change-reward-enable --new_reward_enable <0_OR_1>Set the reward token mint:
yarn script change-reward-mint --new_mint <REWARD_MINT_ADDRESS>Update the daily reward rate:
yarn script change-reward-per-day --new_reward_per_day <REWARD_AMOUNT_PER_DAY>Initialize the caller's user pool account:
yarn script init-userStake a pNFT:
yarn script lock --mint <NFT_MINT_ADDRESS>Unstake a pNFT:
yarn script unlock --mint <NFT_MINT_ADDRESS>Claim accumulated rewards:
yarn script claim-rewardView a user's staking status:
yarn script user-status --user_address <USER_ADDRESS>Run the Anchor test suite:
anchor testRun Prettier checks:
yarn lintFormat TypeScript and JavaScript files:
yarn lint:fix- Keep
declare_id!andAnchor.tomlsynchronized with the deployed program ID. - Review all wallet and RPC configuration before submitting transactions.
- Do not commit private keypair files such as
key.json.