Created
June 12, 2025 14:56
-
-
Save TheCrazyGM/b49432e0ecc294940280e77cbe470e04 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env -S uv run --quiet --script | |
| # /// script | |
| # requires-python = ">=3.13" | |
| # dependencies = [ | |
| # "hive-nectar", | |
| # "nectarengine", | |
| # "rich", | |
| # ] | |
| # | |
| # [tool.uv.sources] | |
| # hive-nectar = { git = "https://github.com/thecrazygm/hive-nectar" } | |
| # nectarengine = { git = "https://github.com/thecrazygm/nectarengine" } | |
| # /// | |
| import argparse | |
| import sys | |
| from datetime import datetime | |
| from typing import Any, Dict | |
| from nectar.account import Account | |
| from nectar.hive import Hive | |
| from nectarengine.api import Api | |
| from nectarengine.tokenobject import Token | |
| from nectarengine.wallet import Wallet as hWallet | |
| from rich.box import DOUBLE | |
| from rich.console import Console, Group | |
| from rich.panel import Panel | |
| from rich.table import Table | |
| from rich.text import Text | |
| # Default Hive nodes – can be extended if necessary | |
| NODES = ["https://api.hive.blog"] | |
| def calculate_dividends( | |
| account_name: str, | |
| token_symbol: str, | |
| currency_symbol: str = "HIVE", | |
| unit_reward: float = 0.001, | |
| sim_balance: float | None = None, | |
| ) -> Dict[str, Any]: | |
| """Return dividend‐related metrics for *token_symbol* owned by *account_name*. | |
| Parameters | |
| ---------- | |
| account_name : str | |
| Hive username to inspect. | |
| token_symbol : str | |
| Symbol of the token whose *wild* supply determines dividend units. | |
| currency_symbol : str, default "HIVE" | |
| Asset used to pay dividends. Either "HIVE" or a Hive-Engine token symbol. | |
| unit_reward : float, default 0.001 | |
| Reward amount **per dividend unit**. | |
| sim_balance : float | None, default None | |
| Simulated balance to override actual available balance. | |
| """ | |
| # Hive & Hive Engine setup | |
| hive = Hive(node=NODES) | |
| api = Api(url="https://engine.thecrazygm.com/") | |
| wallet = hWallet(account_name, api=api) | |
| # On-chain data for the target token | |
| token = Token(token_symbol) | |
| token_balance = wallet.get_token(token_symbol) | |
| # Determine available balance in chosen currency for dividend payment | |
| if currency_symbol.upper() == "HIVE": | |
| actual_balance = float( | |
| Account(account_name, blockchain_instance=hive).get_balance( | |
| "available", "HIVE" | |
| ) | |
| ) | |
| else: | |
| # Treat as Hive-Engine token | |
| cur_bal_info = wallet.get_token(currency_symbol.upper()) | |
| if cur_bal_info is None: | |
| raise ValueError( | |
| f"Balance for token '{currency_symbol}' not found in account '{account_name}'." | |
| ) | |
| actual_balance = float(cur_bal_info.get("balance", 0)) | |
| # Override with simulated balance if provided | |
| available_balance = sim_balance if sim_balance is not None else actual_balance | |
| supply = float(token["supply"]) | |
| held = float(token_balance["balance"]) | |
| wild = supply - held # tokens not held by the account holder | |
| # Cost (in *currency_symbol*) to pay *unit_reward* per *wild* token | |
| div_unit = wild * unit_reward if wild else 0 | |
| # How many units we can fund with available balance | |
| num_div = available_balance // div_unit if div_unit else 0 | |
| # Total outgoing reward | |
| total_reward = num_div * unit_reward | |
| return { | |
| "available_balance": available_balance, | |
| "actual_balance": actual_balance, | |
| "simulated": sim_balance is not None, | |
| "supply": supply, | |
| "held": held, | |
| "wild": wild, | |
| "div_unit": div_unit, | |
| "num_div": num_div, | |
| "unit_reward": unit_reward, | |
| "total_reward": total_reward, | |
| "currency": currency_symbol.upper(), | |
| } | |
| def display_dividends( | |
| account_name: str, | |
| token_symbol: str, | |
| currency_symbol: str = "HIVE", | |
| unit_reward: float = 0.001, | |
| sim_balance: float | None = None, | |
| ) -> int: | |
| """Render dividend data in a Rich panel.""" | |
| console = Console() | |
| data = calculate_dividends( | |
| account_name, token_symbol, currency_symbol, unit_reward, sim_balance | |
| ) | |
| # Header & sub-header | |
| header = Text(f"Dividend Projection for {account_name}", style="bold cyan") | |
| token_info = Text(f"Token: {token_symbol}", style="bold green") | |
| # Table with metrics | |
| table = Table( | |
| title="Dividend Calculation", | |
| show_header=True, | |
| header_style="bold magenta", | |
| padding=(0, 1), | |
| expand=False, | |
| border_style="blue", | |
| box=DOUBLE, | |
| title_justify="center", | |
| ) | |
| table.add_column("Metric", style="cyan") | |
| table.add_column("Value", style="yellow", justify="right") | |
| balance_label = ( | |
| f"Simulated Balance {data['currency']}" | |
| if data.get("simulated") | |
| else f"Available {data['currency']}" | |
| ) | |
| rows = [ | |
| (balance_label, f"{data['available_balance']:.6f}"), | |
| ("Token Supply", f"{data['supply']:.3f}"), | |
| ("Held Tokens", f"{data['held']:.3f}"), | |
| ("Tokens in Wild", f"{data['wild']:.3f}"), | |
| ( | |
| f"Dividend Unit Cost ( @ {data['unit_reward']} {data['currency']})", | |
| f"{data['div_unit']:.6f}", | |
| ), | |
| ("Dividend Units", f"{data['num_div']:.0f}"), | |
| ( | |
| f"Projected Dividend ({data['currency']})", | |
| f"{data['total_reward']:.6f}", | |
| ), | |
| ] | |
| for metric, value in rows: | |
| table.add_row(metric, value) | |
| # Footer timestamp | |
| footer = Text( | |
| f"Updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", style="dim italic" | |
| ) | |
| group = Group( | |
| header, | |
| token_info, | |
| Panel(table, border_style="blue", padding=(0, 0)), | |
| footer, | |
| ) | |
| panel = Panel( | |
| group, | |
| title="[bold blue]Dividend Calculator[/bold blue]", | |
| subtitle="[dim]Powered by Nectar, NectarEngine & Rich[/dim]", | |
| title_align="center", | |
| subtitle_align="right", | |
| border_style="cyan", | |
| padding=(1, 1), | |
| expand=True, | |
| width=min(console.width - 2, 120), | |
| ) | |
| console.print(panel) | |
| return 0 | |
| def main() -> int: | |
| parser = argparse.ArgumentParser( | |
| description="Compute dividend projection for a Hive Engine token." | |
| ) | |
| parser.add_argument( | |
| "-a", "--account", default="armero", help="Hive account name (default: armero)" | |
| ) | |
| parser.add_argument( | |
| "-t", "--token", default="ARMERO", help="Token symbol (default: ARMERO)" | |
| ) | |
| parser.add_argument( | |
| "-c", | |
| "--currency", | |
| default="HIVE", | |
| help="Asset used to pay dividends (default: HIVE; use a Hive-Engine symbol for tokens).", | |
| ) | |
| parser.add_argument( | |
| "-u", | |
| "--unit", | |
| type=float, | |
| default=0.001, | |
| help="Reward per dividend unit (default: 0.001).", | |
| ) | |
| parser.add_argument( | |
| "-s", | |
| "--simulate-balance", | |
| type=float, | |
| help="Override available balance with a simulated amount for projection.", | |
| ) | |
| args = parser.parse_args() | |
| try: | |
| return display_dividends( | |
| args.account, args.token, args.currency, args.unit, args.simulate_balance | |
| ) | |
| except Exception as exc: | |
| Console().print(f"[bold red]Error:[/bold red] {exc}", style="red") | |
| return 1 | |
| if __name__ == "__main__": | |
| sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment