cartha-cli 1.0.5__py3-none-any.whl → 1.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cartha_cli/bt.py CHANGED
@@ -51,92 +51,100 @@ def register_hotkey(
51
51
  """Register a hotkey on the target subnet and return the resulting UID."""
52
52
 
53
53
  subtensor = get_subtensor(network)
54
- wallet = get_wallet(wallet_name, hotkey_name)
55
- hotkey_ss58 = wallet.hotkey.ss58_address
56
-
57
- if subtensor.is_hotkey_registered(hotkey_ss58, netuid=netuid):
58
- neuron = subtensor.get_neuron_for_pubkey_and_subnet(hotkey_ss58, netuid)
59
- uid = None if getattr(neuron, "is_null", False) else getattr(neuron, "uid", None)
60
- return RegistrationResult(status="already", success=True, uid=uid, hotkey=hotkey_ss58)
54
+ try:
55
+ wallet = get_wallet(wallet_name, hotkey_name)
56
+ hotkey_ss58 = wallet.hotkey.ss58_address
61
57
 
62
- # Get balance before registration
63
- balance_before = None
64
- balance_after = None
65
- extrinsic = None
58
+ if subtensor.is_hotkey_registered(hotkey_ss58, netuid=netuid):
59
+ neuron = subtensor.get_neuron_for_pubkey_and_subnet(hotkey_ss58, netuid)
60
+ uid = None if getattr(neuron, "is_null", False) else getattr(neuron, "uid", None)
61
+ return RegistrationResult(status="already", success=True, uid=uid, hotkey=hotkey_ss58)
66
62
 
67
- try:
68
- balance_obj = subtensor.get_balance(wallet.coldkeypub.ss58_address)
69
- # Convert Balance object to float using .tao property
70
- balance_before = balance_obj.tao if hasattr(balance_obj, "tao") else float(balance_obj)
71
- except Exception:
72
- pass # Balance may not be available, continue anyway
73
-
74
- if burned:
75
- # burned_register returns (success, block_info) or just success
76
- registration_result = subtensor.burned_register(
77
- wallet=wallet,
78
- netuid=netuid,
79
- wait_for_finalization=wait_for_finalization,
80
- )
63
+ # Get balance before registration
64
+ balance_before = None
65
+ balance_after = None
66
+ extrinsic = None
81
67
 
82
- # Handle both return types: bool or (bool, message)
83
- if isinstance(registration_result, tuple):
84
- ok, message = registration_result
85
- if isinstance(message, str) and message:
86
- extrinsic = message
68
+ try:
69
+ balance_obj = subtensor.get_balance(wallet.coldkeypub.ss58_address)
70
+ # Convert Balance object to float using .tao property
71
+ balance_before = balance_obj.tao if hasattr(balance_obj, "tao") else float(balance_obj)
72
+ except Exception:
73
+ pass # Balance may not be available, continue anyway
74
+
75
+ if burned:
76
+ # burned_register returns (success, block_info) or just success
77
+ registration_result = subtensor.burned_register(
78
+ wallet=wallet,
79
+ netuid=netuid,
80
+ wait_for_finalization=wait_for_finalization,
81
+ )
82
+
83
+ # Handle both return types: bool or (bool, message)
84
+ if isinstance(registration_result, tuple):
85
+ ok, message = registration_result
86
+ if isinstance(message, str) and message:
87
+ extrinsic = message
88
+ else:
89
+ ok = registration_result
90
+
91
+ status = "burned"
87
92
  else:
88
- ok = registration_result
89
-
90
- status = "burned"
91
- else:
92
- ok = subtensor.register(
93
- wallet=wallet,
94
- netuid=netuid,
95
- wait_for_finalization=wait_for_finalization,
96
- wait_for_inclusion=wait_for_inclusion,
97
- cuda=cuda,
98
- dev_id=dev_id,
99
- tpb=tpb,
100
- num_processes=num_processes,
101
- log_verbose=False,
102
- )
103
- status = "pow"
104
- if isinstance(ok, tuple) and len(ok) == 2:
105
- ok, message = ok
106
- if isinstance(message, str):
107
- extrinsic = message
93
+ ok = subtensor.register(
94
+ wallet=wallet,
95
+ netuid=netuid,
96
+ wait_for_finalization=wait_for_finalization,
97
+ wait_for_inclusion=wait_for_inclusion,
98
+ cuda=cuda,
99
+ dev_id=dev_id,
100
+ tpb=tpb,
101
+ num_processes=num_processes,
102
+ log_verbose=False,
103
+ )
104
+ status = "pow"
105
+ if isinstance(ok, tuple) and len(ok) == 2:
106
+ ok, message = ok
107
+ if isinstance(message, str):
108
+ extrinsic = message
109
+
110
+ if not ok:
111
+ return RegistrationResult(
112
+ status=status,
113
+ success=False,
114
+ uid=None,
115
+ hotkey=hotkey_ss58,
116
+ balance_before=balance_before,
117
+ balance_after=balance_after,
118
+ extrinsic=extrinsic,
119
+ )
120
+
121
+ # Get balance after registration
122
+ try:
123
+ balance_obj = subtensor.get_balance(wallet.coldkeypub.ss58_address)
124
+ # Convert Balance object to float using .tao property
125
+ balance_after = balance_obj.tao if hasattr(balance_obj, "tao") else float(balance_obj)
126
+ except Exception:
127
+ pass
128
+
129
+ neuron = subtensor.get_neuron_for_pubkey_and_subnet(hotkey_ss58, netuid)
130
+ uid = None if getattr(neuron, "is_null", False) else getattr(neuron, "uid", None)
108
131
 
109
- if not ok:
110
132
  return RegistrationResult(
111
133
  status=status,
112
- success=False,
113
- uid=None,
134
+ success=True,
135
+ uid=uid,
114
136
  hotkey=hotkey_ss58,
115
137
  balance_before=balance_before,
116
138
  balance_after=balance_after,
117
139
  extrinsic=extrinsic,
118
140
  )
119
-
120
- # Get balance after registration
121
- try:
122
- balance_obj = subtensor.get_balance(wallet.coldkeypub.ss58_address)
123
- # Convert Balance object to float using .tao property
124
- balance_after = balance_obj.tao if hasattr(balance_obj, "tao") else float(balance_obj)
125
- except Exception:
126
- pass
127
-
128
- neuron = subtensor.get_neuron_for_pubkey_and_subnet(hotkey_ss58, netuid)
129
- uid = None if getattr(neuron, "is_null", False) else getattr(neuron, "uid", None)
130
-
131
- return RegistrationResult(
132
- status=status,
133
- success=True,
134
- uid=uid,
135
- hotkey=hotkey_ss58,
136
- balance_before=balance_before,
137
- balance_after=balance_after,
138
- extrinsic=extrinsic,
139
- )
141
+ finally:
142
+ # Clean up subtensor connection
143
+ try:
144
+ if hasattr(subtensor, "close"):
145
+ subtensor.close()
146
+ except Exception:
147
+ pass # Silently ignore cleanup errors
140
148
 
141
149
 
142
150
  def get_burn_cost(network: str, netuid: int) -> float | None:
@@ -17,7 +17,7 @@ from .common import console
17
17
  ENV_VAR_DOCS: dict[str, dict[str, Any]] = {
18
18
  "CARTHA_VERIFIER_URL": {
19
19
  "description": "URL of the Cartha verifier service",
20
- "default": "https://cartha-verifier-826542474079.us-central1.run.app",
20
+ "default": "https://cartha-verifier-193291340038.us-central1.run.app",
21
21
  "required": False,
22
22
  },
23
23
  "CARTHA_NETWORK": {
@@ -69,13 +69,6 @@ def miner_password(
69
69
  netuid = 78
70
70
  elif network == "finney":
71
71
  netuid = 35
72
- # Warn that mainnet is not live yet
73
- console.print()
74
- console.print("[bold yellow]⚠️ MAINNET NOT AVAILABLE YET[/]")
75
- console.print("[yellow]Cartha subnet is currently in testnet phase (subnet 78).[/]")
76
- console.print("[yellow]Mainnet (subnet 35) has not been announced yet.[/]")
77
- console.print("[dim]Use --network test to access testnet.[/]")
78
- console.print()
79
72
  # Note: netuid parameter is kept for backwards compatibility / explicit override
80
73
 
81
74
  from ..config import get_verifier_url_for_network
@@ -79,13 +79,6 @@ def miner_status(
79
79
  netuid = 78
80
80
  elif network == "finney":
81
81
  netuid = 35
82
- # Warn that mainnet is not live yet
83
- console.print()
84
- console.print("[bold yellow]⚠️ MAINNET NOT AVAILABLE YET[/]")
85
- console.print("[yellow]Cartha subnet is currently in testnet phase (subnet 78).[/]")
86
- console.print("[yellow]Mainnet (subnet 35) has not been announced yet.[/]")
87
- console.print("[dim]Use --network test to access testnet.[/]")
88
- console.print()
89
82
  # Note: netuid parameter is kept for backwards compatibility / explicit override
90
83
 
91
84
  from ..config import get_verifier_url_for_network
@@ -488,25 +481,14 @@ def miner_status(
488
481
 
489
482
  console.print(pool_table)
490
483
 
491
- # Concise reminder
492
- console.print()
493
- console.print("[bold cyan]━━━ Reminders ━━━[/]")
494
- console.print(
495
- "• Lock expiration: USDC returned automatically, emissions stop for that pool."
496
- )
497
- console.print(
498
- "• Top-ups/extensions: Happen automatically on-chain. No CLI action needed."
499
- )
500
- if pools and len(pools) > 1:
501
- console.print(
502
- "• Multiple pools: Each pool is tracked separately. Expired pools stop earning, others continue."
503
- )
504
-
505
484
  # Link to web interface
506
485
  console.print()
507
486
  console.print("[bold cyan]━━━ Web Interface ━━━[/]")
508
487
  console.print(
509
- "[cyan]🌐 View and manage your positions:[/] [bold]https://cartha.finance[/]"
488
+ "[cyan]🌐 Manage your positions:[/] [bold]https://cartha.finance[/]"
489
+ )
490
+ console.print(
491
+ "[dim] • Deposit new lock positions[/]"
510
492
  )
511
493
  console.print(
512
494
  "[dim] • View all your lock positions[/]"
@@ -517,8 +499,5 @@ def miner_status(
517
499
  console.print(
518
500
  "[dim] • Top up existing positions[/]"
519
501
  )
520
- console.print(
521
- "[dim] • Claim testnet USDC from faucet[/]"
522
- )
523
502
 
524
503
  return
@@ -34,26 +34,8 @@ from .shared_options import (
34
34
  json_output_option,
35
35
  )
36
36
 
37
- # Import pool name helper
38
- # Initialize fallback function first to ensure it's always defined
39
- def _fallback_pool_id_to_name(pool_id: str) -> str | None:
40
- """Simple fallback to decode pool ID."""
41
- try:
42
- hex_str = pool_id.lower().removeprefix("0x")
43
- pool_bytes = bytes.fromhex(hex_str)
44
- name = pool_bytes.rstrip(b"\x00").decode("utf-8", errors="ignore")
45
- if name and name.isprintable():
46
- return name
47
- except Exception:
48
- pass
49
- return None
50
-
51
- # Try to import from testnet module, fallback to default if not available
52
- try:
53
- from ..testnet.pool_ids import pool_id_to_name
54
- except (ImportError, ModuleNotFoundError):
55
- # Use fallback function
56
- pool_id_to_name = _fallback_pool_id_to_name
37
+ # Import pool name helper from pool_client (fetches from verifier API)
38
+ from ..pool_client import pool_id_to_name
57
39
 
58
40
 
59
41
  def pair_status(
@@ -100,13 +82,6 @@ def pair_status(
100
82
  netuid = 78
101
83
  elif network == "finney":
102
84
  netuid = 35
103
- # Warn that mainnet is not live yet
104
- console.print()
105
- console.print("[bold yellow]⚠️ MAINNET NOT AVAILABLE YET[/]")
106
- console.print("[yellow]Cartha subnet is currently in testnet phase (subnet 78).[/]")
107
- console.print("[yellow]Mainnet (subnet 35) has not been announced yet.[/]")
108
- console.print("[dim]Use --network test to access testnet.[/]")
109
- console.print()
110
85
  # Note: netuid parameter is kept for backwards compatibility / explicit override
111
86
 
112
87
  from ..config import get_verifier_url_for_network
@@ -5,33 +5,7 @@ from __future__ import annotations
5
5
  import typer
6
6
 
7
7
  from .common import console
8
-
9
- # Import pool helpers for pool_id conversion
10
- # Initialize fallback functions first to ensure they're always defined
11
- def _fallback_list_pools() -> dict[str, str]:
12
- """Fallback: return empty dict."""
13
- return {}
14
-
15
- def _fallback_pool_id_to_vault_address(pool_id: str) -> str | None:
16
- """Fallback: return None."""
17
- return None
18
-
19
- def _fallback_pool_id_to_chain_id(pool_id: str) -> int | None:
20
- """Fallback: return None."""
21
- return None
22
-
23
- # Try to import from testnet module, fallback to defaults if not available
24
- try:
25
- from ..testnet.pool_ids import (
26
- list_pools,
27
- pool_id_to_chain_id,
28
- pool_id_to_vault_address,
29
- )
30
- except (ImportError, ModuleNotFoundError):
31
- # Use fallback functions if import failed
32
- list_pools = _fallback_list_pools
33
- pool_id_to_vault_address = _fallback_pool_id_to_vault_address
34
- pool_id_to_chain_id = _fallback_pool_id_to_chain_id
8
+ from ..verifier import VerifierError, fetch_pools
35
9
 
36
10
 
37
11
  def pools(
@@ -48,47 +22,37 @@ def pools(
48
22
 
49
23
  OUTPUT:
50
24
  -------
51
- - Pool names: BTCUSD, ETHUSD, EURUSD, etc.
25
+ - Pool names: BTC/USD, ETH/USD, EUR/USD, etc.
52
26
  - Pool IDs: Full hex identifiers (0x...)
53
27
  - Vault addresses: Contract addresses for each pool
54
- - Chain IDs: Which blockchain network (e.g., 84532 for Base Sepolia)
28
+ - Chain IDs: Which blockchain network (8453 for Base Mainnet, 84532 for Base Sepolia)
55
29
 
56
30
  Use these pool names directly in 'cartha vault lock -p BTCUSD ...'
57
31
  """
58
32
  try:
59
- available_pools = list_pools()
33
+ # Fetch pools from verifier API
34
+ pools_list = fetch_pools()
60
35
 
61
36
  if json_output:
62
37
  # JSON output format
63
38
  import json
64
-
65
- pools_data = []
66
- for pool_name, pool_id_hex in sorted(available_pools.items()):
67
- vault_addr = pool_id_to_vault_address(pool_id_hex)
68
- chain_id = pool_id_to_chain_id(pool_id_hex)
69
- pool_data = {
70
- "name": pool_name,
71
- "pool_id": pool_id_hex,
72
- }
73
- if vault_addr:
74
- pool_data["vault_address"] = vault_addr
75
- if chain_id:
76
- pool_data["chain_id"] = chain_id
77
- pools_data.append(pool_data)
78
-
79
- console.print(json.dumps(pools_data, indent=2))
39
+ console.print(json.dumps(pools_list, indent=2))
80
40
  return
81
41
 
82
42
  # Multi-line text output
83
- if not available_pools:
43
+ if not pools_list:
84
44
  console.print("[yellow]No pools available.[/]")
85
45
  return
86
46
 
87
47
  console.print("\n[bold cyan]Available Pools[/]\n")
88
48
 
89
- for idx, (pool_name, pool_id_hex) in enumerate(sorted(available_pools.items()), 1):
90
- vault_addr = pool_id_to_vault_address(pool_id_hex)
91
- chain_id = pool_id_to_chain_id(pool_id_hex)
49
+ for idx, pool in enumerate(pools_list, 1):
50
+ pool_name = pool.get("name", "Unknown")
51
+ # Verifier returns camelCase keys
52
+ pool_id_hex = pool.get("poolId", "")
53
+ vault_addr = pool.get("vaultAddress")
54
+ chain_id = pool.get("chainId")
55
+ network = pool.get("network", "")
92
56
 
93
57
  # Ensure full pool ID is displayed (normalize to ensure 0x prefix)
94
58
  pool_id_display = pool_id_hex if pool_id_hex.startswith("0x") else f"0x{pool_id_hex}"
@@ -96,7 +60,16 @@ def pools(
96
60
  # Ensure full vault address is displayed
97
61
  vault_display = vault_addr if vault_addr else "[dim]N/A[/]"
98
62
 
99
- chain_display = str(chain_id) if chain_id else "[dim]N/A[/]"
63
+ # Format chain display with network name
64
+ if chain_id:
65
+ if chain_id == 8453:
66
+ chain_display = f"{chain_id} (Base Mainnet)"
67
+ elif chain_id == 84532:
68
+ chain_display = f"{chain_id} (Base Sepolia)"
69
+ else:
70
+ chain_display = str(chain_id)
71
+ else:
72
+ chain_display = "[dim]N/A[/]"
100
73
 
101
74
  console.print(f"[bold cyan]Pool {idx}:[/] {pool_name}")
102
75
  console.print(f" [yellow]Pool ID:[/] {pool_id_display}")
@@ -104,9 +77,13 @@ def pools(
104
77
  console.print(f" [dim]Chain ID:[/] {chain_display}")
105
78
 
106
79
  # Add spacing between pools except for the last one
107
- if idx < len(available_pools):
80
+ if idx < len(pools_list):
108
81
  console.print()
109
82
 
83
+ except VerifierError as exc:
84
+ console.print(f"[bold red]Error:[/] Failed to fetch pools from verifier: {exc}")
85
+ console.print("[dim]Tip: Check your network connection and verifier URL configuration.[/]")
86
+ raise typer.Exit(code=1)
110
87
  except Exception as exc:
111
88
  console.print(f"[bold red]Error:[/] Failed to list pools: {exc}")
112
89
  raise typer.Exit(code=1)
@@ -42,71 +42,17 @@ from .shared_options import (
42
42
  json_output_option,
43
43
  )
44
44
 
45
- # Import pool helpers for pool_id conversion
46
- # Initialize fallback functions first to ensure they're always defined
47
- def _fallback_pool_name_to_id(pool_name: str) -> str:
48
- """Fallback: encode pool name as hex."""
49
- name_bytes = pool_name.encode("utf-8")
50
- padded = name_bytes.ljust(32, b"\x00")
51
- return "0x" + padded.hex()
52
-
53
- def _fallback_pool_id_to_name(pool_id: str) -> str | None:
54
- """Fallback: try to decode."""
55
- try:
56
- hex_str = pool_id.lower().removeprefix("0x")
57
- pool_bytes = bytes.fromhex(hex_str)
58
- name = pool_bytes.rstrip(b"\x00").decode("utf-8", errors="ignore")
59
- return name if name and name.isprintable() else None
60
- except Exception:
61
- return None
62
-
63
- def _fallback_format_pool_id(pool_id: str) -> str:
64
- """Fallback: return pool_id as-is."""
65
- return pool_id
66
-
67
- def _fallback_list_pools() -> dict[str, str]:
68
- """Fallback: return empty dict."""
69
- return {}
70
-
71
- def _fallback_pool_id_to_vault_address(pool_id: str) -> str | None:
72
- """Fallback: return None."""
73
- return None
74
-
75
- def _fallback_vault_address_to_pool_id(vault_address: str) -> str | None:
76
- """Fallback: return None."""
77
- return None
78
-
79
- def _fallback_pool_id_to_chain_id(pool_id: str) -> int | None:
80
- """Fallback: return None."""
81
- return None
82
-
83
- def _fallback_vault_address_to_chain_id(vault_address: str) -> int | None:
84
- """Fallback: return None."""
85
- return None
86
-
87
- # Try to import from testnet module, fallback to defaults if not available
88
- try:
89
- # Import from cartha_cli.testnet (works both in development and when installed)
90
- from ..testnet.pool_ids import (
91
- format_pool_id,
92
- list_pools,
93
- pool_id_to_chain_id,
94
- pool_id_to_name,
95
- pool_id_to_vault_address,
96
- pool_name_to_id,
97
- vault_address_to_chain_id,
98
- vault_address_to_pool_id,
99
- )
100
- except (ImportError, ModuleNotFoundError):
101
- # Use fallback functions if import failed
102
- pool_name_to_id = _fallback_pool_name_to_id
103
- pool_id_to_name = _fallback_pool_id_to_name
104
- format_pool_id = _fallback_format_pool_id
105
- list_pools = _fallback_list_pools
106
- pool_id_to_vault_address = _fallback_pool_id_to_vault_address
107
- vault_address_to_pool_id = _fallback_vault_address_to_pool_id
108
- pool_id_to_chain_id = _fallback_pool_id_to_chain_id
109
- vault_address_to_chain_id = _fallback_vault_address_to_chain_id
45
+ # Import pool helpers from pool_client (fetches from verifier API)
46
+ from ..pool_client import (
47
+ format_pool_id,
48
+ list_pools,
49
+ pool_id_to_chain_id,
50
+ pool_id_to_name,
51
+ pool_id_to_vault_address,
52
+ pool_name_to_id,
53
+ vault_address_to_chain_id,
54
+ vault_address_to_pool_id,
55
+ )
110
56
 
111
57
 
112
58
  def prove_lock(
@@ -153,22 +99,6 @@ def prove_lock(
153
99
  netuid = 78
154
100
  elif network == "finney":
155
101
  netuid = 35
156
- # Warn that mainnet is not live yet
157
- console.print()
158
- console.print("[bold yellow]⚠️ MAINNET NOT AVAILABLE YET[/]")
159
- console.print()
160
- console.print("[yellow]Cartha subnet is currently in testnet phase (subnet 78 on test network).[/]")
161
- console.print("[yellow]Mainnet (subnet 35 on finney network) has not been announced yet.[/]")
162
- console.print()
163
- console.print("[bold cyan]To use testnet:[/]")
164
- console.print(" cartha vault lock --network test ...")
165
- console.print()
166
- console.print("[dim]If you continue with finney network, the CLI will attempt to connect[/]")
167
- console.print("[dim]but the subnet may not be operational yet.[/]")
168
- console.print()
169
- if not Confirm.ask("[yellow]Continue with finney network anyway?[/]", default=False):
170
- console.print("[yellow]Cancelled. Use --network test for testnet.[/]")
171
- raise typer.Exit(code=0)
172
102
  else:
173
103
  # Default to finney settings if unknown network
174
104
  netuid = 35
@@ -386,72 +316,51 @@ def prove_lock(
386
316
  if not pool_id_normalized.startswith("0x"):
387
317
  pool_id_normalized = "0x" + pool_id_normalized
388
318
 
389
- try:
390
- auto_chain_id = pool_id_to_chain_id(pool_id_normalized)
391
- except (NameError, AttributeError, TypeError):
392
- # Function not available - this shouldn't happen if imports worked
393
- # But handle gracefully by trying to import it
394
- try:
395
- from ..testnet.pool_ids import pool_id_to_chain_id
396
- auto_chain_id = pool_id_to_chain_id(pool_id_normalized)
397
- except (ImportError, ModuleNotFoundError, TypeError):
398
- pass
319
+ auto_chain_id = pool_id_to_chain_id(pool_id_normalized)
399
320
 
400
321
  if not auto_chain_id:
401
322
  # Fallback: try to get from vault address
402
- try:
403
- auto_chain_id = vault_address_to_chain_id(vault)
404
- except (NameError, AttributeError, TypeError):
405
- try:
406
- from ..testnet.pool_ids import vault_address_to_chain_id
407
- auto_chain_id = vault_address_to_chain_id(vault)
408
- except (ImportError, ModuleNotFoundError, TypeError):
409
- pass
323
+ auto_chain_id = vault_address_to_chain_id(vault)
410
324
 
411
325
  if auto_chain_id:
412
326
  chain = auto_chain_id
413
- chain_name = "Base Sepolia" if chain == 84532 else f"Chain {chain}"
327
+ if chain == 8453:
328
+ chain_name = "Base Mainnet"
329
+ elif chain == 84532:
330
+ chain_name = "Base Sepolia"
331
+ else:
332
+ chain_name = f"Chain {chain}"
414
333
  console.print(
415
334
  f"[bold green]✓ Auto-matched chain ID[/] - {chain_name} (chain ID: {chain})"
416
335
  )
417
336
  else:
418
- # Fallback: if on testnet and we have a vault, default to Base Sepolia (84532)
419
- if network == "test" and vault:
420
- chain = 84532
421
- console.print(
422
- f"[bold green]✓ Auto-matched chain ID[/] - Base Sepolia (chain ID: 84532) [dim](testnet default)[/]"
423
- )
424
- else:
425
- # Prompt for chain ID if no mapping found
426
- console.print(
427
- "[yellow]⚠ No chain ID mapping found. Please provide chain ID.[/]"
428
- )
429
- while True:
430
- try:
431
- chain_input = typer.prompt("Chain ID", show_default=False)
432
- chain = int(chain_input)
433
- if chain <= 0:
434
- console.print(
435
- "[bold red]Error:[/] Chain ID must be a positive integer"
436
- )
437
- continue
438
- break
439
- except ValueError:
440
- console.print("[bold red]Error:[/] Chain ID must be a valid integer")
337
+ # Prompt for chain ID if no mapping found
338
+ console.print(
339
+ "[yellow]⚠ No chain ID mapping found. Please provide chain ID.[/]"
340
+ )
341
+ while True:
342
+ try:
343
+ chain_input = typer.prompt("Chain ID", show_default=False)
344
+ chain = int(chain_input)
345
+ if chain <= 0:
346
+ console.print(
347
+ "[bold red]Error:[/] Chain ID must be a positive integer"
348
+ )
349
+ continue
350
+ break
351
+ except ValueError:
352
+ console.print("[bold red]Error:[/] Chain ID must be a valid integer")
441
353
  else:
442
354
  # Chain ID was provided, verify it matches vault if possible
443
- expected_chain_id = None
444
- try:
445
- expected_chain_id = vault_address_to_chain_id(vault)
446
- except (NameError, AttributeError):
447
- try:
448
- from ..testnet.pool_ids import vault_address_to_chain_id
449
- expected_chain_id = vault_address_to_chain_id(vault)
450
- except (ImportError, ModuleNotFoundError):
451
- pass
355
+ expected_chain_id = vault_address_to_chain_id(vault)
452
356
 
453
357
  if expected_chain_id and expected_chain_id != chain:
454
- chain_name = "Base Sepolia" if expected_chain_id == 84532 else f"Chain {expected_chain_id}"
358
+ if expected_chain_id == 8453:
359
+ chain_name = "Base Mainnet"
360
+ elif expected_chain_id == 84532:
361
+ chain_name = "Base Sepolia"
362
+ else:
363
+ chain_name = f"Chain {expected_chain_id}"
455
364
  console.print(
456
365
  f"[bold yellow]⚠ Warning:[/] Vault {vault} is on {chain_name} (chain ID: {expected_chain_id}), "
457
366
  f"but you specified chain ID {chain}"
@@ -674,8 +583,11 @@ def prove_lock(
674
583
  "\n[bold yellow]⚠️ Execute these transactions to complete your lock:[/]\n"
675
584
  )
676
585
 
677
- # USDC contract address for Base Sepolia
678
- usdc_contract_address = "0x2340D09c348930A76c8c2783EDa8610F699A51A8"
586
+ # USDC contract address based on chain ID
587
+ if chain == 8453: # Base Mainnet
588
+ usdc_contract_address = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
589
+ else: # Base Sepolia (default)
590
+ usdc_contract_address = "0x2340D09c348930A76c8c2783EDa8610F699A51A8"
679
591
 
680
592
  console.print("[bold cyan]━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[/]")
681
593
  console.print("[bold]Phase 1: Approve USDC[/]")
@@ -694,7 +606,7 @@ def prove_lock(
694
606
  phase1_params = {
695
607
  "phase": "1",
696
608
  "chainId": str(chain),
697
- "usdcAddress": "0x2340D09c348930A76c8c2783EDa8610F699A51A8",
609
+ "usdcAddress": usdc_contract_address,
698
610
  "vaultAddress": vault,
699
611
  "spender": vault,
700
612
  "amount": str(amount_base_units),
@@ -714,8 +626,11 @@ def prove_lock(
714
626
  console.print("[dim]The CLI will automatically detect when the approval is complete.[/]")
715
627
  console.print("[dim]You can also press Ctrl+C to skip and continue manually.[/]")
716
628
 
717
- # Base Sepolia RPC endpoint
718
- base_sepolia_rpc = "https://sepolia.base.org"
629
+ # RPC endpoint based on chain ID
630
+ if chain == 8453: # Base Mainnet
631
+ rpc_endpoint = "https://mainnet.base.org"
632
+ else: # Base Sepolia (default)
633
+ rpc_endpoint = "https://sepolia.base.org"
719
634
 
720
635
  # ERC20 ABI for allowance function and Approval event
721
636
  erc20_abi = [
@@ -746,7 +661,7 @@ def prove_lock(
746
661
 
747
662
  approval_detected = False
748
663
  try:
749
- w3 = Web3(Web3.HTTPProvider(base_sepolia_rpc))
664
+ w3 = Web3(Web3.HTTPProvider(rpc_endpoint))
750
665
  usdc_contract = w3.eth.contract(
751
666
  address=Web3.to_checksum_address(usdc_contract_address),
752
667
  abi=erc20_abi
@@ -941,13 +856,15 @@ def prove_lock(
941
856
  }
942
857
  ]
943
858
 
944
- # Get RPC endpoint for Base Sepolia
859
+ # Get RPC endpoint based on chain ID
945
860
  rpc_url = None
946
- if chain == 84532: # Base Sepolia
861
+ if chain == 8453: # Base Mainnet
862
+ rpc_url = "https://mainnet.base.org"
863
+ elif chain == 84532: # Base Sepolia
947
864
  rpc_url = "https://sepolia.base.org"
948
865
  else:
949
- # Only Base Sepolia is supported for auto-detection
950
- console.print(f"[yellow]Warning:[/] Auto-detection only supports Base Sepolia (chain ID 84532), but chain ID {chain} was specified.")
866
+ # Unsupported chain for auto-detection
867
+ console.print(f"[yellow]Warning:[/] Auto-detection only supports Base Mainnet (8453) and Base Sepolia (84532), but chain ID {chain} was specified.")
951
868
  console.print("[dim]You'll need to enter the transaction hash manually.[/]")
952
869
  rpc_url = None
953
870
 
@@ -79,22 +79,6 @@ def register(
79
79
  netuid = 78
80
80
  elif network == "finney":
81
81
  netuid = 35
82
- # Warn that mainnet is not live yet
83
- console.print()
84
- console.print("[bold yellow]⚠️ MAINNET NOT AVAILABLE YET[/]")
85
- console.print()
86
- console.print("[yellow]Cartha subnet is currently in testnet phase (subnet 78 on test network).[/]")
87
- console.print("[yellow]Mainnet (subnet 35 on finney network) has not been announced yet.[/]")
88
- console.print()
89
- console.print("[bold cyan]To use testnet:[/]")
90
- console.print(" cartha miner register --network test")
91
- console.print()
92
- console.print("[dim]If you continue with finney network, registration will attempt[/]")
93
- console.print("[dim]subnet 35 but the subnet may not be operational yet.[/]")
94
- console.print()
95
- if not Confirm.ask("[yellow]Continue with finney network anyway?[/]", default=False):
96
- console.print("[yellow]Cancelled. Use --network test for testnet.[/]")
97
- raise typer.Exit(code=0)
98
82
  # Note: netuid parameter is kept for backwards compatibility / explicit override
99
83
 
100
84
  from ..config import get_verifier_url_for_network
cartha_cli/config.py CHANGED
@@ -13,7 +13,7 @@ from pydantic_settings import BaseSettings
13
13
  # Network to verifier URL mapping
14
14
  NETWORK_VERIFIER_MAP = {
15
15
  "test": "https://cartha-verifier-826542474079.us-central1.run.app",
16
- "finney": None, # No mainnet verifier yet - use default or env var
16
+ "finney": "https://cartha-verifier-193291340038.us-central1.run.app",
17
17
  }
18
18
 
19
19
 
@@ -36,13 +36,13 @@ def get_verifier_url_for_network(network: str) -> str:
36
36
  if mapped_url:
37
37
  return mapped_url
38
38
 
39
- # Default fallback (testnet for now since no mainnet)
40
- return "https://cartha-verifier-826542474079.us-central1.run.app"
39
+ # Default fallback to mainnet
40
+ return "https://cartha-verifier-193291340038.us-central1.run.app"
41
41
 
42
42
 
43
43
  class Settings(BaseSettings):
44
44
  verifier_url: str = Field(
45
- "https://cartha-verifier-826542474079.us-central1.run.app", alias="CARTHA_VERIFIER_URL"
45
+ "https://cartha-verifier-193291340038.us-central1.run.app", alias="CARTHA_VERIFIER_URL"
46
46
  )
47
47
  network: str = Field("finney", alias="CARTHA_NETWORK")
48
48
  netuid: int = Field(35, alias="CARTHA_NETUID")
@@ -0,0 +1,214 @@
1
+ """Pool client - fetches pool data from verifier API with caching."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from functools import lru_cache
6
+ from typing import Any
7
+
8
+ from .verifier import VerifierError, fetch_pools
9
+
10
+
11
+ # Cache pool data for 5 minutes (300 seconds)
12
+ # Using a module-level cache that can be cleared if needed
13
+ _pools_cache: dict[str, Any] | None = None
14
+ _cache_timestamp: float = 0
15
+ _CACHE_TTL_SECONDS = 300
16
+
17
+
18
+ def _get_cached_pools() -> list[dict[str, Any]]:
19
+ """Get pools with caching (5 minute TTL)."""
20
+ global _pools_cache, _cache_timestamp
21
+ import time
22
+
23
+ now = time.time()
24
+ if _pools_cache is None or (now - _cache_timestamp) > _CACHE_TTL_SECONDS:
25
+ try:
26
+ _pools_cache = fetch_pools()
27
+ _cache_timestamp = now
28
+ except VerifierError:
29
+ # If fetch fails and we have cached data, use it
30
+ if _pools_cache is not None:
31
+ return _pools_cache
32
+ # Otherwise return empty list
33
+ return []
34
+
35
+ return _pools_cache or []
36
+
37
+
38
+ def clear_cache() -> None:
39
+ """Clear the pools cache."""
40
+ global _pools_cache, _cache_timestamp
41
+ _pools_cache = None
42
+ _cache_timestamp = 0
43
+
44
+
45
+ def list_pools() -> dict[str, str]:
46
+ """List all available pools from verifier.
47
+
48
+ Returns:
49
+ Dictionary mapping pool names (e.g., "BTCUSD") to hex pool IDs
50
+ """
51
+ pools = _get_cached_pools()
52
+ result = {}
53
+ for pool in pools:
54
+ name = pool.get("name", "")
55
+ # Verifier returns camelCase keys
56
+ pool_id = pool.get("poolId", "")
57
+ if name and pool_id:
58
+ # Normalize name: "BTC/USD" -> "BTCUSD"
59
+ normalized_name = name.replace("/", "").upper()
60
+ result[normalized_name] = pool_id.lower()
61
+ return result
62
+
63
+
64
+ def pool_name_to_id(pool_name: str) -> str:
65
+ """Convert a readable pool name to hex pool ID.
66
+
67
+ Args:
68
+ pool_name: Readable name (e.g., "BTCUSD", "BTC/USD")
69
+
70
+ Returns:
71
+ Hex pool ID (bytes32 format)
72
+ """
73
+ normalized = pool_name.replace("/", "").upper()
74
+ pools = list_pools()
75
+
76
+ if normalized in pools:
77
+ return pools[normalized]
78
+
79
+ # Fallback: encode the name as hex (for unknown pools)
80
+ name_bytes = pool_name.encode("utf-8")
81
+ if len(name_bytes) > 32:
82
+ raise ValueError(f"Pool name too long: {pool_name} (max 32 bytes)")
83
+ padded = name_bytes.rjust(32, b"\x00")
84
+ return "0x" + padded.hex()
85
+
86
+
87
+ def pool_id_to_name(pool_id: str) -> str | None:
88
+ """Convert a hex pool ID to readable name if available.
89
+
90
+ Args:
91
+ pool_id: Hex pool ID (bytes32 format)
92
+
93
+ Returns:
94
+ Readable name if found, None otherwise
95
+ """
96
+ pools = _get_cached_pools()
97
+ pool_id_lower = pool_id.lower()
98
+
99
+ for pool in pools:
100
+ # Verifier returns camelCase keys
101
+ if pool.get("poolId", "").lower() == pool_id_lower:
102
+ name = pool.get("name", "")
103
+ # Return normalized name without slash
104
+ return name.replace("/", "").upper() if name else None
105
+
106
+ return None
107
+
108
+
109
+ def format_pool_id(pool_id: str) -> str:
110
+ """Format a pool ID for display (shows readable name if available).
111
+
112
+ Args:
113
+ pool_id: Hex pool ID
114
+
115
+ Returns:
116
+ Formatted string: "BTCUSD (0x...)" or just "0x..." if no name found
117
+ """
118
+ name = pool_id_to_name(pool_id)
119
+ if name:
120
+ return f"{name} ({pool_id})"
121
+ return pool_id
122
+
123
+
124
+ def pool_id_to_vault_address(pool_id: str) -> str | None:
125
+ """Get vault address for a given pool ID.
126
+
127
+ Args:
128
+ pool_id: Pool ID in hex format (bytes32)
129
+
130
+ Returns:
131
+ Vault address if found, None otherwise
132
+ """
133
+ pools = _get_cached_pools()
134
+ pool_id_lower = pool_id.lower()
135
+
136
+ for pool in pools:
137
+ # Verifier returns camelCase keys
138
+ if pool.get("poolId", "").lower() == pool_id_lower:
139
+ return pool.get("vaultAddress")
140
+
141
+ return None
142
+
143
+
144
+ def vault_address_to_pool_id(vault_address: str) -> str | None:
145
+ """Get pool ID for a given vault address.
146
+
147
+ Args:
148
+ vault_address: Vault contract address
149
+
150
+ Returns:
151
+ Pool ID if found, None otherwise
152
+ """
153
+ pools = _get_cached_pools()
154
+ vault_lower = vault_address.lower()
155
+
156
+ for pool in pools:
157
+ # Verifier returns camelCase keys
158
+ if pool.get("vaultAddress", "").lower() == vault_lower:
159
+ return pool.get("poolId", "").lower()
160
+
161
+ return None
162
+
163
+
164
+ def pool_id_to_chain_id(pool_id: str) -> int | None:
165
+ """Get chain ID for a given pool ID.
166
+
167
+ Args:
168
+ pool_id: Pool ID in hex format (bytes32)
169
+
170
+ Returns:
171
+ Chain ID if found, None otherwise
172
+ """
173
+ pools = _get_cached_pools()
174
+ pool_id_lower = pool_id.lower()
175
+
176
+ for pool in pools:
177
+ # Verifier returns camelCase keys
178
+ if pool.get("poolId", "").lower() == pool_id_lower:
179
+ return pool.get("chainId")
180
+
181
+ return None
182
+
183
+
184
+ def vault_address_to_chain_id(vault_address: str) -> int | None:
185
+ """Get chain ID for a given vault address.
186
+
187
+ Args:
188
+ vault_address: Vault contract address
189
+
190
+ Returns:
191
+ Chain ID if found, None otherwise
192
+ """
193
+ pools = _get_cached_pools()
194
+ vault_lower = vault_address.lower()
195
+
196
+ for pool in pools:
197
+ # Verifier returns camelCase keys
198
+ if pool.get("vaultAddress", "").lower() == vault_lower:
199
+ return pool.get("chainId")
200
+
201
+ return None
202
+
203
+
204
+ __all__ = [
205
+ "clear_cache",
206
+ "list_pools",
207
+ "pool_name_to_id",
208
+ "pool_id_to_name",
209
+ "format_pool_id",
210
+ "pool_id_to_vault_address",
211
+ "vault_address_to_pool_id",
212
+ "pool_id_to_chain_id",
213
+ "vault_address_to_chain_id",
214
+ ]
cartha_cli/verifier.py CHANGED
@@ -324,6 +324,20 @@ def process_lock_transaction(
324
324
  )
325
325
 
326
326
 
327
+ def fetch_pools() -> list[dict[str, Any]]:
328
+ """Fetch available pools from verifier.
329
+
330
+ Returns list of pools with:
331
+ - name: Human-readable pool name (e.g., "BTC/USD")
332
+ - pool_id: Hex pool ID (bytes32)
333
+ - vault_address: Vault contract address
334
+ - chain_id: Chain ID
335
+ - network: Network name ("mainnet" or "testnet")
336
+ """
337
+ data = _request("GET", "/pools")
338
+ return data.get("pools", [])
339
+
340
+
327
341
  # REMOVED: Old endpoints - replaced by new lock flow
328
342
  # fetch_pair_password, register_pair_password, submit_lock_proof removed
329
343
 
@@ -339,4 +353,5 @@ __all__ = [
339
353
  "request_lock_signature",
340
354
  "get_lock_status",
341
355
  "process_lock_transaction",
356
+ "fetch_pools",
342
357
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cartha-cli
3
- Version: 1.0.5
3
+ Version: 1.0.8
4
4
  Summary: CLI utilities for Cartha subnet miners.
5
5
  Project-URL: Homepage, https://cartha.finance
6
6
  Project-URL: Repository, https://github.com/General-Tao-Ventures/cartha-cli
@@ -43,7 +43,7 @@ Cartha CLI makes mining on the Cartha subnet effortless. As the Liquidity Provid
43
43
  - **📊 Instant Status Updates** - See all your pools, balances, and expiration dates at a glance
44
44
  - **⏰ Smart Expiration Warnings** - Never miss a renewal with color-coded countdowns
45
45
  - **💼 Multi-Pool Management** - Track multiple trading pairs in one place
46
- - **🔑 Secure by Default** - Your password stays hidden until you actually need it
46
+ - **🔒 Secure Authentication** - Session-based authentication with your Bittensor hotkey
47
47
 
48
48
  ## Installation
49
49
 
@@ -64,17 +64,19 @@ cartha miner register --help
64
64
  cartha miner status --help
65
65
 
66
66
  # Check CLI health and connectivity
67
- cartha health
67
+ cartha utils health
68
68
 
69
69
  # Or use short aliases
70
70
  cartha m status
71
71
  cartha v lock
72
+ cartha u health
72
73
  ```
73
74
 
74
75
  ## Requirements
75
76
 
76
77
  - Python 3.11
77
- - Bittensor wallet
78
+ - Bittensor wallet within btcli
79
+ - learn how to create/import one here https://docs.learnbittensor.org/keys/working-with-keys
78
80
 
79
81
  ## What You Can Do
80
82
 
@@ -90,14 +92,12 @@ cartha miner register --wallet-name your-wallet --wallet-hotkey your-hotkey
90
92
  cartha miner status --wallet-name your-wallet --wallet-hotkey your-hotkey
91
93
  # Or use the short alias: cartha m status
92
94
  ```
93
-
94
- ### Track Your Pools
95
-
96
- See all your active trading pairs, balances, and when they expire—all in one command. The CLI shows you:
97
- - Which pools are active and earning rewards
98
- - How much you have locked in each pool
99
- - Days remaining before expiration (with helpful warnings)
100
- - Which pools are included in the next reward epoch
95
+ > **Track Your Miner Status**
96
+ > See all your active trading pairs, balances, and when they expire—all in one command. The CLI shows you:
97
+ > - Which pools are active and earning rewards
98
+ > - How much you have locked in each pool
99
+ > - Days remaining before expiration (with helpful warnings)
100
+ > - Which pools are included in the next reward epoch
101
101
 
102
102
  ### View Available Pools
103
103
 
@@ -110,14 +110,14 @@ cartha vault pools
110
110
 
111
111
  This shows you which pools are available, their full pool IDs, vault contract addresses, and chain IDs.
112
112
 
113
- ### Lock Your Funds
113
+ ### Lock Your Funds to start Mining
114
114
 
115
115
  Create a new lock position with the streamlined lock flow:
116
116
  ```bash
117
117
  cartha vault lock \
118
118
  --coldkey your-wallet \
119
119
  --hotkey your-hotkey \
120
- --pool-id "BTCUSD" \
120
+ --pool-id BTCUSD \
121
121
  --amount 1000.0 \
122
122
  --lock-days 30 \
123
123
  --owner-evm 0xYourEVMAddress \
@@ -136,36 +136,31 @@ The CLI will:
136
136
  1. Check your registration on the specified network (subnet 35 for finney, subnet 78 for test)
137
137
  2. Authenticate with your Bittensor hotkey
138
138
  3. Request a signed LockRequest from the verifier
139
- 4. Automatically open the Cartha Lock UI in your browser with all parameters pre-filled
139
+ 4. Automatically open the Cartha Lock UI in your browser with all parameters pre-filled (you can also paste the url into your browser manually)
140
140
  5. Guide you through Phase 1 (Approve USDC) and Phase 2 (Lock Position) via the web interface
141
141
  6. Automatically detect when approval completes and proceed to Phase 2
142
142
  7. The verifier automatically detects your lock and adds you to the upcoming epoch
143
143
 
144
144
  **Managing Positions**: Visit https://cartha.finance/manage to view all your positions, extend locks, or top up existing positions.
145
145
 
146
- ### View Your Password
147
-
148
- When you need your password (like for signing transactions):
149
- ```bash
150
- cartha miner password --wallet-name your-wallet --wallet-hotkey your-hotkey
151
- ```
152
-
153
- **Tip:** Use `miner status` for daily checks—it's faster and doesn't require signing. Only use `miner password` when you actually need it.
154
-
155
146
  ### Check Your Setup
156
147
 
157
148
  Verify your CLI is configured correctly and can reach all services:
158
149
 
159
150
  ```bash
160
- cartha health
151
+ cartha utils health
152
+ # Or use the short alias
153
+ cartha u health
161
154
  ```
162
155
 
163
156
  This checks:
164
157
  - Verifier connectivity and latency
165
158
  - Bittensor network connectivity
166
159
  - Configuration validation
160
+ - Subnet metadata
161
+ - Environment variables
167
162
 
168
- Use `cartha health --verbose` for detailed troubleshooting information.
163
+ Use `cartha utils health --verbose` (or `cartha u health --verbose`) for detailed troubleshooting information.
169
164
 
170
165
  ## Need Help?
171
166
 
@@ -179,4 +174,4 @@ We welcome contributions! Please see our [Feedback & Support](docs/FEEDBACK.md)
179
174
 
180
175
  ---
181
176
 
182
- **Made with ❤ by GTV**
177
+ **Made with ❤ by General Tensor**
@@ -1,31 +1,32 @@
1
1
  cartha_cli/__init__.py,sha256=cSKsPAfHW8_hqJkGMXUh4mFNz9HXsq-UcgRl8G_2KhM,720
2
- cartha_cli/bt.py,sha256=GGW8QvOgFPFNrIghu7JNygRmTgBeMt2vhEh26ZiPe4Q,6933
3
- cartha_cli/config.py,sha256=MSHNiRow1tzHUJeMOvQRQsTslntV6DecLTQ-Y_CmB4A,2294
2
+ cartha_cli/bt.py,sha256=UC5n0LpLD2YNOL-xsawrzohXpuHaoClraQh3fu4qI90,7467
3
+ cartha_cli/config.py,sha256=eIrLNzkG6NE7zr2duDAxEuAdTgpJsDz1oymL5RkNwJc,2272
4
4
  cartha_cli/display.py,sha256=Krim69DLgiCHSYDuWNjnOep25IAHUebRAceePHfsiRA,2040
5
5
  cartha_cli/eth712.py,sha256=5NU0MnvOk89mxWnkDHzoOaSHN8TJGRAHVLGXmCq8jhM,241
6
6
  cartha_cli/main.py,sha256=0-G2syhsj2okLblX5WYb5NGqWjOwF5eW2tDn9AF5vaw,6756
7
7
  cartha_cli/pair.py,sha256=Y-TAjAK5FeWqKlUK52dHZLdBhDxx1CJbea8mlsQXkqc,6245
8
+ cartha_cli/pool_client.py,sha256=1mUpzeZX5pzOGW4cV4Y9o9Dtkjw1GgytEHoT3vNo4mE,5717
8
9
  cartha_cli/utils.py,sha256=LWlJXzWNkIpInWclCJ2PObkG--JEN1mIcvVXsHmFllE,8429
9
- cartha_cli/verifier.py,sha256=JFtDA9bhecsAUCQEp0SBrZ1Z-48EkDT1Q6y7X4eTK60,10548
10
+ cartha_cli/verifier.py,sha256=sKIjJBwz-Rir-hQNwM8CVgE9fpBu8TnGKQKJ-7Ub4_c,10985
10
11
  cartha_cli/wallet.py,sha256=Jha1pONa4Hy2XsHMTrk60eBqdkwJyzsQYgPuI-cxxFo,1770
11
12
  cartha_cli/commands/__init__.py,sha256=8CYMVEWJmg2qjLyE3ZeheQtS-E9doltDSfyyumOsET4,345
12
13
  cartha_cli/commands/common.py,sha256=tpxKsdzjFtcb0ae7J-J-zxnh32qVXZd8jwjP-frFoio,2099
13
- cartha_cli/commands/config.py,sha256=XT1LQo7b9vVm_mgwUTJRLCBCHJhtGclBzh_CTBAd280,10539
14
+ cartha_cli/commands/config.py,sha256=1G6q6PU7qj6AA71pH9nUygoU6yLVgU8tbreLPcgd6rU,10539
14
15
  cartha_cli/commands/health.py,sha256=NRwmIultxUzAe7udOOBIdkcdGG5KsE_kuCs43LZObGk,20717
15
16
  cartha_cli/commands/help.py,sha256=6ubfWtmjXfCtp6L_PYvn7rR7m5C_pp-iEjtRc6BS0GA,1721
16
- cartha_cli/commands/miner_password.py,sha256=7cbcyrJ9KzCyJ68_174U_CXjBUt9BaYhgKAycRpv7AE,11078
17
- cartha_cli/commands/miner_status.py,sha256=tWlCWcuwm9NEd4USuCLp_6qObikX2odc2e7m6Y_vNrU,21873
18
- cartha_cli/commands/pair_status.py,sha256=LoU-fA1MXuWZGHNmeKPMjwvNw30Yn094ZD1EC0-WXVc,19978
19
- cartha_cli/commands/pools.py,sha256=P02SEp23a7OdrgNj6AaiJTnQ9K_QrI300DzucA6HH8A,3884
20
- cartha_cli/commands/prove_lock.py,sha256=FkurHtL2i2891ACEV1TejTAgkutIV1grykatx0W-JCI,61168
21
- cartha_cli/commands/register.py,sha256=sxbYO0V4NucOKLZpaFoVnhFDHLSLDHREoMtN9DjyLsM,10227
17
+ cartha_cli/commands/miner_password.py,sha256=7IZcufDKiBTmnW2pPshQBCEh69nKR-FBWfWXteA0mso,10635
18
+ cartha_cli/commands/miner_status.py,sha256=lw4e8BVhJCA8fPPO7Fr6ZuN46hgkjHGPISFJAs7ULe8,20843
19
+ cartha_cli/commands/pair_status.py,sha256=4NqyO30HAawkzSoCM5SU7KFMCPel-YFP66FMDkKB_es,18905
20
+ cartha_cli/commands/pools.py,sha256=GzYqpJvpTiY7cgTZCZwlzwxPpycV7JZkGwZ1A5n6lno,3225
21
+ cartha_cli/commands/prove_lock.py,sha256=xKQN_ZujZQ5-_6czQpG51CZtSjzfiOmCTmvVSzYBIbI,57104
22
+ cartha_cli/commands/register.py,sha256=3sdQjsLTtwsbF8ILMROTAMdrAneaesM-cBu_P_uEC-w,9262
22
23
  cartha_cli/commands/shared_options.py,sha256=itHzJSgxuKQxUVOh1_jVTcMQXjI3PPzexQyhqIbabxc,5874
23
24
  cartha_cli/commands/version.py,sha256=u5oeccQzK0LLcCbgZm0U8-Vslk5vB_lVvW3xT5HPeTg,456
24
25
  cartha_cli/testnet/README.md,sha256=kWKaLtq6t_46W-mvXkSaLi2fjXDELLk5ntVGkogiUY0,14511
25
26
  cartha_cli/testnet/__init__.py,sha256=xreJMXs-ZKTkPtUQBR5xdY7ImOyUiF7WKG6bv9J9aBM,41
26
27
  cartha_cli/testnet/pool_ids.py,sha256=0jvQ6tvc6sL0aGKkl31KXM6ngVpUboYiABY5SDMaRCQ,6747
27
- cartha_cli-1.0.5.dist-info/METADATA,sha256=CpmQxsTilpHMwpDu5xlNnWyU0baoAJkGWAnFOO05eEE,5794
28
- cartha_cli-1.0.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
29
- cartha_cli-1.0.5.dist-info/entry_points.txt,sha256=sTYVMgb9l0fuJibUtWpGnIoDmgHinne97G4Y_cCwC-U,43
30
- cartha_cli-1.0.5.dist-info/licenses/LICENSE,sha256=B4UCiDn13m4xYwIl4TMKfbuKw7kh9pg4c81rJecxHSo,1076
31
- cartha_cli-1.0.5.dist-info/RECORD,,
28
+ cartha_cli-1.0.8.dist-info/METADATA,sha256=rtrIH0UTa9mvW2_gq9DERWEr2F3YRnB4mzb087jHxas,5842
29
+ cartha_cli-1.0.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
30
+ cartha_cli-1.0.8.dist-info/entry_points.txt,sha256=sTYVMgb9l0fuJibUtWpGnIoDmgHinne97G4Y_cCwC-U,43
31
+ cartha_cli-1.0.8.dist-info/licenses/LICENSE,sha256=B4UCiDn13m4xYwIl4TMKfbuKw7kh9pg4c81rJecxHSo,1076
32
+ cartha_cli-1.0.8.dist-info/RECORD,,