-
-
Save apetresc/caaf222c31b02354dbc11a333cdb688e to your computer and use it in GitHub Desktop.
#!/bin/bash -e | |
# redelegate-cro.sh is a script that automatically claims all your delegation | |
# rewards (across any number of validators) in a single transaction (assuming a | |
# minimum reward threshold is met, to avoid spurious transactions). The rewards | |
# are then automatically redelegated to the provided validator address, leaving | |
# behind at least a 0.005 CRO buffer to ensure there is always enough for | |
# regular transaction fees. | |
# | |
# The idea is that it is safe to run this script on a fixed cron schedule and | |
# feel confident that you are minimizing fees and maximizing APY. | |
# | |
# TODO: Currently, the delegation only happens to a single validator (although | |
# rewards are claimed from all). In future, you will be able to specify | |
# multiple <validator-address>es to evenly split the stake across multiple. | |
# | |
# REQUIREMENTS: | |
# - chain-maind | |
# - jq | |
# | |
# Updates will be posted to the gist at: | |
# https://gist.github.com/apetresc/caaf222c31b02354dbc11a333cdb688e | |
if [[ "$1" == "-h" || "$1" == "" || "$2" == "" ]] | |
then | |
echo "Usage: $0 <wallet-address> <validator-address> [-y]" | |
exit | |
fi | |
# Arguments | |
WALLET=$1 | |
VALIDATOR=$2 | |
YES=$3 | |
# Global parameters | |
REWARDS_THRESHOLD=10 | |
RPC_NODE="https://mainnet.crypto.org:26657" | |
CHAIN_ID="crypto-org-chain-mainnet-1" | |
echo "Wallet is: $WALLET" | |
BALANCE=$(chain-maind --chain-id $CHAIN_ID query bank balances $WALLET --node $RPC_NODE --output json | jq -r '.balances[] | select(.denom == "basecro") .amount') | |
echo "Balance is: $BALANCE" | |
REWARDS=$(chain-maind --chain-id $CHAIN_ID query distribution rewards $WALLET --node $RPC_NODE --output json) | |
REWARDS_AMOUNT=$(echo $REWARDS | jq -r '.total[] | select(.denom == "basecro") .amount|tonumber/100000000') | |
echo "There are $REWARDS_AMOUNT CRO rewards across $(echo $REWARDS | jq -r '.rewards | length') validators to be claimed." | |
if awk 'BEGIN {exit !('$REWARDS_AMOUNT' >= '$REWARDS_THRESHOLD')}' | |
then | |
echo "Claiming rewards..." | |
chain-maind --chain-id $CHAIN_ID tx distribution withdraw-all-rewards \ | |
--from $WALLET \ | |
--gas=auto --gas-prices=0.1basecro --gas-adjustment=1.2 \ | |
--node $RPC_NODE $YES | |
NEW_BALANCE=$(chain-maind --chain-id $CHAIN_ID query bank balances $WALLET --node $RPC_NODE --output json | jq -r '.balances[] | select(.denom == "basecro") .amount') | |
while awk 'BEGIN {exit !('$NEW_BALANCE' <= '$BALANCE')}' | |
do | |
echo "Waiting for rewards to appear..." | |
NEW_BALANCE=$(chain-maind --chain-id $CHAIN_ID query bank balances $WALLET --node $RPC_NODE --output json | jq -r '.balances[] | select(.denom == "basecro") .amount') | |
done | |
BALANCE=$NEW_BALANCE | |
echo "New balance is: $BALANCE" | |
STAKING_AMOUNT=$(expr $BALANCE - 500000) | |
echo "Amount to stake: $STAKING_AMOUNT" | |
chain-maind --chain-id $CHAIN_ID tx staking delegate \ | |
$VALIDATOR \ | |
"${STAKING_AMOUNT}basecro" \ | |
--from $WALLET \ | |
--gas=auto --gas-prices=0.1basecro --gas-adjustment=1.2 \ | |
--node $RPC_NODE $YES | |
echo "Done!" | |
else | |
echo "Need at least $REWARDS_THRESHOLD CRO to claim, skipping claim..." | |
fi | |
@jlavos Yup, you can use a keyring backend that doesn't require a passphrase, as long as you understand the security implications. That's done on chain-maind directly, here's how: https://crypto.org/docs/wallets/cli.html#the-keyring-keyring-backend-option
Thanks @aptresc. The only option I see that does not require as passphrase is using the "test backend" method. Is that it?
got it working, ;), thanks.
Thank you for sharing this!
I get this error "Error: error unmarshalling: invalid character '<' looking for beginning of value" however the balance in the wallet I am testing with is below 10 CRO.
I get that on some calls (e.g. 1st time I run the script it fails, if I run it right after it works), haven't figured out why yet.
@jcdmacleod Yeah, that's a normal error that just means the public RPC node we're using (one of Crypto.com's) rejected our query for whatever reason, presumably due to congestion. As @jlavos points out, retrying immediately afterwards will usually solve it.
I suppose I should just add a little retry logic directly in the script, thanks for the idea 👍
Did the RPC_NODE change? I keep getting an error:
"Error: post failed: Post "https://mainnet.crypto.org:26657": dial tcp: lookup mainnet.crypto.org: no such host"
Greate script, thank you!!
Trying to run as a schedule but it keeps asking me for the passphrase. Is there a way to pass the passphrase to chain-maind or not to have to type it ever?
Can't run this on a schedule if passphrase needs to be typed in all the time.