[EN/PT-BR] Python on holiday and joy in advancing even further in programming with Hive!

avatar
(Edited)

image.png
Brasilcode

divisor.jpeg

It's been a while since I've programmed anything in code to help me or just play around with Hive. My last project was an offline project that formatted small texts for the inleo standard, threads (from meta) and for X. Each one with its own way of using tags or text formatting commands.

In addition, it already translated from Brazilian Portuguese to English, making it easier to copy and paste wherever needed. I stopped working on the project because I ended up losing the source code along with one of my SSDs, but at the moment I can even do better, after all, this program called "Free Translator" was practically offline, it just accessed an API or URL (I don't remember) that did the translation.

image.png

Taking advantage of today's holiday, I wanted to play around a bit and create something I've been wanting to do for a while: access to HiveSQL and Hive Engine to get my total dividends (everything that came in as Hive tokens) and, along with that, calculate the APR on top of the L2 tokens.

This was crazy, but now I'm more relaxed, because I finally managed to do it! Just 3 Python files, a lot of ChatGPT and help from two great friends: @mengao and @gwajnberg and with that, I can already say that I have a first version done.

image.png

As I said, there is no turning back when it comes to using artificial intelligence. I probably would never have done this just by studying and searching on Google. So, I didn't keep track of the hours, but I probably spent about 3 hours last night, from 11 pm to 2 am messing around with no success. And today probably another 7 or 8 hours, starting at 9 am and finishing now around 3 pm, I didn't even have lunch to tell you the truth haha.

I started by doing:

pip install hiveengine
pip install beem
pip install nectarengine

And nothing, none of them would install, the result was a problem with OpenSSL, which I had already installed in version 3.5 and everything else. Oddly enough, I had to use ChatGPT with all my strength and that's how I discovered that I needed version 1.1.1 of OpenSSL to be able to install any of these packages/libraries.

After that, phew, I took a deep breath and was left with just this command:

pip install hiveengine

With that, everything was very simple, a main file to start and call the functions and then print the file in the terminal:

import Conexao as conexao
import CmdHiveEngine as hiveengine

from tabulate import tabulate

# Mapeamento de perfil_envio para token
perfil_para_token = {
    "armero": "ARMERO",
    #"bee.drone": "BEE",
    "beeswap.fees": "BXT",
    "dab-treasury": "DAB",
    "dcityfund": "SIM",
    "duo-sales": "DUO",
    "eds-pay": "EDSI",
    "lgndivs": "LGN",
    "pakx": "PAKX",
    "tokenpimp": "PIMP",
    "vetfunding": "CAV"
}

try:
    
    Campos = "UPPER([FROM]) AS perfil_envio," + "\r\n"
    Campos += "SUM(amount) AS week_income" + "\r\n"
    Tabelas = "TxTransfers tt" + "\r\n"
    Criterio = "[TO] = 'shiftrox'" + "\r\n"
    Criterio += "AND [type] NOT IN ('transfer_from_savings','transfer_to_savings')" + "\r\n"
    Criterio += "AND tt.[timestamp] >= DATEADD(day, -7, GETDATE())" + "\r\n"
    Criterio += "AND tt.amount_symbol = 'HIVE'" + "\r\n"
    Criterio += "AND tt.[FROM] <> 'shiftrox'" + "\r\n"
    Criterio += "GROUP BY [FROM]" + "\r\n"
    Ordem = "UPPER([FROM])"+ "\r\n"

    rsResultado = conexao.RetReg(Campos, Tabelas, Criterio, Ordem)

    if rsResultado and isinstance(rsResultado[0], dict):
        
        dblMenorPreco : float = 0.0
        dblTotal : float = 0.0
        intQtdeSemanas : int = 52

        # Extrair os cabeçalhos (nomes das colunas) do primeiro dicionário
        headers = list(rsResultado[0].keys())  # Converte dict_keys para lista
        
        # Adicionar a nova coluna que será manipulada manualmente
        headers.append("HOLDING")
        headers.append("HIVE_PRICE")
        headers.append("HIVE_VALUE")
        headers.append("APR")

        for item in rsResultado:
            
            dblTokenBalance = 0
            dblMenorPreco = 0

            #buscando holding, stake e menor preco
            token = perfil_para_token.get(item["perfil_envio"].lower(), "nenhum")

            if token != "nenhum":
                
                dblTokenBalance = hiveengine.get_token_balance("shiftrox", token)

                dblMenorPreco = hiveengine.obter_menor_preco_venda(token)

            else:
                dblTokenBalance = 0
            #buscando holding e stake

            # Calcular valores numéricos
            holding = float(dblTokenBalance)
            hive_price = float(dblMenorPreco)
            hive_value = holding * hive_price

            # Guardar valores numéricos para cálculos
            item["HOLDING"] = holding
            item["HIVE_PRICE"] = hive_price
            item["HIVE_VALUE"] = hive_value

            item["APR"] = ((float(item["week_income"]) * intQtdeSemanas) / hive_value) * 100 if hive_value != 0 else 0.0

            # Agora formatar os valores apenas para exibição (ex: tabulate)
            item["HOLDING"] = f"{holding:,.8f}"
            item["HIVE_PRICE"] = f"{hive_price:,.8f}"
            item["HIVE_VALUE"] = f"{hive_value:,.8f}"
            item["APR"] = f"{item['APR']:.2f}%"

            dblTotal += float(item["week_income"])

        # Criar linha de total
        total_row = {
            "perfil_envio": "Total:",
            "week_income": f"{dblTotal:.3f}",  # formatado com 3 casas decimais
            "APR": ""
        }

        # Adicionar a linha ao final da lista
        rsResultado.append(total_row)

        print(tabulate(rsResultado, headers="keys", tablefmt="grid"))
    
    else:
        print("Nenhum resultado retornado ou formato não suportado.")

except Exception as erro:
    print("Erro Principal =>", erro)

And so some APRs were calculated. I thought it was great to finally be able to access more layers of Hive to create a program that will help me a lot to understand how my dividend gains are going. Of course, I still need to improve it, it only searches for tokens that are liquid and some are calculated only with them in stake, so the next step will be to improve this.

Some things related to formatting also need to be improved, I want to put everything with 8 decimal places, which is the maximum that appears in the portfolios, and thus align it as much as possible with them. I also need to translate everything into English to make it more eye-catching and improve some small points.

image.png

There is also a totalizer, so in this case in the last 7 days I earned a total of 20.75 Hive just with dividends and transfers from other profiles. I am not interested in setting up something in HBD at the moment, especially because none of the tokens I have pays in HBD.

One thing that has always left me in doubt is regarding the filter date. In my mind I should always take 7 days, but I don't think I should count today, but I took a look at https://hivestats.io/@shiftrox and saw that their 7-day option filters exactly (Today - 7 days), so they take for example everything that happened on 04/25/2025 until today, 05/01/2025).

Criterion += "AND tt.[timestamp] >= DATEADD(day, -7, GETDATE())" + "\r\n"

I don't know if this is good for dividends, maybe I'll change it to consider (yesterday - 7 days), that is, work with days that are already "closed", but anyway, there's still a lot to improve.

Finally, the code to find the amount of tokens I have and their lowest market value was:

import requests

from hiveengine.api import Api
#from hiveengine.market import Market

def obter_menor_preco_venda(token_symbol):
    try:

        api = Api()

        sell_orders = api.find("market", "sellBook", query={"symbol": token_symbol})
        
        if not sell_orders:
            #return f"Não há ordens de venda para o token {token_symbol} no momento."
            return 0

        menor_preco = min(sell_orders, key=lambda x: float(x['price']))

        dblMenorPreco = str(menor_preco['price'])

        return dblMenorPreco
    
    except Exception as e:
        print(f"Ocorreu um erro: {e}")
        return 0
    
def get_token_balance(usuario: str, token: str) -> float:
    
    url = "https://api.hive-engine.com/rpc/contracts"

    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "find",
        "params": {
            "contract": "tokens",
            "table": "balances",
            "query": {
                "account": usuario,
                "symbol": token.upper()
            },
            "limit": 1
        }
    }

    try:
        response = requests.post(url, json=payload)
        response.raise_for_status()
        result = response.json().get("result", [])

        if result:
            return float(result[0].get("balance", 0.0))
        else:
            return 0.0

    except requests.RequestException as e:
        print(f"Erro ao acessar a API: {e}")
        return 0.0

