Cardano Staking: Delegate to Stake Pool, Withdraw Rewards
Scalus TxBuilder provides a type-safe API for managing Cardano staking operations. This guide covers the four core staking operations: registering stake keys, delegating to pools, withdrawing rewards, and deregistering stake keys.
Staking operations require interaction with Cardano’s stake address system. All operations support both Byron-era and Conway-era protocol parameters.
Registering Stake Keys
Registering a stake key is the first step to participate in Cardano staking. This operation requires a 2 ADA deposit that is refundable when you deregister the stake key.
val tx = TxBuilder(env)
.registerStake(stakeAddress)
.complete(provider, sponsorAddress)
.build()In the Conway era, you can specify the deposit amount explicitly:
val tx = TxBuilder(env)
.registerStake(stakeAddress, Coin.ada(2))
.complete(provider, sponsorAddress)
.build()The 2 ADA deposit is held by the protocol and will be returned when you deregister your stake key.
Delegating to Stake Pools
After registering a stake key, you can delegate it to a stake pool using the pool’s unique Pool ID. Your delegated ADA helps secure the network and earns staking rewards.
val poolId = PoolKeyHash.fromHex("pool1...")
val tx = TxBuilder(env)
.delegateTo(stakeAddress, poolId)
.complete(provider, sponsorAddress)
.build()Registering and Delegating in One Transaction
For efficiency, you can combine registration and delegation into a single transaction:
val poolId = PoolKeyHash.fromHex("pool1...")
val deposit = Coin.ada(2)
val tx = TxBuilder(env)
.stakeAndDelegate(stakeAddress, poolId, deposit)
.complete(provider, sponsorAddress)
.build()Combining operations saves transaction fees and reduces the number of blockchain interactions required.
Withdrawing Staking Rewards
Claim your accumulated staking rewards to your wallet.
val tx = TxBuilder(env)
.withdrawRewards(stakeAddress, rewardAmount)
.complete(provider, sponsorAddress)
.build()Post-Vasil Era: Stake rewards must be withdrawn fully. Partial withdrawals are not supported.
Post-Chang Era: Rewards are only withdrawable if you have delegated your voting power to a DRep (Delegated Representative). See the Governance guide for more information.
Deregistering Stake Keys
Deregistering a stake key returns your initial 2 ADA deposit and removes your stake key from the blockchain.
val tx = TxBuilder(env)
.deregisterStake(stakeAddress)
.complete(provider, sponsorAddress)
.build()With explicit refund:
val tx = TxBuilder(env)
.deregisterStake(stakeAddress, Coin.ada(2))
.complete(provider, sponsorAddress)
.build()Working with Stake Addresses
Creating Stake Addresses from Key Hash
To perform staking operations, you need a properly formatted stake address. Here’s how to create one from a stake key hash:
import scalus.cardano.address.{StakeAddress, StakePayload}
val stakeAddress = StakeAddress(
Network.Mainnet,
StakePayload.Stake(stakeKeyHash)
)Extracting Stake Address from Payment Address
You can extract the stake address from a Shelley payment address:
val stakeAddress = shelleyAddress.delegation match {
case ShelleyDelegationPart.Key(keyHash) =>
StakeAddress(shelleyAddress.network, StakePayload.Stake(keyHash))
case _ => throw new Exception("No stake key")
}