Automating Holozing reward claims

in holozing •  3 months ago

    Screenshot 2025-01-12 at 21.10.43.png

    That's me in HIVE universe

    If you have some stake at Holozing, and tired about claiming your rewards, automation is your friend.

    import json
    import requests
    import time
    from beem import Hive
    from beemgraphenebase.ecdsasig import sign_message
    from beemgraphenebase.account import PrivateKey
    from binascii import hexlify
    from dotenv import load_dotenv
    import os
    import logging
    
    load_dotenv()
    
    # Set up logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s'
    )
    logger = logging.getLogger(__name__)
    
    class HolozingClient:
        def __init__(self, username: str, posting_key: str):
            self.username = username
            self.posting_key = posting_key
            self.jwt_token = None
            self.hive = Hive(keys=[posting_key])
    
        def check_pending_rewards(self) -> dict:
            """Check if there are any pending rewards before attempting to claim"""
            url = f"https://api.holozing.com/rewards/pending?user={self.username}"
            headers = {
                'accept': 'application/json, text/plain, */*',
                'origin': 'https://holozing.com',
                'referer': 'https://holozing.com/'
            }
            
            try:
                response = requests.get(url, headers=headers)
                data = response.json()
                
                total_rewards = (
                    float(data.get('delegation', '0')) +
                    float(data.get('stakeZing', '0')) +
                    float(data.get('holdingRewards', '0'))
                )
                
                logger.info(f"Rewards check for {self.username}:")
                logger.info(f"Delegation: {data.get('delegation')} ZING")
                logger.info(f"Stake: {data.get('stakeZing')} ZING")
                logger.info(f"Holding: {data.get('holdingRewards')} ZING")
                logger.info(f"Total: {total_rewards} ZING")
                
                return {'total': total_rewards, 'data': data}
                
            except Exception as e:
                logger.error(f"Failed to check rewards: {str(e)}")
                return {'total': 0, 'data': None}
    
        def login(self) -> bool:
            try:
                login_result = self._login_to_holozing()
                self.jwt_token = login_result.get('jwt')
                return bool(self.jwt_token)
            except Exception as e:
                logger.error(f"Login failed: {str(e)}")
                return False
    
        def _login_to_holozing(self):
            expiry = int(time.time()) + 86400
            message = {
                "username": self.username,
                "type": "login",
                "app": "holozing",
                "expiry": expiry
            }
            
            message_str = json.dumps(message)
            private_key = PrivateKey(self.posting_key)
            signature_bytes = sign_message(message_str, private_key)
            signature = hexlify(signature_bytes).decode('ascii')
            
            login_url = "https://api.holozing.com/login/hive"
            headers = {
                "accept": "application/json, text/plain, */*",
                "content-type": "application/json",
                "origin": "https://holozing.com",
                "referer": "https://holozing.com/"
            }
            
            payload = {
                "success": True,
                "error": None,
                "result": signature,
                "data": {
                    "type": "signBuffer",
                    "username": self.username,
                    "message": message_str,
                    "method": "Posting",
                    "rpc": None,
                    "title": "Login to HoloZing",
                    "key": "posting"
                },
                "message": "Message signed successfully.",
                "request_id": 2
            }
            
            response = requests.post(login_url, json=payload, headers=headers)
            return response.json()
    
        def claim_rewards(self) -> bool:
            """
            Claim rewards using the JWT token
            """
            if not self.jwt_token:
                logger.error(f"No JWT token available for {self.username}")
                return False
    
            url = "https://api.holozing.com/rewards/pending"
            headers = {
                "accept": "application/json, text/plain, */*",
                "content-type": "application/json",
                "authorization": f"Bearer {self.jwt_token}",
                "origin": "https://holozing.com",
                "referer": "https://holozing.com/",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
            }
            
            try:
                response = requests.post(url, json={}, headers=headers)
                if response.status_code == 200:
                    logger.info(f"Successfully claimed rewards for {self.username}")
                    return True
                else:
                    logger.error(f"Failed to claim rewards for {self.username}. Status: {response.status_code}")
                    logger.error(f"Response: {response.text}")
                    return False
            except Exception as e:
                logger.error(f"Error claiming rewards for {self.username}: {str(e)}")
                return False
    
    def main():
        username = "emrebeyler"
        posting_key = os.getenv('HOLOZING_ACCOUNT_POSTING_KEY')
        
        if not all([username, posting_key]):
            logger.error("Missing credentials in environment variables")
            return
    
        client = HolozingClient(username, posting_key)
        
        # First check if there are any rewards
        rewards = client.check_pending_rewards()
        
        if rewards['total'] <= 0:
            logger.info("No rewards available to claim")
            return
        
        # Only proceed with login and claim if there are rewards
        logger.info("Found claimable rewards. Proceeding with claim process...")
        if client.login():
            client.claim_rewards()
        else:
            logger.error("Failed to login for claiming")
    
    if __name__ == "__main__":
        main()
    

    Required packages:

    beem>=0.24.26
    requests>=2.31.0
    python-dotenv>=1.0.0
    

    create .env file in the script, put your posting key as HOLOZING_POSTING_KEY=..., then just run the script. Basic knowledge about running python scripts and python environments are required.

    *P.S: Most of the code is written by Cursor AI Editor, can only get credits by giving it correct and clear directions.

      Authors get paid when people like you upvote their post.
      If you enjoyed what you read here, create your account today and start earning FREE VOILK!