get_token_balance() came out as a URL search, then I want to see if I can find it via the hiveengine library, just like the get_lowest_sale_price() function was created, to centralize everything using the API.

Anyway, the first steps have been taken, now it's time to burn neurons to do more! First you start and then you improve!

sun_divisor.webp

image.png
Brasilcode

divisor.jpeg

Já faz um bom tempo que não programo nada em código para me auxiliar ou apenas brincar juntamente com a Hive. Meu ultimo projeto foi um offline que formatava pequenos textos para o padrão da inleo, threads (da meta) e para o X. Cada um com sua respectiva forma de usar tags ou comandos de formatação de texto.

Além de que ele já fazia a tradução do português do Brasil para o inglês, facilitando assim poder copiar e colar aonde fosse preciso. Parei de mexer no projeto porque acabei perdendo o código fonte juntamente com um SSD meu, mas no momento posso até fazer melhor, afinal, esse programa chamado de "Tradutor Livre" era praticamente offline, apenas acessava uma API ou URL (não lembro) que fazia a tradução.

image.png

Aproveitando o feriado de hoje, quis brincar um pouco e criar algo que sentia necessidade de fazer há algum tempo: acesso ao HiveSQL e Hive Engine, para buscar o meu total de dividendos (tudo que entrou de token Hive) e juntamente com isso, calcular o APR em cima dos tokens da L2.

