hippius 0.2.1__py3-none-any.whl → 0.2.3__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.
- {hippius-0.2.1.dist-info → hippius-0.2.3.dist-info}/METADATA +8 -7
- hippius-0.2.3.dist-info/RECORD +16 -0
- hippius_sdk/__init__.py +1 -1
- hippius_sdk/cli.py +277 -2628
- hippius_sdk/cli_assets.py +8 -0
- hippius_sdk/cli_handlers.py +2370 -0
- hippius_sdk/cli_parser.py +602 -0
- hippius_sdk/cli_rich.py +253 -0
- hippius_sdk/client.py +56 -8
- hippius_sdk/config.py +1 -1
- hippius_sdk/ipfs.py +540 -130
- hippius_sdk/ipfs_core.py +22 -1
- hippius_sdk/substrate.py +215 -525
- hippius_sdk/utils.py +84 -2
- hippius-0.2.1.dist-info/RECORD +0 -12
- {hippius-0.2.1.dist-info → hippius-0.2.3.dist-info}/WHEEL +0 -0
- {hippius-0.2.1.dist-info → hippius-0.2.3.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,602 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Command Line Interface argument parser for Hippius SDK.
|
4
|
+
|
5
|
+
This module provides the argument parsing functionality for the Hippius CLI,
|
6
|
+
defining all available commands, subcommands, and their respective arguments.
|
7
|
+
"""
|
8
|
+
|
9
|
+
import argparse
|
10
|
+
|
11
|
+
from hippius_sdk import get_config_value
|
12
|
+
|
13
|
+
|
14
|
+
def get_default_address():
|
15
|
+
"""Get the default address for read-only operations"""
|
16
|
+
from hippius_sdk import load_config
|
17
|
+
|
18
|
+
config = load_config()
|
19
|
+
return config["substrate"].get("default_address")
|
20
|
+
|
21
|
+
|
22
|
+
def create_parser() -> argparse.ArgumentParser:
|
23
|
+
"""Create and configure the argument parser for the CLI."""
|
24
|
+
# Import custom help action that shows the logo
|
25
|
+
from hippius_sdk.cli_rich import RichHelpAction
|
26
|
+
|
27
|
+
# Set up the argument parser
|
28
|
+
parser = argparse.ArgumentParser(
|
29
|
+
description="Hippius SDK Command Line Interface",
|
30
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
31
|
+
add_help=False, # Disable the default help action
|
32
|
+
epilog="""
|
33
|
+
examples:
|
34
|
+
# Store a file
|
35
|
+
hippius store example.txt
|
36
|
+
|
37
|
+
# Store a directory
|
38
|
+
hippius store-dir ./my_directory
|
39
|
+
|
40
|
+
# Download a file
|
41
|
+
hippius download QmHash output.txt
|
42
|
+
|
43
|
+
# Check if a CID exists
|
44
|
+
hippius exists QmHash
|
45
|
+
|
46
|
+
# View the content of a CID
|
47
|
+
hippius cat QmHash
|
48
|
+
|
49
|
+
# View your available credits
|
50
|
+
hippius credits
|
51
|
+
|
52
|
+
# View your stored files
|
53
|
+
hippius files
|
54
|
+
|
55
|
+
# View all miners for stored files
|
56
|
+
hippius files --all-miners
|
57
|
+
|
58
|
+
# Check file pinning status
|
59
|
+
hippius pinning-status
|
60
|
+
|
61
|
+
# Erasure code a file (Reed-Solomon)
|
62
|
+
hippius erasure-code large_file.mp4 --k 3 --m 5
|
63
|
+
|
64
|
+
# Erasure code without publishing to global IPFS network
|
65
|
+
hippius erasure-code large_file.avi --no-publish
|
66
|
+
|
67
|
+
# Reconstruct an erasure-coded file
|
68
|
+
hippius reconstruct QmMetadataHash reconstructed_file.mp4
|
69
|
+
|
70
|
+
# Delete a file from IPFS and marketplace
|
71
|
+
hippius delete QmHash
|
72
|
+
|
73
|
+
# Delete an erasure-coded file and all its chunks
|
74
|
+
hippius ec-delete QmMetadataHash
|
75
|
+
""",
|
76
|
+
)
|
77
|
+
|
78
|
+
# Add our custom help option
|
79
|
+
parser.add_argument(
|
80
|
+
"-h", "--help", action=RichHelpAction, help="Show this help message and exit"
|
81
|
+
)
|
82
|
+
|
83
|
+
# Optional arguments for all commands
|
84
|
+
parser.add_argument(
|
85
|
+
"--gateway",
|
86
|
+
default=get_config_value("ipfs", "gateway", "https://get.hippius.network"),
|
87
|
+
help="IPFS gateway URL for downloads (default: from config or https://get.hippius.network)",
|
88
|
+
)
|
89
|
+
parser.add_argument(
|
90
|
+
"--api-url",
|
91
|
+
default=get_config_value("ipfs", "api_url", "https://store.hippius.network"),
|
92
|
+
help="IPFS API URL for uploads (default: from config or https://store.hippius.network)",
|
93
|
+
)
|
94
|
+
parser.add_argument(
|
95
|
+
"--local-ipfs",
|
96
|
+
action="store_true",
|
97
|
+
default=get_config_value("ipfs", "local_ipfs", False),
|
98
|
+
help="Use local IPFS node (http://localhost:5001) instead of remote API",
|
99
|
+
)
|
100
|
+
parser.add_argument(
|
101
|
+
"--substrate-url",
|
102
|
+
default=get_config_value("substrate", "url", "wss://rpc.hippius.network"),
|
103
|
+
help="Substrate node WebSocket URL (default: from config or wss://rpc.hippius.network)",
|
104
|
+
)
|
105
|
+
parser.add_argument(
|
106
|
+
"--miner-ids",
|
107
|
+
help="Comma-separated list of miner IDs for storage (default: from config)",
|
108
|
+
)
|
109
|
+
parser.add_argument(
|
110
|
+
"--verbose",
|
111
|
+
"-v",
|
112
|
+
action="store_true",
|
113
|
+
default=get_config_value("cli", "verbose", False),
|
114
|
+
help="Enable verbose debug output",
|
115
|
+
)
|
116
|
+
parser.add_argument(
|
117
|
+
"--encrypt",
|
118
|
+
action="store_true",
|
119
|
+
help="Encrypt files when uploading (overrides default)",
|
120
|
+
)
|
121
|
+
parser.add_argument(
|
122
|
+
"--no-encrypt",
|
123
|
+
action="store_true",
|
124
|
+
help="Do not encrypt files when uploading (overrides default)",
|
125
|
+
)
|
126
|
+
parser.add_argument(
|
127
|
+
"--decrypt",
|
128
|
+
action="store_true",
|
129
|
+
help="Decrypt files when downloading (overrides default)",
|
130
|
+
)
|
131
|
+
parser.add_argument(
|
132
|
+
"--no-decrypt",
|
133
|
+
action="store_true",
|
134
|
+
help="Do not decrypt files when downloading (overrides default)",
|
135
|
+
)
|
136
|
+
parser.add_argument(
|
137
|
+
"--encryption-key",
|
138
|
+
help="Base64-encoded encryption key (overrides HIPPIUS_ENCRYPTION_KEY in .env)",
|
139
|
+
)
|
140
|
+
parser.add_argument(
|
141
|
+
"--password",
|
142
|
+
help="Password to decrypt the seed phrase if needed (will prompt if required and not provided)",
|
143
|
+
)
|
144
|
+
parser.add_argument(
|
145
|
+
"--account",
|
146
|
+
help="Account name to use (uses active account if not specified)",
|
147
|
+
)
|
148
|
+
|
149
|
+
# Subcommands
|
150
|
+
subparsers = parser.add_subparsers(dest="command", help="Commands")
|
151
|
+
|
152
|
+
# Add all command parsers
|
153
|
+
add_file_commands(subparsers)
|
154
|
+
add_storage_commands(subparsers)
|
155
|
+
add_market_commands(subparsers)
|
156
|
+
add_erasure_coding_commands(subparsers)
|
157
|
+
add_config_commands(subparsers)
|
158
|
+
add_seed_commands(subparsers)
|
159
|
+
add_account_commands(subparsers)
|
160
|
+
add_address_commands(subparsers)
|
161
|
+
|
162
|
+
return parser
|
163
|
+
|
164
|
+
|
165
|
+
def add_file_commands(subparsers):
|
166
|
+
"""Add file operation commands to the parser."""
|
167
|
+
# Download command
|
168
|
+
download_parser = subparsers.add_parser(
|
169
|
+
"download", help="Download a file from IPFS"
|
170
|
+
)
|
171
|
+
download_parser.add_argument("cid", help="CID of file to download")
|
172
|
+
download_parser.add_argument("output_path", help="Path to save downloaded file")
|
173
|
+
|
174
|
+
# Exists command
|
175
|
+
exists_parser = subparsers.add_parser(
|
176
|
+
"exists", help="Check if a CID exists on IPFS"
|
177
|
+
)
|
178
|
+
exists_parser.add_argument("cid", help="CID to check")
|
179
|
+
|
180
|
+
# Cat command
|
181
|
+
cat_parser = subparsers.add_parser(
|
182
|
+
"cat", help="Display content of a file from IPFS"
|
183
|
+
)
|
184
|
+
cat_parser.add_argument("cid", help="CID of file to display")
|
185
|
+
cat_parser.add_argument(
|
186
|
+
"--max-size",
|
187
|
+
type=int,
|
188
|
+
default=1024,
|
189
|
+
help="Maximum number of bytes to display (default: 1024)",
|
190
|
+
)
|
191
|
+
|
192
|
+
|
193
|
+
def add_storage_commands(subparsers):
|
194
|
+
"""Add storage commands to the parser."""
|
195
|
+
# Store command (upload to IPFS then store on Substrate)
|
196
|
+
store_parser = subparsers.add_parser(
|
197
|
+
"store", help="Upload a file to IPFS and store it on Substrate"
|
198
|
+
)
|
199
|
+
store_parser.add_argument("file_path", help="Path to file to upload")
|
200
|
+
|
201
|
+
# Store directory command
|
202
|
+
store_dir_parser = subparsers.add_parser(
|
203
|
+
"store-dir", help="Upload a directory to IPFS and store all files on Substrate"
|
204
|
+
)
|
205
|
+
store_dir_parser.add_argument("dir_path", help="Path to directory to upload")
|
206
|
+
|
207
|
+
# Pinning status command
|
208
|
+
pinning_status_parser = subparsers.add_parser(
|
209
|
+
"pinning-status", help="Check the status of file pinning requests"
|
210
|
+
)
|
211
|
+
pinning_status_parser.add_argument(
|
212
|
+
"--account_address",
|
213
|
+
help="Substrate account to view pins for (defaults to your keyfile account)",
|
214
|
+
)
|
215
|
+
pinning_status_parser.add_argument(
|
216
|
+
"--no-contents",
|
217
|
+
action="store_true",
|
218
|
+
help="Don't fetch additional content info for pins",
|
219
|
+
)
|
220
|
+
|
221
|
+
# Delete command
|
222
|
+
delete_parser = subparsers.add_parser(
|
223
|
+
"delete",
|
224
|
+
help="Delete a file from IPFS and cancel its storage on the blockchain",
|
225
|
+
)
|
226
|
+
delete_parser.add_argument("cid", help="CID of file to delete")
|
227
|
+
delete_parser.add_argument(
|
228
|
+
"--force",
|
229
|
+
action="store_true",
|
230
|
+
help="Delete without confirmation prompt",
|
231
|
+
)
|
232
|
+
|
233
|
+
# Keygen command
|
234
|
+
keygen_parser = subparsers.add_parser(
|
235
|
+
"keygen", help="Generate an encryption key for secure file storage"
|
236
|
+
)
|
237
|
+
keygen_parser.add_argument(
|
238
|
+
"--save",
|
239
|
+
action="store_true",
|
240
|
+
help="Save the generated key to the configuration",
|
241
|
+
)
|
242
|
+
keygen_parser.add_argument(
|
243
|
+
"--copy",
|
244
|
+
action="store_true",
|
245
|
+
help="Copy the key to clipboard (requires pyperclip)",
|
246
|
+
)
|
247
|
+
|
248
|
+
|
249
|
+
def add_market_commands(subparsers):
|
250
|
+
"""Add marketplace commands to the parser."""
|
251
|
+
# Credits command
|
252
|
+
credits_parser = subparsers.add_parser(
|
253
|
+
"credits", help="Check free credits for an account in the marketplace"
|
254
|
+
)
|
255
|
+
credits_parser.add_argument(
|
256
|
+
"account_address",
|
257
|
+
nargs="?",
|
258
|
+
default=None,
|
259
|
+
help="Substrate account address (uses keypair address if not specified)",
|
260
|
+
)
|
261
|
+
|
262
|
+
# Files command
|
263
|
+
files_parser = subparsers.add_parser(
|
264
|
+
"files", help="View files stored by you or another account"
|
265
|
+
)
|
266
|
+
files_parser.add_argument(
|
267
|
+
"--account_address",
|
268
|
+
help="Substrate account to view files for (defaults to your keyfile account)",
|
269
|
+
)
|
270
|
+
files_parser.add_argument(
|
271
|
+
"--all-miners",
|
272
|
+
action="store_true",
|
273
|
+
help="Show all miners for each file",
|
274
|
+
)
|
275
|
+
|
276
|
+
files_parser.add_argument(
|
277
|
+
"cid",
|
278
|
+
help="CID to filter on",
|
279
|
+
default=None,
|
280
|
+
nargs="?",
|
281
|
+
)
|
282
|
+
|
283
|
+
|
284
|
+
def add_erasure_coding_commands(subparsers):
|
285
|
+
"""Add erasure coding commands to the parser."""
|
286
|
+
# Erasure coded files command
|
287
|
+
ec_files_parser = subparsers.add_parser(
|
288
|
+
"ec-files", help="View erasure-coded files stored by you or another account"
|
289
|
+
)
|
290
|
+
ec_files_parser.add_argument(
|
291
|
+
"--account_address",
|
292
|
+
help="Substrate account to view EC files for (defaults to your keyfile account)",
|
293
|
+
)
|
294
|
+
ec_files_parser.add_argument(
|
295
|
+
"--all-miners",
|
296
|
+
action="store_true",
|
297
|
+
help="Show all miners for each chunk",
|
298
|
+
)
|
299
|
+
ec_files_parser.add_argument(
|
300
|
+
"--show-chunks",
|
301
|
+
action="store_true",
|
302
|
+
help="Show individual chunks for each file",
|
303
|
+
)
|
304
|
+
|
305
|
+
ec_files_parser.add_argument(
|
306
|
+
"cid",
|
307
|
+
help="CID to filter on",
|
308
|
+
default=None,
|
309
|
+
nargs="?",
|
310
|
+
)
|
311
|
+
|
312
|
+
# EC Delete command
|
313
|
+
ec_delete_parser = subparsers.add_parser(
|
314
|
+
"ec-delete", help="Delete an erasure-coded file and all its chunks"
|
315
|
+
)
|
316
|
+
ec_delete_parser.add_argument(
|
317
|
+
"metadata_cid", help="Metadata CID of the erasure-coded file to delete"
|
318
|
+
)
|
319
|
+
ec_delete_parser.add_argument(
|
320
|
+
"--force",
|
321
|
+
action="store_true",
|
322
|
+
help="Delete without confirmation prompt",
|
323
|
+
)
|
324
|
+
|
325
|
+
# Erasure code command
|
326
|
+
erasure_code_parser = subparsers.add_parser(
|
327
|
+
"erasure-code", help="Erasure code a file"
|
328
|
+
)
|
329
|
+
erasure_code_parser.add_argument("file_path", help="Path to file to erasure code")
|
330
|
+
erasure_code_parser.add_argument(
|
331
|
+
"--k",
|
332
|
+
type=int,
|
333
|
+
default=3,
|
334
|
+
help="Number of chunks needed for reconstruction (default: 3)",
|
335
|
+
)
|
336
|
+
erasure_code_parser.add_argument(
|
337
|
+
"--m",
|
338
|
+
type=int,
|
339
|
+
default=5,
|
340
|
+
help="Total number of chunks to create (default: 5)",
|
341
|
+
)
|
342
|
+
erasure_code_parser.add_argument(
|
343
|
+
"--chunk-size",
|
344
|
+
type=int,
|
345
|
+
default=10,
|
346
|
+
help="Chunk size in MB (default: 10)",
|
347
|
+
)
|
348
|
+
erasure_code_parser.add_argument(
|
349
|
+
"--no-publish",
|
350
|
+
action="store_true",
|
351
|
+
help="Don't publish to the global IPFS network",
|
352
|
+
)
|
353
|
+
|
354
|
+
# Reconstruct command
|
355
|
+
reconstruct_parser = subparsers.add_parser(
|
356
|
+
"reconstruct", help="Reconstruct an erasure-coded file"
|
357
|
+
)
|
358
|
+
reconstruct_parser.add_argument(
|
359
|
+
"metadata_cid", help="Metadata CID of the erasure-coded file"
|
360
|
+
)
|
361
|
+
reconstruct_parser.add_argument(
|
362
|
+
"output_file", help="Path to save the reconstructed file"
|
363
|
+
)
|
364
|
+
|
365
|
+
|
366
|
+
def add_config_commands(subparsers):
|
367
|
+
"""Add configuration commands to the parser."""
|
368
|
+
# Config command
|
369
|
+
config_parser = subparsers.add_parser(
|
370
|
+
"config", help="Manage Hippius SDK configuration"
|
371
|
+
)
|
372
|
+
config_subparsers = config_parser.add_subparsers(
|
373
|
+
dest="config_action", help="Configuration action"
|
374
|
+
)
|
375
|
+
|
376
|
+
# Get configuration value
|
377
|
+
get_parser = config_subparsers.add_parser("get", help="Get a configuration value")
|
378
|
+
get_parser.add_argument(
|
379
|
+
"section",
|
380
|
+
help="Configuration section (ipfs, substrate, encryption, erasure_coding, cli)",
|
381
|
+
)
|
382
|
+
get_parser.add_argument("key", help="Configuration key")
|
383
|
+
|
384
|
+
# Set configuration value
|
385
|
+
set_parser = config_subparsers.add_parser("set", help="Set a configuration value")
|
386
|
+
set_parser.add_argument(
|
387
|
+
"section",
|
388
|
+
help="Configuration section (ipfs, substrate, encryption, erasure_coding, cli)",
|
389
|
+
)
|
390
|
+
set_parser.add_argument("key", help="Configuration key")
|
391
|
+
set_parser.add_argument("value", help="Configuration value")
|
392
|
+
|
393
|
+
# List configuration
|
394
|
+
config_subparsers.add_parser("list", help="List all configuration values")
|
395
|
+
|
396
|
+
# Reset configuration to defaults
|
397
|
+
config_subparsers.add_parser("reset", help="Reset configuration to default values")
|
398
|
+
|
399
|
+
# Import config from .env
|
400
|
+
config_subparsers.add_parser(
|
401
|
+
"import-env", help="Import configuration from .env file"
|
402
|
+
)
|
403
|
+
|
404
|
+
|
405
|
+
def add_seed_commands(subparsers):
|
406
|
+
"""Add seed phrase commands to the parser."""
|
407
|
+
# Seed command
|
408
|
+
seed_parser = subparsers.add_parser("seed", help="Manage substrate seed phrase")
|
409
|
+
seed_subparsers = seed_parser.add_subparsers(
|
410
|
+
dest="seed_action", help="Seed phrase action"
|
411
|
+
)
|
412
|
+
|
413
|
+
# Set seed phrase
|
414
|
+
set_seed_parser = seed_subparsers.add_parser(
|
415
|
+
"set", help="Set the substrate seed phrase"
|
416
|
+
)
|
417
|
+
set_seed_parser.add_argument(
|
418
|
+
"seed_phrase", help="Substrate seed phrase (12 or 24 words)"
|
419
|
+
)
|
420
|
+
set_seed_parser.add_argument(
|
421
|
+
"--encode",
|
422
|
+
action="store_true",
|
423
|
+
help="Encrypt the seed phrase with a password",
|
424
|
+
)
|
425
|
+
set_seed_parser.add_argument(
|
426
|
+
"--account",
|
427
|
+
help="Account name to use (uses default if not specified)",
|
428
|
+
)
|
429
|
+
|
430
|
+
# Encode seed phrase
|
431
|
+
encode_seed_parser = seed_subparsers.add_parser(
|
432
|
+
"encode", help="Encrypt the existing seed phrase"
|
433
|
+
)
|
434
|
+
encode_seed_parser.add_argument(
|
435
|
+
"--account",
|
436
|
+
help="Account name to use (uses default if not specified)",
|
437
|
+
)
|
438
|
+
|
439
|
+
# Decode seed phrase
|
440
|
+
decode_seed_parser = seed_subparsers.add_parser(
|
441
|
+
"decode", help="Temporarily decrypt and display the seed phrase"
|
442
|
+
)
|
443
|
+
decode_seed_parser.add_argument(
|
444
|
+
"--account",
|
445
|
+
help="Account name to use (uses default if not specified)",
|
446
|
+
)
|
447
|
+
|
448
|
+
# Status seed phrase
|
449
|
+
status_seed_parser = seed_subparsers.add_parser(
|
450
|
+
"status", help="Check the status of the configured seed phrase"
|
451
|
+
)
|
452
|
+
status_seed_parser.add_argument(
|
453
|
+
"--account",
|
454
|
+
help="Account name to check (uses default if not specified)",
|
455
|
+
)
|
456
|
+
|
457
|
+
|
458
|
+
def add_account_commands(subparsers):
|
459
|
+
"""Add account management commands to the parser."""
|
460
|
+
# Account command
|
461
|
+
account_parser = subparsers.add_parser("account", help="Manage substrate accounts")
|
462
|
+
account_subparsers = account_parser.add_subparsers(
|
463
|
+
dest="account_action", help="Account action"
|
464
|
+
)
|
465
|
+
|
466
|
+
# List accounts
|
467
|
+
account_subparsers.add_parser("list", help="List all accounts")
|
468
|
+
|
469
|
+
# Create account
|
470
|
+
create_account_parser = account_subparsers.add_parser(
|
471
|
+
"create", help="Create a new account with a generated seed phrase"
|
472
|
+
)
|
473
|
+
create_account_parser.add_argument(
|
474
|
+
"--name",
|
475
|
+
required=True,
|
476
|
+
help="Name for the new account",
|
477
|
+
)
|
478
|
+
create_account_parser.add_argument(
|
479
|
+
"--encrypt",
|
480
|
+
action="store_true",
|
481
|
+
help="Encrypt the seed phrase with a password",
|
482
|
+
)
|
483
|
+
|
484
|
+
# Export account
|
485
|
+
export_account_parser = account_subparsers.add_parser(
|
486
|
+
"export", help="Export an account to a file"
|
487
|
+
)
|
488
|
+
export_account_parser.add_argument(
|
489
|
+
"--name",
|
490
|
+
help="Account name to export (uses active account if not specified)",
|
491
|
+
)
|
492
|
+
export_account_parser.add_argument(
|
493
|
+
"--file",
|
494
|
+
dest="file_path",
|
495
|
+
help="File path to export to (default: <account_name>_hippius_account.json)",
|
496
|
+
)
|
497
|
+
|
498
|
+
# Import account
|
499
|
+
import_account_parser = account_subparsers.add_parser(
|
500
|
+
"import", help="Import an account from a file"
|
501
|
+
)
|
502
|
+
import_account_parser.add_argument(
|
503
|
+
"--file",
|
504
|
+
dest="file_path",
|
505
|
+
required=True,
|
506
|
+
help="File path to import from",
|
507
|
+
)
|
508
|
+
import_account_parser.add_argument(
|
509
|
+
"--encrypt",
|
510
|
+
action="store_true",
|
511
|
+
help="Encrypt the seed phrase during import",
|
512
|
+
)
|
513
|
+
|
514
|
+
# Account info
|
515
|
+
info_account_parser = account_subparsers.add_parser(
|
516
|
+
"info", help="Display detailed information about an account"
|
517
|
+
)
|
518
|
+
info_account_parser.add_argument(
|
519
|
+
"--name",
|
520
|
+
help="Account name to show info for (uses active account if not specified)",
|
521
|
+
)
|
522
|
+
|
523
|
+
# Account balance
|
524
|
+
balance_account_parser = account_subparsers.add_parser(
|
525
|
+
"balance", help="Check account balance"
|
526
|
+
)
|
527
|
+
balance_account_parser.add_argument(
|
528
|
+
"--name",
|
529
|
+
help="Account name to check balance for (uses active account if not specified)",
|
530
|
+
)
|
531
|
+
balance_account_parser.add_argument(
|
532
|
+
"--address",
|
533
|
+
help="Substrate address to check balance for (overrides account name)",
|
534
|
+
)
|
535
|
+
|
536
|
+
# Switch account
|
537
|
+
switch_account_parser = account_subparsers.add_parser(
|
538
|
+
"switch", help="Switch to a different account"
|
539
|
+
)
|
540
|
+
switch_account_parser.add_argument(
|
541
|
+
"account_name",
|
542
|
+
help="Account name to switch to",
|
543
|
+
)
|
544
|
+
|
545
|
+
# Delete account
|
546
|
+
delete_account_parser = account_subparsers.add_parser(
|
547
|
+
"delete", help="Delete an account"
|
548
|
+
)
|
549
|
+
delete_account_parser.add_argument(
|
550
|
+
"account_name",
|
551
|
+
help="Account name to delete",
|
552
|
+
)
|
553
|
+
|
554
|
+
|
555
|
+
def add_address_commands(subparsers):
|
556
|
+
"""Add address management commands to the parser."""
|
557
|
+
# Address command
|
558
|
+
address_parser = subparsers.add_parser(
|
559
|
+
"address", help="Manage default address for read-only operations"
|
560
|
+
)
|
561
|
+
address_subparsers = address_parser.add_subparsers(
|
562
|
+
dest="address_action", help="Address action"
|
563
|
+
)
|
564
|
+
|
565
|
+
# Set default address
|
566
|
+
set_default_parser = address_subparsers.add_parser(
|
567
|
+
"set-default", help="Set the default address for read-only operations"
|
568
|
+
)
|
569
|
+
set_default_parser.add_argument(
|
570
|
+
"address",
|
571
|
+
help="Substrate account address to use as default",
|
572
|
+
)
|
573
|
+
|
574
|
+
# Get default address
|
575
|
+
address_subparsers.add_parser(
|
576
|
+
"get-default", help="Show the current default address for read-only operations"
|
577
|
+
)
|
578
|
+
|
579
|
+
# Clear default address
|
580
|
+
address_subparsers.add_parser(
|
581
|
+
"clear-default", help="Clear the default address for read-only operations"
|
582
|
+
)
|
583
|
+
|
584
|
+
|
585
|
+
def get_subparser(command: str) -> argparse.ArgumentParser:
|
586
|
+
"""Get a subparser for a specific command.
|
587
|
+
|
588
|
+
Args:
|
589
|
+
command: The command name to get the subparser for
|
590
|
+
|
591
|
+
Returns:
|
592
|
+
The subparser for the specified command
|
593
|
+
"""
|
594
|
+
parser = create_parser()
|
595
|
+
return parser._subparsers._group_actions[0].choices[command]
|
596
|
+
|
597
|
+
|
598
|
+
def parse_arguments() -> argparse.Namespace:
|
599
|
+
"""Parse command line arguments."""
|
600
|
+
parser = create_parser()
|
601
|
+
args = parser.parse_args()
|
602
|
+
return args
|