Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions gittensor/cli/miner_commands/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
from rich.console import Console
from rich.table import Table

from .helpers import _get_validator_axons
from .post import NETUID_DEFAULT, _error, _load_config_value, _resolve_endpoint
from .helpers import NETUID_DEFAULT, _error, _get_validator_axons, _load_config_value, _resolve_endpoint

console = Console()

Expand Down
47 changes: 47 additions & 0 deletions gittensor/cli/miner_commands/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

from __future__ import annotations

import json
from pathlib import Path

import click
from rich.console import Console

from gittensor.constants import NETWORK_MAP

console = Console()

NETUID_DEFAULT = 74


def _get_validator_axons(metagraph) -> tuple[list, list]:
"""Return (axons, uids) for all active validators (vtrust > 0.1, serving)."""
Expand All @@ -14,3 +26,38 @@ def _get_validator_axons(metagraph) -> tuple[list, list]:
axons.append(metagraph.axons[uid])
uids.append(uid)
return axons, uids


def _load_config_value(key: str):
"""Load a value from ~/.gittensor/config.json, or None."""
config_file = Path.home() / '.gittensor' / 'config.json'
if not config_file.exists():
return None
try:
config = json.loads(config_file.read_text())
return config.get(key)
except (json.JSONDecodeError, OSError):
return None


def _resolve_endpoint(network: str | None, rpc_url: str | None) -> str:
"""Resolve the subtensor endpoint from CLI args or config."""
if rpc_url:
return rpc_url
if network:
return NETWORK_MAP.get(network.lower(), network)
config_network = _load_config_value('network')
config_endpoint = _load_config_value('ws_endpoint')
if config_endpoint:
return config_endpoint
if config_network:
return NETWORK_MAP.get(config_network.lower()) or config_network
return NETWORK_MAP['finney']


def _error(msg: str, json_mode: bool) -> None:
"""Print an error message in the appropriate format."""
if json_mode:
click.echo(json.dumps({'success': False, 'error': msg}))
else:
console.print(f'[red]Error: {msg}[/red]')
42 changes: 8 additions & 34 deletions gittensor/cli/miner_commands/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,17 @@
from rich.console import Console
from rich.table import Table

from gittensor.cli.issue_commands.helpers import resolve_network
from gittensor.cli.miner_commands.helpers import _get_validator_axons
from gittensor.cli.miner_commands.helpers import (
NETUID_DEFAULT,
_error,
_get_validator_axons,
_load_config_value,
_resolve_endpoint,
)
from gittensor.constants import BASE_GITHUB_API_URL

console = Console()

# Shared CLI options for wallet/network configuration
NETUID_DEFAULT = 74


def _resolve_endpoint(network: str | None, rpc_url: str | None) -> str:
"""Resolve miner network options to a websocket endpoint."""
ws_endpoint, _ = resolve_network(network=network, rpc_url=rpc_url)
return ws_endpoint


@click.command()
@click.option('--wallet', 'wallet_name', default=None, help='Bittensor wallet name.')
Expand Down Expand Up @@ -89,7 +85,7 @@ def miner_post(wallet_name, wallet_hotkey, netuid, network, rpc_url, pat, json_m
# 2. Resolve wallet and network
wallet_name = wallet_name or _load_config_value('wallet') or 'default'
wallet_hotkey = wallet_hotkey or _load_config_value('hotkey') or 'default'
ws_endpoint = _resolve_endpoint(network=network, rpc_url=rpc_url)
ws_endpoint = _resolve_endpoint(network, rpc_url)

if not json_mode:
console.print(f'[dim]Wallet: {wallet_name}/{wallet_hotkey} | Network: {ws_endpoint} | Netuid: {netuid}[/dim]')
Expand Down Expand Up @@ -223,25 +219,3 @@ def _validate_pat_locally(pat: str) -> bool:
return True
except requests.RequestException:
return False


def _load_config_value(key: str):
"""Load a value from ~/.gittensor/config.json, or None."""
from pathlib import Path

config_file = Path.home() / '.gittensor' / 'config.json'
if not config_file.exists():
return None
try:
config = json.loads(config_file.read_text())
return config.get(key)
except (json.JSONDecodeError, OSError):
return None


def _error(msg: str, json_mode: bool):
"""Print an error message in the appropriate format."""
if json_mode:
click.echo(json.dumps({'success': False, 'error': msg}))
else:
console.print(f'[red]Error: {msg}[/red]')
Loading