Muito maluco isso, mas agora, estou mais tranquilo, pois finalmente consegui fazer! Apenas 3 arquivos em Python, muito ChatGPT e ajuda de dois grandes amigos: @mengao e @gwajnberg e com isso, já posso dizer que tem uma primeira versão feita.

image.png

É como digo, não tem mais volta no uso de inteligência artificial. Eu provavelmente nunca teria feito isso aqui somente com estudo e buscando no google. Então, não marquei as horas, mas provavelmente gastei umas 3 horas ontem a noite, fiquei das 11 da noite até as 2 da manhã mexendo e sem sucesso. E hoje provavelmente mais umas 7 ou 8 horas, começando as 9 da manhã e finalizando agora por volta das 3 da tarde, eu nem almocei para falar a verdade haha.

Comecei fazendo:

pip install hiveengine
pip install beem
pip install nectarengine

E nada, nenhum deles instalava, o retorno era problema com OpenSSL que já havia instalado na versão 3.5 e tudo mais. Por incrível que pareça, precisei o usar o ChatGPT com todas as forças e assim descobri que precisava da versão 1.1.1 do OpenSSL para poder instalar qualquer um destes pacotes/bibliotecas.

Depois disso, ufa, respirei fundo e fiquei apenas com este comando:

pip install hiveengine

Com isso era tudo bem simples, um arquivo principal para iniciar e chamar as funções e depois realizar o print no terminal:

import Conexao as conexao
import CmdHiveEngine as hiveengine

from tabulate import tabulate

# Mapeamento de perfil_envio para token
perfil_para_token = {
    "armero": "ARMERO",
    #"bee.drone": "BEE",
    "beeswap.fees": "BXT",
    "dab-treasury": "DAB",
    "dcityfund": "SIM",
    "duo-sales": "DUO",
    "eds-pay": "EDSI",
    "lgndivs": "LGN",
    "pakx": "PAKX",
    "tokenpimp": "PIMP",
    "vetfunding": "CAV"
}

