cartha-cli 1.0.4__tar.gz → 1.0.7__tar.gz

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.
Files changed (43) hide show
  1. cartha_cli-1.0.7/.github/workflows/publish.yml +85 -0
  2. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/PKG-INFO +22 -27
  3. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/README.md +21 -26
  4. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/bt.py +82 -74
  5. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/prove_lock.py +34 -22
  6. cartha_cli-1.0.7/docs/COMMANDS.md +843 -0
  7. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/pyproject.toml +1 -1
  8. cartha_cli-1.0.4/docs/COMMANDS.md +0 -910
  9. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/.github/workflows/README.md +0 -0
  10. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/.github/workflows/ci.yml +0 -0
  11. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/.gitignore +0 -0
  12. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/.ruff.toml +0 -0
  13. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/CONTRIBUTING.md +0 -0
  14. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/LICENSE +0 -0
  15. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/Makefile +0 -0
  16. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/__init__.py +0 -0
  17. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/__init__.py +0 -0
  18. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/common.py +0 -0
  19. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/config.py +0 -0
  20. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/health.py +0 -0
  21. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/help.py +0 -0
  22. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/miner_password.py +0 -0
  23. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/miner_status.py +0 -0
  24. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/pair_status.py +0 -0
  25. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/pools.py +0 -0
  26. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/register.py +0 -0
  27. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/shared_options.py +0 -0
  28. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/commands/version.py +0 -0
  29. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/config.py +0 -0
  30. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/display.py +0 -0
  31. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/eth712.py +0 -0
  32. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/main.py +0 -0
  33. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/pair.py +0 -0
  34. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/testnet/README.md +0 -0
  35. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/testnet/__init__.py +0 -0
  36. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/testnet/pool_ids.py +0 -0
  37. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/utils.py +0 -0
  38. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/verifier.py +0 -0
  39. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/cartha_cli/wallet.py +0 -0
  40. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/docs/FEEDBACK.md +0 -0
  41. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/tests/conftest.py +0 -0
  42. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/tests/test_cli.py +0 -0
  43. {cartha_cli-1.0.4 → cartha_cli-1.0.7}/uv.lock +0 -0
@@ -0,0 +1,85 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch: # Allow manual triggers
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ name: Build distribution
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+ with:
23
+ version: "latest"
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.11"
29
+
30
+ - name: Build package
31
+ run: uv build
32
+
33
+ - name: Store the distribution packages
34
+ uses: actions/upload-artifact@v4
35
+ with:
36
+ name: python-package-distributions
37
+ path: dist/
38
+
39
+ publish-to-pypi:
40
+ name: Publish to PyPI
41
+ needs: [build]
42
+ runs-on: ubuntu-latest
43
+
44
+ environment:
45
+ name: release
46
+ url: https://pypi.org/p/cartha-cli
47
+
48
+ permissions:
49
+ id-token: write # IMPORTANT: mandatory for trusted publishing
50
+
51
+ steps:
52
+ - name: Download all the dists
53
+ uses: actions/download-artifact@v4
54
+ with:
55
+ name: python-package-distributions
56
+ path: dist/
57
+
58
+ - name: Publish to PyPI
59
+ uses: pypa/gh-action-pypi-publish@release/v1
60
+
61
+ publish-to-testpypi:
62
+ name: Publish to TestPyPI
63
+ needs: [build]
64
+ runs-on: ubuntu-latest
65
+ if: github.event_name == 'workflow_dispatch' # Only for manual runs
66
+
67
+ environment:
68
+ name: test-release
69
+ url: https://test.pypi.org/p/cartha-cli
70
+
71
+ permissions:
72
+ id-token: write
73
+
74
+ steps:
75
+ - name: Download all the dists
76
+ uses: actions/download-artifact@v4
77
+ with:
78
+ name: python-package-distributions
79
+ path: dist/
80
+
81
+ - name: Publish to TestPyPI
82
+ uses: pypa/gh-action-pypi-publish@release/v1
83
+ with:
84
+ repository-url: https://test.pypi.org/legacy/
85
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cartha-cli
3
- Version: 1.0.4
3
+ Version: 1.0.7
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**
@@ -10,7 +10,7 @@ Cartha CLI makes mining on the Cartha subnet effortless. As the Liquidity Provid
10
10
  - **📊 Instant Status Updates** - See all your pools, balances, and expiration dates at a glance
11
11
  - **⏰ Smart Expiration Warnings** - Never miss a renewal with color-coded countdowns
12
12
  - **💼 Multi-Pool Management** - Track multiple trading pairs in one place
13
- - **🔑 Secure by Default** - Your password stays hidden until you actually need it
13
+ - **🔒 Secure Authentication** - Session-based authentication with your Bittensor hotkey
14
14
 
15
15
  ## Installation
16
16
 
@@ -31,17 +31,19 @@ cartha miner register --help
31
31
  cartha miner status --help
32
32
 
33
33
  # Check CLI health and connectivity
34
- cartha health
34
+ cartha utils health
35
35
 
36
36
  # Or use short aliases
37
37
  cartha m status
38
38
  cartha v lock
39
+ cartha u health
39
40
  ```
40
41
 
41
42
  ## Requirements
42
43
 
43
44
  - Python 3.11
44
- - Bittensor wallet
45
+ - Bittensor wallet within btcli
46
+ - learn how to create/import one here https://docs.learnbittensor.org/keys/working-with-keys
45
47
 
46
48
  ## What You Can Do
47
49
 
@@ -57,14 +59,12 @@ cartha miner register --wallet-name your-wallet --wallet-hotkey your-hotkey
57
59
  cartha miner status --wallet-name your-wallet --wallet-hotkey your-hotkey
58
60
  # Or use the short alias: cartha m status
59
61
  ```
60
-
61
- ### Track Your Pools
62
-
63
- See all your active trading pairs, balances, and when they expire—all in one command. The CLI shows you:
64
- - Which pools are active and earning rewards
65
- - How much you have locked in each pool
66
- - Days remaining before expiration (with helpful warnings)
67
- - Which pools are included in the next reward epoch
62
+ > **Track Your Miner Status**
63
+ > See all your active trading pairs, balances, and when they expire—all in one command. The CLI shows you:
64
+ > - Which pools are active and earning rewards
65
+ > - How much you have locked in each pool
66
+ > - Days remaining before expiration (with helpful warnings)
67
+ > - Which pools are included in the next reward epoch
68
68
 
69
69
  ### View Available Pools
70
70
 
@@ -77,14 +77,14 @@ cartha vault pools
77
77
 
78
78
  This shows you which pools are available, their full pool IDs, vault contract addresses, and chain IDs.
79
79
 
80
- ### Lock Your Funds
80
+ ### Lock Your Funds to start Mining
81
81
 
82
82
  Create a new lock position with the streamlined lock flow:
83
83
  ```bash
84
84
  cartha vault lock \
85
85
  --coldkey your-wallet \
86
86
  --hotkey your-hotkey \
87
- --pool-id "BTCUSD" \
87
+ --pool-id BTCUSD \
88
88
  --amount 1000.0 \
89
89
  --lock-days 30 \
90
90
  --owner-evm 0xYourEVMAddress \
@@ -103,36 +103,31 @@ The CLI will:
103
103
  1. Check your registration on the specified network (subnet 35 for finney, subnet 78 for test)
104
104
  2. Authenticate with your Bittensor hotkey
105
105
  3. Request a signed LockRequest from the verifier
106
- 4. Automatically open the Cartha Lock UI in your browser with all parameters pre-filled
106
+ 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)
107
107
  5. Guide you through Phase 1 (Approve USDC) and Phase 2 (Lock Position) via the web interface
108
108
  6. Automatically detect when approval completes and proceed to Phase 2
109
109
  7. The verifier automatically detects your lock and adds you to the upcoming epoch
110
110
 
111
111
  **Managing Positions**: Visit https://cartha.finance/manage to view all your positions, extend locks, or top up existing positions.
112
112
 
113
- ### View Your Password
114
-
115
- When you need your password (like for signing transactions):
116
- ```bash
117
- cartha miner password --wallet-name your-wallet --wallet-hotkey your-hotkey
118
- ```
119
-
120
- **Tip:** Use `miner status` for daily checks—it's faster and doesn't require signing. Only use `miner password` when you actually need it.
121
-
122
113
  ### Check Your Setup
123
114
 
124
115
  Verify your CLI is configured correctly and can reach all services:
125
116
 
126
117
  ```bash
127
- cartha health
118
+ cartha utils health
119
+ # Or use the short alias
120
+ cartha u health
128
121
  ```
129
122
 
130
123
  This checks:
131
124
  - Verifier connectivity and latency
132
125
  - Bittensor network connectivity
133
126
  - Configuration validation
127
+ - Subnet metadata
128
+ - Environment variables
134
129
 
135
- Use `cartha health --verbose` for detailed troubleshooting information.
130
+ Use `cartha utils health --verbose` (or `cartha u health --verbose`) for detailed troubleshooting information.
136
131
 
137
132
  ## Need Help?
138
133
 
@@ -146,4 +141,4 @@ We welcome contributions! Please see our [Feedback & Support](docs/FEEDBACK.md)
146
141
 
147
142
  ---
148
143
 
149
- **Made with ❤ by GTV**
144
+ **Made with ❤ by General Tensor**
@@ -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:
@@ -381,26 +381,31 @@ def prove_lock(
381
381
  if chain is None:
382
382
  # Try to get chain ID from pool ID first
383
383
  auto_chain_id = None
384
+ # Ensure pool_id is properly formatted (lowercase, with 0x prefix)
385
+ pool_id_normalized = pool_id.lower().strip()
386
+ if not pool_id_normalized.startswith("0x"):
387
+ pool_id_normalized = "0x" + pool_id_normalized
388
+
384
389
  try:
385
- auto_chain_id = pool_id_to_chain_id(pool_id)
386
- except (NameError, AttributeError):
390
+ auto_chain_id = pool_id_to_chain_id(pool_id_normalized)
391
+ except (NameError, AttributeError, TypeError):
387
392
  # Function not available - this shouldn't happen if imports worked
388
393
  # But handle gracefully by trying to import it
389
394
  try:
390
395
  from ..testnet.pool_ids import pool_id_to_chain_id
391
- auto_chain_id = pool_id_to_chain_id(pool_id)
392
- except (ImportError, ModuleNotFoundError):
396
+ auto_chain_id = pool_id_to_chain_id(pool_id_normalized)
397
+ except (ImportError, ModuleNotFoundError, TypeError):
393
398
  pass
394
399
 
395
400
  if not auto_chain_id:
396
401
  # Fallback: try to get from vault address
397
402
  try:
398
403
  auto_chain_id = vault_address_to_chain_id(vault)
399
- except (NameError, AttributeError):
404
+ except (NameError, AttributeError, TypeError):
400
405
  try:
401
406
  from ..testnet.pool_ids import vault_address_to_chain_id
402
407
  auto_chain_id = vault_address_to_chain_id(vault)
403
- except (ImportError, ModuleNotFoundError):
408
+ except (ImportError, ModuleNotFoundError, TypeError):
404
409
  pass
405
410
 
406
411
  if auto_chain_id:
@@ -410,22 +415,29 @@ def prove_lock(
410
415
  f"[bold green]✓ Auto-matched chain ID[/] - {chain_name} (chain ID: {chain})"
411
416
  )
412
417
  else:
413
- # Fallback: prompt for chain ID if no mapping found
414
- console.print(
415
- "[yellow]⚠ No chain ID mapping found. Please provide chain ID.[/]"
416
- )
417
- while True:
418
- try:
419
- chain_input = typer.prompt("Chain ID", show_default=False)
420
- chain = int(chain_input)
421
- if chain <= 0:
422
- console.print(
423
- "[bold red]Error:[/] Chain ID must be a positive integer"
424
- )
425
- continue
426
- break
427
- except ValueError:
428
- console.print("[bold red]Error:[/] Chain ID must be a valid integer")
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")
429
441
  else:
430
442
  # Chain ID was provided, verify it matches vault if possible
431
443
  expected_chain_id = None