Full lesson
dobro-stake-pool
The Dobro Solana Liquid Staking Pool
- Original
- grassets-tech/dobro-stake-pool
- SuperStack fork
- Blockchains/dobro-stake-pool @
cf35d15 - Stars
- 0
- Last push (original)
- 2025-05-13
- Languages
- Rust, Python, TypeScript, JavaScript, Shell
- Detected stack
- Native Rustsolana-pyweb3.js
- Categories
- DeFi
- Licence
- Apache-2.0
Architecture
89 source files. By extension: .rs ×39, .py ×32, .ts ×16, .js ×2.
| Top-level directory | Source files |
|---|---|
clients | 53 |
program | 36 |
Dapp: devnet deploy pending
⏳ Devnet deploy pending — goes live when the devnet wallet is topped up. This fork's own dapp is not deployed yet, so there is no program address or transaction to show. It is queued in dapp-queue.txt; once devnet SOL is available it is deployed, exercised with real devnet transactions, and this section switches to the live dapp at /dapps/dobro-stake-pool/. Until then, the lesson and step-by-step guide below are complete, and you can run it locally with the commands below.
Key code, explained
Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.
program/src/state.rs L49–72 @ cf35d15 · Apache-2.0 · original /// Manager authority, allows for updating the staker, manager, and fee /// account pub manager: Pubkey, /// Staker authority, allows for adding and removing validators, and /// managing stake distribution pub staker: Pubkey, /// Stake deposit authority /// /// If a depositor pubkey is specified on initialization, then deposits must /// be signed by this authority. If no deposit authority is specified, /// then the stake pool will default to the result of: /// `Pubkey::find_program_address( /// &[&stake_pool_address.as_ref(), b"deposit"], /// program_id, /// )` pub stake_deposit_authority: Pubkey, /// Stake withdrawal authority bump seed /// for `create_program_address(&[state::StakePool account, "withdrawal"])` pub stake_withdraw_bump_seed: u8, /// Validator stake list storage account- Line 54
/// managing stake distribution: Touches staking state: the amount locked and when it was locked. - Line 62
/// `Pubkey::find_program_address(: Derives a PDA from seeds and the program ID and returns the address with its canonical bump. - Line 68
/// Stake withdrawal authority bump seed: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
program/src/lib.rs L73–95 @ cf35d15 · Apache-2.0 · original#[inline]pub fn minimum_delegation(stake_program_minimum_delegation: u64) -> u64 { std::cmp::max(stake_program_minimum_delegation, MINIMUM_ACTIVE_STAKE)} /// Get the stake amount under consideration when calculating pool token/// conversions#[inline]pub fn minimum_reserve_lamports(meta: &Meta) -> u64 { meta.rent_exempt_reserve .saturating_add(MINIMUM_RESERVE_LAMPORTS)} /// Generates the deposit authority program address for the stake poolpub fn find_deposit_authority_program_address( program_id: &Pubkey, stake_pool_address: &Pubkey,) -> (Pubkey, u8) { Pubkey::find_program_address( &[stake_pool_address.as_ref(), AUTHORITY_DEPOSIT], program_id, )}- Line 78
/// Get the stake amount under consideration when calculating pool token: Touches staking state: the amount locked and when it was locked. - Line 91
Pubkey::find_program_address(: Derives a PDA from seeds and the program ID and returns the address with its canonical bump.
clients/py/stake_pool/constants.py L13–36 @ cf35d15 · Apache-2.0 · original MINIMUM_RESERVE_LAMPORTS: int = 0"""Minimum balance required in the stake pool reserve""" MINIMUM_ACTIVE_STAKE: int = MINIMUM_DELEGATION"""Minimum active delegated staked required in a stake account""" METADATA_PROGRAM_ID = Pubkey.from_string("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s")"""Public key that identifies the Metaplex Token Metadata program.""" def find_deposit_authority_program_address( program_id: Pubkey, stake_pool_address: Pubkey,) -> Tuple[Pubkey, int]: """Generates the deposit authority program address for the stake pool""" return Pubkey.find_program_address( [bytes(stake_pool_address), AUTHORITY_DEPOSIT], program_id, ) def find_withdraw_authority_program_address( program_id: Pubkey,- Line 15
"""Minimum balance required in the stake pool reserve""": Touches staking state: the amount locked and when it was locked. - Line 29
return Pubkey.find_program_address(: Derives a PDA from seeds and the program ID and returns the address with its canonical bump.
clients/py/stake_pool/actions.py L529–552 @ cf35d15 · Apache-2.0 · original data = resp.value.data if resp.value else bytes() stake_pool = StakePool.decode(data) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) data = resp.value.data if resp.value else bytes() validator_list = ValidatorList.decode(data) (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) if ephemeral_stake_seed is None: transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid reuse else: # we are updating an existing transient stake account, so we must use the same seed transient_stake_seed = validator_info.transient_seed_suffix validator_stake_seed = validator_info.validator_seed_suffix or None (transient_stake, _) = find_transient_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_info.vote_account_address, stake_pool_address, transient_stake_seed, ) (validator_stake, _) = find_stake_program_address(- Line 540
transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve. - Line 542
# we are updating an existing transient stake account, so we must use the same seed: Touches staking state: the amount locked and when it was locked.
How to run, build and test
These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.
| Directory | Command | Runs |
|---|---|---|
clients/js-legacy | npm run build | tsc && cross-env NODE_ENV=production rollup -c |
clients/js-legacy | npm run test | jest |
clients/js-legacy | npm run lint | eslint --max-warnings 0 . |
. | cargo build | Rust workspace build |
. | cargo test | Rust tests |
What you could build from it
- Fork the SuperStack copy and extend it within the DeFi gaps listed on the idea page.
- Learn the pattern first: Program Derived Addresses (PDAs)
- Learn the pattern first: Cross-Program Invocations (CPIs)
- Learn the pattern first: SPL Tokens: mints, accounts and transfers