try:
    
    Campos = "UPPER([FROM]) AS perfil_envio," + "\r\n"
    Campos += "SUM(amount) AS week_income" + "\r\n"
    Tabelas = "TxTransfers tt" + "\r\n"
    Criterio = "[TO] = 'shiftrox'" + "\r\n"
    Criterio += "AND [type] NOT IN ('transfer_from_savings','transfer_to_savings')" + "\r\n"
    Criterio += "AND tt.[timestamp] >= DATEADD(day, -7, GETDATE())" + "\r\n"
    Criterio += "AND tt.amount_symbol = 'HIVE'" + "\r\n"
    Criterio += "AND tt.[FROM] <> 'shiftrox'" + "\r\n"
    Criterio += "GROUP BY [FROM]" + "\r\n"
    Ordem = "UPPER([FROM])"+ "\r\n"

    rsResultado = conexao.RetReg(Campos, Tabelas, Criterio, Ordem)

    if rsResultado and isinstance(rsResultado[0], dict):
        
        dblMenorPreco : float = 0.0
        dblTotal : float = 0.0
        intQtdeSemanas : int = 52

        # Extrair os cabeçalhos (nomes das colunas) do primeiro dicionário
        headers = list(rsResultado[0].keys())  # Converte dict_keys para lista
        
        # Adicionar a nova coluna que será manipulada manualmente
        headers.append("HOLDING")
        headers.append("HIVE_PRICE")
        headers.append("HIVE_VALUE")
        headers.append("APR")

        for item in rsResultado:
            
            dblTokenBalance = 0
            dblMenorPreco = 0

            #buscando holding, stake e menor preco
            token = perfil_para_token.get(item["perfil_envio"].lower(), "nenhum")

            if token != "nenhum":
                
                dblTokenBalance = hiveengine.get_token_balance("shiftrox", token)

                dblMenorPreco = hiveengine.obter_menor_preco_venda(token)

            else:
                dblTokenBalance = 0
            #buscando holding e stake

            # Calcular valores numéricos
            holding = float(dblTokenBalance)
            hive_price = float(dblMenorPreco)
            hive_value = holding * hive_price

            # Guardar valores numéricos para cálculos
            item["HOLDING"] = holding
            item["HIVE_PRICE"] = hive_price
            item["HIVE_VALUE"] = hive_value

            item["APR"] = ((float(item["week_income"]) * intQtdeSemanas) / hive_value) * 100 if hive_value != 0 else 0.0

            # Agora formatar os valores apenas para exibição (ex: tabulate)
            item["HOLDING"] = f"{holding:,.8f}"
            item["HIVE_PRICE"] = f"{hive_price:,.8f}"
            item["HIVE_VALUE"] = f"{hive_value:,.8f}"
            item["APR"] = f"{item['APR']:.2f}%"

            dblTotal += float(item["week_income"])

        # Criar linha de total
        total_row = {
            "perfil_envio": "Total:",
            "week_income": f"{dblTotal:.3f}",  # formatado com 3 casas decimais
            "APR": ""
        }

        # Adicionar a linha ao final da lista
        rsResultado.append(total_row)

        print(tabulate(rsResultado, headers="keys", tablefmt="grid"))
    
    else:
        print("Nenhum resultado retornado ou formato não suportado.")

except Exception as erro:
    print("Erro Principal =>", erro)

E assim calculado alguns APR. Achei sensacional isso de conseguir finalmente acessar mais camadas da Hive para fazer um programa que irá me ajudar bastante a entender como está os meus ganhos de dividendos. Claro que ainda preciso melhorar, está buscando apenas os tokens que estão líquidos e alguns são calculados apenas com eles em stake, então o próximo passo vai ser melhorar isso.

Algumas coisas relacionadas a formatação também precisam ser melhoradas, quero colocar tudo com 8 casas decimais que é o máximo que aparece nas carteiras e com isso já alinhar o máximo possível com elas. Falta passar tudo para o inglês também para ficar mais chamativo e melhorar alguns pequenos pontos.

image.png

Já tem um totalizador também, então neste caso nos últimos 7 dias eu ganhei um total de 20,75 Hive apenas com dividendos e transferências de outros perfis. Não tenho interesse no momento de montar algo em HBD, até porque nenhum token que eu tenho paga em HBD.

Uma coisa que sempre me deixou em dúvidas é em relação a data de filtro. Na minha mente devo pegar sempre 7 dias, mas acho que não deveria contar o dia de hoje, mas dei uma olhada no https://hivestats.io/@shiftrox e vi que a opção de 7 dias deles filtra exatamente (Hoje - 7 dias), então eles pegam por exemplo tudo o que aconteceu no dia 25/04/2025 até hoje, 01/05/2025).

