A Rust-based CLI tool for automated withdrawal of staking rewards and validator commissions on Cosmos SDK-based blockchain networks. This tool uses the authz module to enable secure delegation of withdrawal permissions between accounts.
- Automated Reward Withdrawal: Withdraw staking rewards and validator commissions automatically
- Multi-Chain Support: Works with any Cosmos SDK-based network
- Flexible Authentication: Supports both standard secp256k1 and Ethereum-style eth_secp256k1 keys
- Threshold-Based Withdrawals: Only withdraw when rewards exceed specified thresholds
- Authz Integration: Uses Cosmos authz module for secure permission delegation
- Gas Optimization: Automatic gas estimation with customizable adjustment factors
- Transaction Generation: Can generate unsigned transactions for external signing
Ensure you have Rust 1.85.0 or later installed:
git clone https://github.com/restake/cosmos-withdrawer
cd cosmos-withdrawer
cargo build --release
The binary will be available at target/release/cosmos-withdrawer
.
First, set up the authorization grants between your delegator (validator) and controller accounts:
cosmos-withdrawer setup-valoper \
--rpc-url "https://rpc.osmosis.zone" \
--delegator-address "osmo1validator..." \
--delegator-mnemonic "your validator mnemonic phrase" \
--controller-address "osmo1controller..." \
--controller-mnemonic "your controller mnemonic phrase"
Once set up, withdraw rewards when they exceed specified thresholds:
cosmos-withdrawer withdraw \
--rpc-url "https://rpc.osmosis.zone" \
--delegator-address "osmo1validator..." \
--controller-address "osmo1controller..." \
--controller-mnemonic "your controller mnemonic phrase" \
--threshold "1000000uosmo"
You can configure the tool using environment variables:
export COSMOS_WITHDRAWER_RPC_URL="https://rpc.osmosis.zone"
export COSMOS_WITHDRAWER_DELEGATOR_ADDRESS="osmo1validator..."
export COSMOS_WITHDRAWER_CONTROLLER_ADDRESS="osmo1controller..."
export COSMOS_WITHDRAWER_DELEGATOR_MNEMONIC="your validator mnemonic"
export COSMOS_WITHDRAWER_CONTROLLER_MNEMONIC="your controller mnemonic"
export COSMOS_WITHDRAWER_WITHDRAW_THRESHOLDS="1000000uosmo,500000uion"
Create a .envrc.local
file (use direnv) in the project root for local overrides:
# .envrc.local
export COSMOS_WITHDRAWER_RPC_URL="http://localhost:26657"
export COSMOS_WITHDRAWER_DELEGATOR_MNEMONIC="your local test mnemonic"
Set up authorization grants between delegator and controller accounts.
cosmos-withdrawer setup-valoper [OPTIONS] <METHOD>
Methods:
auto
: Automatically determine the best setup methodauthz-withdraw
: Use authz with withdraw address setting (recommended)authz-send
: Use authz with token sending (fallback for older chains)
Key Options:
--delegator-address
: The validator operator address--controller-address
: The account that will execute withdrawals--reward-address
: Optional separate address to receive rewards--expiration
: Set expiration for authz grants (if required by chain)
Withdraw validator rewards and commissions.
cosmos-withdrawer withdraw [OPTIONS]
Key Options:
--threshold
: Token thresholds for withdrawal (format:1000000uosmo
)--gas
: Gas limit (auto
or specific amount)--gas-prices
: Gas prices (format:0.025uosmo
)--dry-run
: Simulate without broadcasting--generate-only
: Generate unsigned transaction JSON
Debug utilities for address derivation and testing.
cosmos-withdrawer debug derive-address \
--mnemonic "your mnemonic phrase" \
--key-type secp256k1 \
--coin-type 118
The tool supports different key types:
secp256k1
: Standard Cosmos SDK key type (default)eth_secp256k1
: Ethereum-style keys (for Evmos, Injective, etc.)
--gas auto --gas-adjustment 1.25
--gas 200000 --gas-prices 0.025uosmo
Transactions are signed and broadcasted automatically.
Generate unsigned transaction JSON for external signing:
cosmos-withdrawer withdraw --generate-only > unsigned_tx.json
Simulate transactions without broadcasting:
cosmos-withdrawer withdraw --dry-run
- Delegator Account: The validator operator account that receives rewards
- Controller Account: The account authorized to execute withdrawals
- Reward Account: Optional separate account to receive withdrawn funds
- Setup Phase: Delegator grants authz permissions to controller
- Withdrawal Phase: Controller executes withdrawals on behalf of delegator
- Distribution: Rewards are sent to the configured reward address
The tool includes gas price data for 200+ Cosmos networks. For networks not in the built-in registry, specify gas prices manually:
--gas-prices 0.025uatom
# Setup authz grants
cosmos-withdrawer setup-valoper \
--rpc-url "https://rpc.osmosis.zone" \
--delegator-address "osmo1validator..." \
--controller-address "osmo1controller..." \
--delegator-mnemonic "$VALIDATOR_MNEMONIC" \
--controller-mnemonic "$CONTROLLER_MNEMONIC"
# Withdraw when rewards exceed 1 OSMO
cosmos-withdrawer withdraw \
--rpc-url "https://rpc.osmosis.zone" \
--delegator-address "osmo1validator..." \
--controller-address "osmo1controller..." \
--controller-mnemonic "$CONTROLLER_MNEMONIC" \
--threshold "1000000uosmo"
cosmos-withdrawer withdraw \
--threshold "1000000uosmo" \
--threshold "500000uion" \
--threshold "2000000uakt"
cosmos-withdrawer setup-valoper \
--delegator-address-type eth_secp256k1 \
--controller-address-type eth_secp256k1 \
--delegator-mnemonic-coin-type 60 \
# ... other options
- Never share mnemonics: Store them securely and never commit to version control
- Use environment variables: Avoid passing mnemonics as command-line arguments
- Separate accounts: Use different accounts for validator operations and withdrawals
The tool grants minimal required permissions:
MsgWithdrawDelegatorReward
: For reward withdrawalsMsgWithdrawValidatorCommission
: For commission withdrawalsMsgSetWithdrawAddress
: For setting reward destination (preferred)MsgSend
: Only when withdraw address setting is not supported (fallback)
- Use HTTPS RPCs: Always use secure RPC endpoints
- Verify chain IDs: Ensure you're connected to the correct network
- Monitor transactions: Review all transactions before and after execution
Ensure all accounts are initialized with some balance before setup.
Increase gas limit or adjustment factor:
--gas-adjustment 1.5
Specify gas prices manually for unsupported chains:
--gas-prices 0.025unative
Verify mnemonic phrase and coin type match your wallet configuration.
Check derived addresses:
cosmos-withdrawer debug derive-address \
--mnemonic "your mnemonic" \
--key-type secp256k1 \
--coin-type 118
cargo build
cargo test
Update gas price data:
./hack/chain-registry-data.sh > src/chain_registry/gas_data.json
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the terms specified in the repository.
For support and questions:
- Create an issue on GitHub
- Check existing issues for solutions
- Review the troubleshooting section