htcli 1.1.0__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.
- htcli-1.1.0.dist-info/METADATA +509 -0
- htcli-1.1.0.dist-info/RECORD +140 -0
- htcli-1.1.0.dist-info/WHEEL +4 -0
- htcli-1.1.0.dist-info/entry_points.txt +2 -0
- htcli-1.1.0.dist-info/licenses/LICENSE +21 -0
- src/__init__.py +0 -0
- src/htcli/__init__.py +5 -0
- src/htcli/client/__init__.py +338 -0
- src/htcli/client/extrinsics/__init__.py +26 -0
- src/htcli/client/extrinsics/base.py +487 -0
- src/htcli/client/extrinsics/consensus.py +79 -0
- src/htcli/client/extrinsics/governance.py +714 -0
- src/htcli/client/extrinsics/identity.py +490 -0
- src/htcli/client/extrinsics/node.py +1054 -0
- src/htcli/client/extrinsics/overwatch.py +401 -0
- src/htcli/client/extrinsics/staking.py +1504 -0
- src/htcli/client/extrinsics/subnet.py +2218 -0
- src/htcli/client/extrinsics/validator.py +203 -0
- src/htcli/client/extrinsics/wallet.py +323 -0
- src/htcli/client/offchain/__init__.py +10 -0
- src/htcli/client/offchain/backup.py +385 -0
- src/htcli/client/offchain/config.py +541 -0
- src/htcli/client/offchain/wallet.py +839 -0
- src/htcli/client/rpc/__init__.py +20 -0
- src/htcli/client/rpc/chain.py +568 -0
- src/htcli/client/rpc/node.py +783 -0
- src/htcli/client/rpc/overwatch.py +680 -0
- src/htcli/client/rpc/staking.py +216 -0
- src/htcli/client/rpc/subnet.py +2104 -0
- src/htcli/client/rpc/wallet.py +912 -0
- src/htcli/commands/__init__.py +31 -0
- src/htcli/commands/chain/__init__.py +66 -0
- src/htcli/commands/chain/display.py +204 -0
- src/htcli/commands/chain/handlers.py +260 -0
- src/htcli/commands/config/__init__.py +158 -0
- src/htcli/commands/config/display.py +353 -0
- src/htcli/commands/config/handlers.py +347 -0
- src/htcli/commands/config/prompts.py +357 -0
- src/htcli/commands/consensus/__init__.py +61 -0
- src/htcli/commands/consensus/handlers.py +100 -0
- src/htcli/commands/governance/__init__.py +49 -0
- src/htcli/commands/governance/handlers.py +81 -0
- src/htcli/commands/node/__init__.py +304 -0
- src/htcli/commands/node/display.py +749 -0
- src/htcli/commands/node/error_handling.py +470 -0
- src/htcli/commands/node/handlers.py +844 -0
- src/htcli/commands/node/prompts.py +346 -0
- src/htcli/commands/overwatch/__init__.py +219 -0
- src/htcli/commands/overwatch/display.py +396 -0
- src/htcli/commands/overwatch/error_handling.py +276 -0
- src/htcli/commands/overwatch/handlers.py +443 -0
- src/htcli/commands/overwatch/prompts.py +359 -0
- src/htcli/commands/stake/__init__.py +736 -0
- src/htcli/commands/stake/display.py +1103 -0
- src/htcli/commands/stake/error_handling.py +425 -0
- src/htcli/commands/stake/handlers.py +1902 -0
- src/htcli/commands/stake/prompts.py +1080 -0
- src/htcli/commands/subnet/__init__.py +639 -0
- src/htcli/commands/subnet/display.py +801 -0
- src/htcli/commands/subnet/error_handling.py +524 -0
- src/htcli/commands/subnet/handlers.py +2855 -0
- src/htcli/commands/subnet/prompts.py +1225 -0
- src/htcli/commands/validator/__init__.py +192 -0
- src/htcli/commands/validator/display.py +54 -0
- src/htcli/commands/validator/handlers.py +340 -0
- src/htcli/commands/wallet/__init__.py +546 -0
- src/htcli/commands/wallet/display.py +806 -0
- src/htcli/commands/wallet/error_handling.py +210 -0
- src/htcli/commands/wallet/handlers.py +3040 -0
- src/htcli/commands/wallet/prompts.py +1518 -0
- src/htcli/config.py +184 -0
- src/htcli/dependencies.py +186 -0
- src/htcli/errors/__init__.py +63 -0
- src/htcli/errors/base.py +141 -0
- src/htcli/errors/display.py +20 -0
- src/htcli/errors/handlers.py +710 -0
- src/htcli/main.py +343 -0
- src/htcli/models/__init__.py +21 -0
- src/htcli/models/enums/enum_types.py +35 -0
- src/htcli/models/errors.py +103 -0
- src/htcli/models/requests/__init__.py +197 -0
- src/htcli/models/requests/config.py +70 -0
- src/htcli/models/requests/consensus.py +19 -0
- src/htcli/models/requests/governance.py +38 -0
- src/htcli/models/requests/identity.py +51 -0
- src/htcli/models/requests/key.py +22 -0
- src/htcli/models/requests/node.py +91 -0
- src/htcli/models/requests/overwatch.py +64 -0
- src/htcli/models/requests/staking.py +580 -0
- src/htcli/models/requests/subnet.py +195 -0
- src/htcli/models/requests/validator.py +139 -0
- src/htcli/models/requests/wallet.py +118 -0
- src/htcli/models/responses/__init__.py +147 -0
- src/htcli/models/responses/base.py +18 -0
- src/htcli/models/responses/chain.py +39 -0
- src/htcli/models/responses/config.py +58 -0
- src/htcli/models/responses/identity.py +102 -0
- src/htcli/models/responses/overwatch.py +51 -0
- src/htcli/models/responses/staking.py +502 -0
- src/htcli/models/responses/subnet.py +856 -0
- src/htcli/models/responses/wallet.py +185 -0
- src/htcli/ui/__init__.py +87 -0
- src/htcli/ui/colors.py +309 -0
- src/htcli/ui/components/__init__.py +60 -0
- src/htcli/ui/components/panels.py +174 -0
- src/htcli/ui/components/progress.py +166 -0
- src/htcli/ui/components/spinners.py +92 -0
- src/htcli/ui/components/tables.py +809 -0
- src/htcli/ui/components/trees.py +721 -0
- src/htcli/ui/display.py +336 -0
- src/htcli/ui/prompts.py +870 -0
- src/htcli/utils/__init__.py +76 -0
- src/htcli/utils/blockchain/__init__.py +75 -0
- src/htcli/utils/blockchain/formatting.py +368 -0
- src/htcli/utils/blockchain/patches.py +286 -0
- src/htcli/utils/blockchain/peer_id.py +186 -0
- src/htcli/utils/blockchain/staking.py +448 -0
- src/htcli/utils/blockchain/type_registry.py +1373 -0
- src/htcli/utils/blockchain/validation.py +179 -0
- src/htcli/utils/cache.py +613 -0
- src/htcli/utils/constants.py +38 -0
- src/htcli/utils/legacy/__init__.py +12 -0
- src/htcli/utils/legacy/colors.py +311 -0
- src/htcli/utils/legacy/crypto.py +1176 -0
- src/htcli/utils/legacy/formatting.py +452 -0
- src/htcli/utils/legacy/interactive.py +306 -0
- src/htcli/utils/legacy/subnet_manifest.py +265 -0
- src/htcli/utils/legacy/validation.py +488 -0
- src/htcli/utils/logging.py +183 -0
- src/htcli/utils/network/__init__.py +20 -0
- src/htcli/utils/network/subnet.py +344 -0
- src/htcli/utils/prompts.py +27 -0
- src/htcli/utils/scale_codec.py +155 -0
- src/htcli/utils/validation/__init__.py +57 -0
- src/htcli/utils/validation/prompt_validators.py +267 -0
- src/htcli/utils/wallet/__init__.py +65 -0
- src/htcli/utils/wallet/auth.py +151 -0
- src/htcli/utils/wallet/core.py +1069 -0
- src/htcli/utils/wallet/crypto.py +1615 -0
- src/htcli/utils/wallet/migration.py +159 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Wallet command module.
|
|
3
|
+
|
|
4
|
+
Provides wallet management functionality including generation, restoration, listing, and operations.
|
|
5
|
+
Migrated from the original wallet commands with the new folder-based architecture.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from textwrap import dedent
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
|
|
13
|
+
from .handlers import (
|
|
14
|
+
balance_handler,
|
|
15
|
+
check_hotkey_owner_handler,
|
|
16
|
+
delete_handler,
|
|
17
|
+
describe_handler,
|
|
18
|
+
generate_coldkey_handler,
|
|
19
|
+
generate_handler,
|
|
20
|
+
generate_hotkey_handler,
|
|
21
|
+
list_wallets_handler,
|
|
22
|
+
restore_coldkey_handler,
|
|
23
|
+
restore_hotkey_handler,
|
|
24
|
+
status_handler,
|
|
25
|
+
transfer_handler,
|
|
26
|
+
update_coldkey_handler,
|
|
27
|
+
update_hotkey_handler,
|
|
28
|
+
rotate_coldkey_handler,
|
|
29
|
+
rotate_hotkey_handler,
|
|
30
|
+
upgrade_wallet_layout_handler,
|
|
31
|
+
update_identity_handler,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
app = typer.Typer(name="wallet", help="Wallet operations and management")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
DELETE_HELP = dedent(
|
|
38
|
+
"""\
|
|
39
|
+
Delete wallets with confirmation.
|
|
40
|
+
|
|
41
|
+
\b
|
|
42
|
+
Usage:
|
|
43
|
+
- To delete a coldkey: --coldkey <name>
|
|
44
|
+
- To delete a hotkey: --coldkey <owner_name> --hotkey <name>
|
|
45
|
+
"""
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
ROTATE_COLDKEY_HELP = dedent(
|
|
49
|
+
"""\
|
|
50
|
+
Rotate a coldkey to a new keypair.
|
|
51
|
+
|
|
52
|
+
This operation:
|
|
53
|
+
|
|
54
|
+
\b
|
|
55
|
+
1. Generates a new keypair in memory.
|
|
56
|
+
2. Submits an on-chain extrinsic to update the coldkey address.
|
|
57
|
+
3. Backs up the old wallet file.
|
|
58
|
+
4. Overwrites the local wallet file with the new keypair.
|
|
59
|
+
|
|
60
|
+
\b
|
|
61
|
+
Warning:
|
|
62
|
+
Ensure you have backed up your old key before running this.
|
|
63
|
+
"""
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
ROTATE_HOTKEY_HELP = dedent(
|
|
67
|
+
"""\
|
|
68
|
+
Rotate a hotkey to a new keypair.
|
|
69
|
+
|
|
70
|
+
This operation:
|
|
71
|
+
|
|
72
|
+
\b
|
|
73
|
+
1. Generates a new keypair in memory.
|
|
74
|
+
2. Submits an on-chain extrinsic signed by the owner to update the hotkey address.
|
|
75
|
+
3. Backs up the old wallet file.
|
|
76
|
+
4. Overwrites the local wallet file with the new keypair.
|
|
77
|
+
|
|
78
|
+
\b
|
|
79
|
+
Warning:
|
|
80
|
+
Ensure you have backed up your old key before running this.
|
|
81
|
+
"""
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@app.command()
|
|
86
|
+
def generate(
|
|
87
|
+
coldkey_name: Optional[str] = typer.Option(
|
|
88
|
+
None, "--coldkey", "-c", help="Coldkey wallet name"
|
|
89
|
+
),
|
|
90
|
+
hotkey_name: Optional[str] = typer.Option(
|
|
91
|
+
None, "--hotkey", "-h", help="Hotkey name"
|
|
92
|
+
),
|
|
93
|
+
password: Optional[str] = typer.Option(
|
|
94
|
+
None, "--password", "-p", help="Key password"
|
|
95
|
+
),
|
|
96
|
+
no_password: bool = typer.Option(
|
|
97
|
+
False, "--no-password", help="Skip password encryption (no prompt)"
|
|
98
|
+
),
|
|
99
|
+
copy_mnemonic: bool = typer.Option(
|
|
100
|
+
False,
|
|
101
|
+
"--copy-mnemonic",
|
|
102
|
+
help="Copy recovery phrase to clipboard after generation",
|
|
103
|
+
),
|
|
104
|
+
):
|
|
105
|
+
"""Generate a new wallet with both coldkey and hotkey at once."""
|
|
106
|
+
# If --no-password is set, use empty string to skip encryption
|
|
107
|
+
final_password = "" if no_password else password
|
|
108
|
+
generate_handler(
|
|
109
|
+
coldkey_name=coldkey_name,
|
|
110
|
+
hotkey_name=hotkey_name,
|
|
111
|
+
key_type="ecdsa",
|
|
112
|
+
password=final_password,
|
|
113
|
+
copy_mnemonic=copy_mnemonic,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@app.command()
|
|
118
|
+
def generate_hotkey(
|
|
119
|
+
hotkey_name: Optional[str] = typer.Option(
|
|
120
|
+
None, "--hotkey", "-h", help="Hotkey name"
|
|
121
|
+
),
|
|
122
|
+
coldkey_name: Optional[str] = typer.Option(
|
|
123
|
+
None,
|
|
124
|
+
"--coldkey",
|
|
125
|
+
"-c",
|
|
126
|
+
"--owner",
|
|
127
|
+
help="Coldkey wallet name that owns this hotkey (alias: --owner)",
|
|
128
|
+
),
|
|
129
|
+
password: Optional[str] = typer.Option(
|
|
130
|
+
None, "--password", "-p", help="Key password"
|
|
131
|
+
),
|
|
132
|
+
no_password: bool = typer.Option(
|
|
133
|
+
False, "--no-password", help="Skip password encryption (no prompt)"
|
|
134
|
+
),
|
|
135
|
+
copy_mnemonic: bool = typer.Option(
|
|
136
|
+
False,
|
|
137
|
+
"--copy-mnemonic",
|
|
138
|
+
help="Copy recovery phrase to clipboard after generation",
|
|
139
|
+
),
|
|
140
|
+
):
|
|
141
|
+
"""Generate a new hotkey with comprehensive guidance."""
|
|
142
|
+
# If --no-password is set, use empty string to skip encryption
|
|
143
|
+
final_password = "" if no_password else password
|
|
144
|
+
generate_hotkey_handler(
|
|
145
|
+
name=hotkey_name,
|
|
146
|
+
coldkey_name=coldkey_name,
|
|
147
|
+
key_type="ecdsa",
|
|
148
|
+
password=final_password,
|
|
149
|
+
copy_mnemonic=copy_mnemonic,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@app.command()
|
|
154
|
+
def generate_coldkey(
|
|
155
|
+
name: Optional[str] = typer.Option(None, "--name", "-n", help="Coldkey name"),
|
|
156
|
+
password: Optional[str] = typer.Option(
|
|
157
|
+
None, "--password", "-p", help="Key password"
|
|
158
|
+
),
|
|
159
|
+
no_password: bool = typer.Option(
|
|
160
|
+
False, "--no-password", help="Skip password encryption (no prompt)"
|
|
161
|
+
),
|
|
162
|
+
copy_mnemonic: bool = typer.Option(
|
|
163
|
+
False,
|
|
164
|
+
"--copy-mnemonic",
|
|
165
|
+
help="Copy recovery phrase to clipboard after generation",
|
|
166
|
+
),
|
|
167
|
+
):
|
|
168
|
+
"""Generate a new coldkey with comprehensive guidance."""
|
|
169
|
+
# If --no-password is set, use empty string to skip encryption
|
|
170
|
+
final_password = "" if no_password else password
|
|
171
|
+
generate_coldkey_handler(
|
|
172
|
+
name=name,
|
|
173
|
+
key_type="ecdsa", # Fixed to ECDSA for HyperTensor EVM compatibility
|
|
174
|
+
password=final_password,
|
|
175
|
+
copy_mnemonic=copy_mnemonic,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@app.command()
|
|
180
|
+
def restore_coldkey(
|
|
181
|
+
name: Optional[str] = typer.Option(None, "--name", "-n", help="Coldkey name"),
|
|
182
|
+
private_key: Optional[str] = typer.Option(
|
|
183
|
+
None, "--private-key", "-p", help="Private key to restore from"
|
|
184
|
+
),
|
|
185
|
+
mnemonic: Optional[str] = typer.Option(
|
|
186
|
+
None, "--mnemonic", "-m", help="Mnemonic phrase to restore from"
|
|
187
|
+
),
|
|
188
|
+
key_type: str = typer.Option(
|
|
189
|
+
"ecdsa", "--type", "-t", help="Key type (ecdsa/sr25519/ed25519)"
|
|
190
|
+
),
|
|
191
|
+
password: Optional[str] = typer.Option(None, "--password", help="Key password"),
|
|
192
|
+
):
|
|
193
|
+
"""Restore a coldkey from private key or mnemonic."""
|
|
194
|
+
restore_coldkey_handler(
|
|
195
|
+
name=name,
|
|
196
|
+
private_key=private_key,
|
|
197
|
+
mnemonic=mnemonic,
|
|
198
|
+
key_type=key_type,
|
|
199
|
+
password=password,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@app.command()
|
|
204
|
+
def restore_hotkey(
|
|
205
|
+
hotkey_name: Optional[str] = typer.Option(
|
|
206
|
+
None, "--hotkey", "-h", help="Hotkey name"
|
|
207
|
+
),
|
|
208
|
+
private_key: Optional[str] = typer.Option(
|
|
209
|
+
None, "--private-key", "-p", help="Private key to restore from"
|
|
210
|
+
),
|
|
211
|
+
mnemonic: Optional[str] = typer.Option(
|
|
212
|
+
None, "--mnemonic", "-m", help="Mnemonic phrase to restore from"
|
|
213
|
+
),
|
|
214
|
+
coldkey_name: Optional[str] = typer.Option(
|
|
215
|
+
None,
|
|
216
|
+
"--coldkey",
|
|
217
|
+
"-c",
|
|
218
|
+
"--owner",
|
|
219
|
+
help="Coldkey wallet name that owns this hotkey (alias: --owner)",
|
|
220
|
+
),
|
|
221
|
+
key_type: str = typer.Option(
|
|
222
|
+
"ecdsa", "--type", "-t", help="Key type (ecdsa/sr25519/ed25519)"
|
|
223
|
+
),
|
|
224
|
+
password: Optional[str] = typer.Option(None, "--password", help="Key password"),
|
|
225
|
+
):
|
|
226
|
+
"""Restore a hotkey from private key or mnemonic."""
|
|
227
|
+
restore_hotkey_handler(
|
|
228
|
+
name=hotkey_name,
|
|
229
|
+
private_key=private_key,
|
|
230
|
+
mnemonic=mnemonic,
|
|
231
|
+
owner_name=coldkey_name,
|
|
232
|
+
key_type=key_type,
|
|
233
|
+
password=password,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@app.command()
|
|
238
|
+
def list(
|
|
239
|
+
format_type: str = typer.Option(
|
|
240
|
+
"tree", "--format", "-f", help="Output format (tree/table/json)"
|
|
241
|
+
),
|
|
242
|
+
show_balances: bool = typer.Option(
|
|
243
|
+
False, "--balances", "-b", help="Show wallet balances"
|
|
244
|
+
),
|
|
245
|
+
):
|
|
246
|
+
"""List all wallets with comprehensive information."""
|
|
247
|
+
list_wallets_handler(format_type=format_type, show_balances=show_balances)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
# @app.command()
|
|
251
|
+
# def status(
|
|
252
|
+
# format_type: str = typer.Option(
|
|
253
|
+
# "table", "--format", "-f", help="Output format (table/json)"
|
|
254
|
+
# ),
|
|
255
|
+
# check_balances: bool = typer.Option(
|
|
256
|
+
# False, "--balances", "-b", help="Check wallet balances"
|
|
257
|
+
# ),
|
|
258
|
+
# ):
|
|
259
|
+
# """Show wallet status and identity information."""
|
|
260
|
+
# status_handler(format_type=format_type, check_balances=check_balances)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@app.command(help=DELETE_HELP)
|
|
264
|
+
def delete(
|
|
265
|
+
coldkey: Optional[str] = typer.Option(
|
|
266
|
+
None,
|
|
267
|
+
"--coldkey",
|
|
268
|
+
"-c",
|
|
269
|
+
help="Coldkey name to delete (required for coldkey deletion)",
|
|
270
|
+
),
|
|
271
|
+
hotkey: Optional[str] = typer.Option(
|
|
272
|
+
None,
|
|
273
|
+
"--hotkey",
|
|
274
|
+
"-h",
|
|
275
|
+
help="Hotkey name to delete (requires --coldkey to specify owner)",
|
|
276
|
+
),
|
|
277
|
+
force: bool = typer.Option(
|
|
278
|
+
False, "--force", "-f", help="Skip confirmation prompts"
|
|
279
|
+
),
|
|
280
|
+
):
|
|
281
|
+
"""Delete wallets with confirmation."""
|
|
282
|
+
delete_handler(coldkey=coldkey, hotkey=hotkey, force=force)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
@app.command()
|
|
286
|
+
def balance(
|
|
287
|
+
wallet_name: Optional[str] = typer.Option(
|
|
288
|
+
None,
|
|
289
|
+
"--coldkey",
|
|
290
|
+
"-c",
|
|
291
|
+
"--name",
|
|
292
|
+
"-n",
|
|
293
|
+
help="Coldkey wallet name to check balance",
|
|
294
|
+
),
|
|
295
|
+
address: Optional[str] = typer.Option(
|
|
296
|
+
None, "--address", "-a", help="Address to check balance"
|
|
297
|
+
),
|
|
298
|
+
show_all: bool = typer.Option(False, "--all", help="Show balance for all wallets"),
|
|
299
|
+
format_type: str = typer.Option(
|
|
300
|
+
"table", "--format", "-f", help="Output format (table/json)"
|
|
301
|
+
),
|
|
302
|
+
show_guidance: bool = typer.Option(
|
|
303
|
+
True, "--guidance/--no-guidance", help="Show comprehensive guidance"
|
|
304
|
+
),
|
|
305
|
+
):
|
|
306
|
+
"""Check balance of a wallet, address, or all wallets."""
|
|
307
|
+
balance_handler(
|
|
308
|
+
wallet_name=wallet_name,
|
|
309
|
+
address=address,
|
|
310
|
+
show_all=show_all,
|
|
311
|
+
format_type=format_type,
|
|
312
|
+
show_guidance=show_guidance,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@app.command()
|
|
317
|
+
def transfer(
|
|
318
|
+
from_wallet: Optional[str] = typer.Option(
|
|
319
|
+
None, "--from", "-f", help="Source wallet name"
|
|
320
|
+
),
|
|
321
|
+
to_address: Optional[str] = typer.Option(
|
|
322
|
+
None, "--to", "-t", help="Destination address"
|
|
323
|
+
),
|
|
324
|
+
amount: Optional[float] = typer.Option(
|
|
325
|
+
None, "--amount", "-a", help="Amount to transfer"
|
|
326
|
+
),
|
|
327
|
+
password: Optional[str] = typer.Option(
|
|
328
|
+
None, "--password", "-p", help="Wallet password"
|
|
329
|
+
),
|
|
330
|
+
dry_run: bool = typer.Option(
|
|
331
|
+
False, "--dry-run", help="Show transfer details without executing"
|
|
332
|
+
),
|
|
333
|
+
):
|
|
334
|
+
"""Transfer balance from one wallet to another address."""
|
|
335
|
+
transfer_handler(
|
|
336
|
+
from_wallet=from_wallet,
|
|
337
|
+
to_address=to_address,
|
|
338
|
+
amount=amount,
|
|
339
|
+
password=password,
|
|
340
|
+
dry_run=dry_run,
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
@app.command("update-coldkey")
|
|
345
|
+
def update_coldkey_cmd(
|
|
346
|
+
name: Optional[str] = typer.Option(None, "--name", "-n", help="Coldkey name"),
|
|
347
|
+
new_name: Optional[str] = typer.Option(None, "--new-name", help="New wallet name"),
|
|
348
|
+
new_password: Optional[str] = typer.Option(
|
|
349
|
+
None, "--new-password", help="New password"
|
|
350
|
+
),
|
|
351
|
+
current_password: Optional[str] = typer.Option(
|
|
352
|
+
None, "--current-password", help="Current password"
|
|
353
|
+
),
|
|
354
|
+
):
|
|
355
|
+
"""Update coldkey password or other properties."""
|
|
356
|
+
update_coldkey_handler(
|
|
357
|
+
name=name,
|
|
358
|
+
new_name=new_name,
|
|
359
|
+
new_password=new_password,
|
|
360
|
+
current_password=current_password,
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
@app.command("update-hotkey")
|
|
365
|
+
def update_hotkey_cmd(
|
|
366
|
+
hotkey_name: Optional[str] = typer.Option(
|
|
367
|
+
None, "--hotkey", "-h", help="Hotkey name"
|
|
368
|
+
),
|
|
369
|
+
coldkey_name: Optional[str] = typer.Option(
|
|
370
|
+
None,
|
|
371
|
+
"--coldkey",
|
|
372
|
+
"-c",
|
|
373
|
+
"--owner",
|
|
374
|
+
help="Current coldkey name (required to identify the hotkey, alias: --owner)",
|
|
375
|
+
),
|
|
376
|
+
new_password: Optional[str] = typer.Option(
|
|
377
|
+
None, "--new-password", help="New password"
|
|
378
|
+
),
|
|
379
|
+
current_password: Optional[str] = typer.Option(
|
|
380
|
+
None, "--current-password", help="Current password"
|
|
381
|
+
),
|
|
382
|
+
new_coldkey: Optional[str] = typer.Option(
|
|
383
|
+
None, "--new-coldkey", help="New coldkey name"
|
|
384
|
+
),
|
|
385
|
+
new_hotkey: Optional[str] = typer.Option(
|
|
386
|
+
None, "--new-hotkey", help="New hotkey name"
|
|
387
|
+
),
|
|
388
|
+
):
|
|
389
|
+
"""Update hotkey password, coldkey, or other properties."""
|
|
390
|
+
update_hotkey_handler(
|
|
391
|
+
name=hotkey_name,
|
|
392
|
+
owner_name=coldkey_name,
|
|
393
|
+
new_password=new_password,
|
|
394
|
+
current_password=current_password,
|
|
395
|
+
new_owner=new_coldkey,
|
|
396
|
+
new_name=new_hotkey,
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@app.command("rotate-coldkey", help=ROTATE_COLDKEY_HELP)
|
|
401
|
+
def rotate_coldkey(
|
|
402
|
+
name: Optional[str] = typer.Option(None, "--name", "-n", help="Coldkey name"),
|
|
403
|
+
password: Optional[str] = typer.Option(
|
|
404
|
+
None, "--password", "-p", help="Key password"
|
|
405
|
+
),
|
|
406
|
+
):
|
|
407
|
+
"""Rotate a coldkey to a new keypair."""
|
|
408
|
+
if not name:
|
|
409
|
+
from .prompts import prompt_wallet_selection
|
|
410
|
+
|
|
411
|
+
name = prompt_wallet_selection("Select coldkey to rotate", is_hotkey=False)
|
|
412
|
+
|
|
413
|
+
rotate_coldkey_handler(name=name, password=password)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
@app.command("rotate-hotkey", help=ROTATE_HOTKEY_HELP)
|
|
417
|
+
def rotate_hotkey(
|
|
418
|
+
name: Optional[str] = typer.Option(None, "--name", "-n", help="Hotkey name"),
|
|
419
|
+
owner_name: Optional[str] = typer.Option(
|
|
420
|
+
None, "--owner", "-o", help="Owner coldkey name (required)"
|
|
421
|
+
),
|
|
422
|
+
password: Optional[str] = typer.Option(
|
|
423
|
+
None, "--password", "-p", help="Key password"
|
|
424
|
+
),
|
|
425
|
+
):
|
|
426
|
+
"""Rotate a hotkey to a new keypair."""
|
|
427
|
+
if not name:
|
|
428
|
+
from .prompts import prompt_wallet_selection
|
|
429
|
+
|
|
430
|
+
name = prompt_wallet_selection("Select hotkey to rotate", is_hotkey=True)
|
|
431
|
+
|
|
432
|
+
rotate_hotkey_handler(name=name, owner_name=owner_name, password=password)
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
@app.command()
|
|
436
|
+
def describe(
|
|
437
|
+
name: Optional[str] = typer.Option(
|
|
438
|
+
None, "--name", "-n", help="Wallet name to describe"
|
|
439
|
+
),
|
|
440
|
+
):
|
|
441
|
+
"""Describe a wallet with detailed information including balance and full address."""
|
|
442
|
+
describe_handler(name=name)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
@app.command("check-hotkey-owner")
|
|
446
|
+
def check_hotkey_owner(
|
|
447
|
+
hotkey: Optional[str] = typer.Option(None, "--hotkey", "-h", help="Hotkey name"),
|
|
448
|
+
address: Optional[str] = typer.Option(
|
|
449
|
+
None, "--address", "-a", help="Hotkey address"
|
|
450
|
+
),
|
|
451
|
+
coldkey: Optional[str] = typer.Option(
|
|
452
|
+
None,
|
|
453
|
+
"--coldkey",
|
|
454
|
+
"-c",
|
|
455
|
+
help="Coldkey name (required if hotkey name is ambiguous)",
|
|
456
|
+
),
|
|
457
|
+
):
|
|
458
|
+
"""Check the on-chain owner of a hotkey."""
|
|
459
|
+
check_hotkey_owner_handler(
|
|
460
|
+
hotkey_name=hotkey,
|
|
461
|
+
hotkey_address=address,
|
|
462
|
+
coldkey_name=coldkey,
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
@app.command()
|
|
467
|
+
def upgrade(
|
|
468
|
+
dry_run: bool = typer.Option(
|
|
469
|
+
False, "--dry-run", help="Show actions without modifying files"
|
|
470
|
+
),
|
|
471
|
+
force: bool = typer.Option(
|
|
472
|
+
False, "--force", "-f", help="Overwrite existing hierarchical files"
|
|
473
|
+
),
|
|
474
|
+
no_backup: bool = typer.Option(
|
|
475
|
+
False, "--no-backup", help="Skip creating .bak backups before moving files"
|
|
476
|
+
),
|
|
477
|
+
wallets: Optional[str] = typer.Option(
|
|
478
|
+
None,
|
|
479
|
+
"--wallets",
|
|
480
|
+
help="Comma-separated coldkey names to migrate (default: all legacy wallets)",
|
|
481
|
+
),
|
|
482
|
+
):
|
|
483
|
+
"""Upgrade wallet storage layout to the per-coldkey hierarchy."""
|
|
484
|
+
wallet_list = (
|
|
485
|
+
[item.strip() for item in wallets.split(",") if item.strip()]
|
|
486
|
+
if wallets
|
|
487
|
+
else None
|
|
488
|
+
)
|
|
489
|
+
upgrade_wallet_layout_handler(
|
|
490
|
+
dry_run=dry_run,
|
|
491
|
+
force=force,
|
|
492
|
+
backup=not no_backup,
|
|
493
|
+
wallet_names=wallet_list,
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
@app.command()
|
|
498
|
+
def identity(
|
|
499
|
+
hotkey: Optional[str] = typer.Option(
|
|
500
|
+
None, "--hotkey", "-h", help="Hotkey name to update identity for"
|
|
501
|
+
),
|
|
502
|
+
name: Optional[str] = typer.Option(None, "--name", "-n", help="Display name"),
|
|
503
|
+
url: Optional[str] = typer.Option(None, "--url", "-u", help="Website URL"),
|
|
504
|
+
image: Optional[str] = typer.Option(
|
|
505
|
+
None, "--image", "-i", help="Profile image URL"
|
|
506
|
+
),
|
|
507
|
+
discord: Optional[str] = typer.Option(
|
|
508
|
+
None, "--discord", "-d", help="Discord handle"
|
|
509
|
+
),
|
|
510
|
+
x: Optional[str] = typer.Option(None, "--x", "-x", help="X (Twitter) handle"),
|
|
511
|
+
telegram: Optional[str] = typer.Option(
|
|
512
|
+
None, "--telegram", "-t", help="Telegram handle"
|
|
513
|
+
),
|
|
514
|
+
github: Optional[str] = typer.Option(
|
|
515
|
+
None, "--github", "-g", help="GitHub profile URL"
|
|
516
|
+
),
|
|
517
|
+
hugging_face: Optional[str] = typer.Option(
|
|
518
|
+
None, "--hugging-face", "-hf", help="Hugging Face profile URL"
|
|
519
|
+
),
|
|
520
|
+
description: Optional[str] = typer.Option(
|
|
521
|
+
None, "--description", "-desc", help="Short description"
|
|
522
|
+
),
|
|
523
|
+
misc: Optional[str] = typer.Option(None, "--misc", "-m", help="Additional data"),
|
|
524
|
+
password: Optional[str] = typer.Option(
|
|
525
|
+
None, "--password", "-p", help="Wallet password"
|
|
526
|
+
),
|
|
527
|
+
):
|
|
528
|
+
"""Register or update identity information for a hotkey."""
|
|
529
|
+
update_identity_handler(
|
|
530
|
+
hotkey_name=hotkey,
|
|
531
|
+
name=name,
|
|
532
|
+
url=url,
|
|
533
|
+
image=image,
|
|
534
|
+
discord=discord,
|
|
535
|
+
x=x,
|
|
536
|
+
telegram=telegram,
|
|
537
|
+
github=github,
|
|
538
|
+
hugging_face=hugging_face,
|
|
539
|
+
description=description,
|
|
540
|
+
misc=misc,
|
|
541
|
+
password=password,
|
|
542
|
+
)
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
# Export the app for main.py
|
|
546
|
+
__all__ = ["app"]
|