Criterio += "AND tt.[timestamp] >= DATEADD(day, -7, GETDATE())" + "\r\n"

Não sei se para dividendos isso é bom, talvez mude para considerar (ontem - 7 dias), ou seja, trabalhar com dias já "fechados", mas enfim, tem muita coisa por aí ainda para melhorar.

Por fim o código para buscar a quantidade de token que tenho e o seu menor valor de mercado foi:

import requests

from hiveengine.api import Api
#from hiveengine.market import Market

def obter_menor_preco_venda(token_symbol):
    try:

        api = Api()

        sell_orders = api.find("market", "sellBook", query={"symbol": token_symbol})
        
        if not sell_orders:
            #return f"Não há ordens de venda para o token {token_symbol} no momento."
            return 0

        menor_preco = min(sell_orders, key=lambda x: float(x['price']))

        dblMenorPreco = str(menor_preco['price'])

        return dblMenorPreco
    
    except Exception as e:
        print(f"Ocorreu um erro: {e}")
        return 0
    
def get_token_balance(usuario: str, token: str) -> float:
    
    url = "https://api.hive-engine.com/rpc/contracts"

    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "find",
        "params": {
            "contract": "tokens",
            "table": "balances",
            "query": {
                "account": usuario,
                "symbol": token.upper()
            },
            "limit": 1
        }
    }

    try:
        response = requests.post(url, json=payload)
        response.raise_for_status()
        result = response.json().get("result", [])

        if result:
            return float(result[0].get("balance", 0.0))
        else:
            return 0.0

    except requests.RequestException as e:
        print(f"Erro ao acessar a API: {e}")
        return 0.0

get_token_balance() saiu como busca por URL, depois quero ver se consigo encontrar via a biblioteca do hiveengine, assim como foi feita a função obter_menor_preco_venda(), para centralizar tudo no uso da API.

Enfim, primeiros passos dados, agora é queimar neurônio para fazer mais! Primeiro você começa e depois você melhora!

divisor.jpeg

banner_hiver_br_01.png


Follow me on X (Formerly Twitter)

🔹Hive Games🔹

🔸Splinterlands🔸Holozing🔸Terracore🔸dCrops🔸Rising Star🔸



0
0
0.000
12 comments
avatar

Bzzzrrr, que legal que você está de volta ao mundo do programação! Fico feliz que tenha conseguido superar os problemas e agora tenha uma versão funcional do Free Translator. Parabéns pelo esforço e pela paciência!

#hivebr

AI generated content
Commands: !pixbee stop | !pixbee start | !pixbee price

0
0
0.000
avatar

Congratulations @shiftrox! You received a personal badge!

You powered-up at least 100 HP on Hive Power Up Day! This entitles you to a level 3 badge
Participate in the next Power Up Day and try to power-up more HIVE to get a bigger Power-Bee.
May the Hive Power be with you!

You can view your badges on your board and compare yourself to others in the Ranking

Check out our last posts:

Hive Power Up Month Challenge - April 2025 Winners List
Be ready for the May edition of the Hive Power Up Month!
Hive Power Up Day - May 1st 2025
0
0
0.000
avatar

Congratulations @shiftrox! You received a personal badge!

You made another user happy by powering him up some HIVE on Hive Power Up Day and got awarded this Power Up Helper badge.

You can view your badges on your board and compare yourself to others in the Ranking

Check out our last posts:

Hive Power Up Month Challenge - April 2025 Winners List
Be ready for the May edition of the Hive Power Up Month!
Hive Power Up Day - May 1st 2025
0
0
0.000
avatar

Thanks!!!

0
0
0.000
avatar

Congratulations @shiftrox! You're doing your part to make Hive stronger. Keep up the great work! 💪

0
0
0.000
avatar

Well done 👍. Great Job.

0
0
0.000
avatar

Thanks my friend, now it's time to develop more things hehe

0
0
0.000
avatar

Okay. Keep working like this, success will touch your feet with excellent results and it is waiting for you.
Well done

0
0
0.000