hippius 0.2.49__py3-none-any.whl → 0.2.51__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.49.dist-info → hippius-0.2.51.dist-info}/METADATA +1 -1
- {hippius-0.2.49.dist-info → hippius-0.2.51.dist-info}/RECORD +8 -8
- hippius_sdk/__init__.py +1 -1
- hippius_sdk/cli.py +48 -18
- hippius_sdk/cli_handlers.py +459 -45
- hippius_sdk/cli_parser.py +182 -37
- {hippius-0.2.49.dist-info → hippius-0.2.51.dist-info}/WHEEL +0 -0
- {hippius-0.2.49.dist-info → hippius-0.2.51.dist-info}/entry_points.txt +0 -0
@@ -1,8 +1,8 @@
|
|
1
|
-
hippius_sdk/__init__.py,sha256=
|
2
|
-
hippius_sdk/cli.py,sha256=
|
1
|
+
hippius_sdk/__init__.py,sha256=2tr11jqNWfGOSCaZaOJgorgBqn1yv51iPXzLNJ0skHI,1474
|
2
|
+
hippius_sdk/cli.py,sha256=3TocM--b4stdOYS8_ixZMzThZvJZVmmWqEqz_PHvWxo,22188
|
3
3
|
hippius_sdk/cli_assets.py,sha256=rjH3Z5A1CQr2d5CIAAAb0WMCjoZZlMWcdo0f93KqluE,635
|
4
|
-
hippius_sdk/cli_handlers.py,sha256=
|
5
|
-
hippius_sdk/cli_parser.py,sha256=
|
4
|
+
hippius_sdk/cli_handlers.py,sha256=XuiqSuX3q4F7c6q9Cmmvq3FlL2Jfvl5a0tskZwnx-vU,157948
|
5
|
+
hippius_sdk/cli_parser.py,sha256=bg1jqQ9IXBkZVeKUAkjDWXFz67DMXs5Mzt3MXnW0lcQ,30134
|
6
6
|
hippius_sdk/cli_rich.py,sha256=_jTBYMdHi2--fIVwoeNi-EtkdOb6Zy_O2TUiGvU3O7s,7324
|
7
7
|
hippius_sdk/client.py,sha256=6W50r7-WcMyZNI1j3NOKMpcSMlB819AMKM9w06YqMx0,24302
|
8
8
|
hippius_sdk/config.py,sha256=Hf_aUYzG9ylzqauA_ABUSSB5mBTYbp-VtB36VQt2XDw,21981
|
@@ -19,7 +19,7 @@ hippius_sdk/ipfs_core.py,sha256=xsY0Ox6anmrkbrxkRr2RXzEukB-EEaW_oMvO0Va3vjQ,1314
|
|
19
19
|
hippius_sdk/key_storage.py,sha256=HWV9mM5Zkq_xxn7A72L7gvlYBtcmMwOyeFdtl8ExlmE,8315
|
20
20
|
hippius_sdk/substrate.py,sha256=4a7UIE4UqGcDW7luKTBgSDqfb2OIZusB39G1UiRs_YU,50158
|
21
21
|
hippius_sdk/utils.py,sha256=rJ611yvwKSyiBpYU3w-SuyQxoghMGU-ePuslrPv5H5g,7388
|
22
|
-
hippius-0.2.
|
23
|
-
hippius-0.2.
|
24
|
-
hippius-0.2.
|
25
|
-
hippius-0.2.
|
22
|
+
hippius-0.2.51.dist-info/METADATA,sha256=sXT-9hIotzwU8ah-xCAI4HCIMtB2YB5YGrmhPn8xm-Q,30088
|
23
|
+
hippius-0.2.51.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
24
|
+
hippius-0.2.51.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
|
25
|
+
hippius-0.2.51.dist-info/RECORD,,
|
hippius_sdk/__init__.py
CHANGED
@@ -26,7 +26,7 @@ from hippius_sdk.config import (
|
|
26
26
|
from hippius_sdk.ipfs import IPFSClient, S3PublishResult, S3DownloadResult
|
27
27
|
from hippius_sdk.utils import format_cid, format_size, hex_to_ipfs_cid
|
28
28
|
|
29
|
-
__version__ = "0.2.
|
29
|
+
__version__ = "0.2.51"
|
30
30
|
__all__ = [
|
31
31
|
"HippiusClient",
|
32
32
|
"IPFSClient",
|
hippius_sdk/cli.py
CHANGED
@@ -418,15 +418,15 @@ def main():
|
|
418
418
|
args.node_id,
|
419
419
|
args.node_priv_hex,
|
420
420
|
args.node_type,
|
421
|
-
ipfs_config=getattr(args,
|
422
|
-
ipfs_priv_b64=getattr(args,
|
423
|
-
ipfs_peer_id=getattr(args,
|
424
|
-
pay_in_credits=getattr(args,
|
425
|
-
expires_in=getattr(args,
|
426
|
-
block_width=getattr(args,
|
427
|
-
domain=getattr(args,
|
428
|
-
nonce_hex=getattr(args,
|
429
|
-
dry_run=getattr(args,
|
421
|
+
ipfs_config=getattr(args, "ipfs_config", None),
|
422
|
+
ipfs_priv_b64=getattr(args, "ipfs_priv_b64", None),
|
423
|
+
ipfs_peer_id=getattr(args, "ipfs_peer_id", None),
|
424
|
+
pay_in_credits=getattr(args, "pay_in_credits", False),
|
425
|
+
expires_in=getattr(args, "expires_in", 10),
|
426
|
+
block_width=getattr(args, "block_width", "u32"),
|
427
|
+
domain=getattr(args, "domain", "HIPPIUS::REGISTER::v1"),
|
428
|
+
nonce_hex=getattr(args, "nonce_hex", None),
|
429
|
+
dry_run=getattr(args, "dry_run", False),
|
430
430
|
)
|
431
431
|
elif args.miner_action == "register-hotkey":
|
432
432
|
return run_async_handler(
|
@@ -436,15 +436,45 @@ def main():
|
|
436
436
|
args.node_id,
|
437
437
|
args.node_priv_hex,
|
438
438
|
args.node_type,
|
439
|
-
ipfs_config=getattr(args,
|
440
|
-
ipfs_priv_b64=getattr(args,
|
441
|
-
ipfs_peer_id=getattr(args,
|
442
|
-
pay_in_credits=getattr(args,
|
443
|
-
expires_in=getattr(args,
|
444
|
-
block_width=getattr(args,
|
445
|
-
domain=getattr(args,
|
446
|
-
nonce_hex=getattr(args,
|
447
|
-
dry_run=getattr(args,
|
439
|
+
ipfs_config=getattr(args, "ipfs_config", None),
|
440
|
+
ipfs_priv_b64=getattr(args, "ipfs_priv_b64", None),
|
441
|
+
ipfs_peer_id=getattr(args, "ipfs_peer_id", None),
|
442
|
+
pay_in_credits=getattr(args, "pay_in_credits", False),
|
443
|
+
expires_in=getattr(args, "expires_in", 10),
|
444
|
+
block_width=getattr(args, "block_width", "u32"),
|
445
|
+
domain=getattr(args, "domain", "HIPPIUS::REGISTER::v1"),
|
446
|
+
nonce_hex=getattr(args, "nonce_hex", None),
|
447
|
+
dry_run=getattr(args, "dry_run", False),
|
448
|
+
)
|
449
|
+
elif args.miner_action == "verify-node":
|
450
|
+
return run_async_handler(
|
451
|
+
cli_handlers.handle_verify_node,
|
452
|
+
client,
|
453
|
+
args.node_id,
|
454
|
+
args.node_priv_hex,
|
455
|
+
ipfs_config=getattr(args, "ipfs_config", None),
|
456
|
+
ipfs_priv_b64=getattr(args, "ipfs_priv_b64", None),
|
457
|
+
ipfs_peer_id=getattr(args, "ipfs_peer_id", None),
|
458
|
+
expires_in=getattr(args, "expires_in", 10),
|
459
|
+
block_width=getattr(args, "block_width", "u32"),
|
460
|
+
domain=getattr(args, "domain", "HIPPIUS::REGISTER::v1"),
|
461
|
+
nonce_hex=getattr(args, "nonce_hex", None),
|
462
|
+
dry_run=getattr(args, "dry_run", False),
|
463
|
+
)
|
464
|
+
elif args.miner_action == "verify-coldkey-node":
|
465
|
+
return run_async_handler(
|
466
|
+
cli_handlers.handle_verify_coldkey_node,
|
467
|
+
client,
|
468
|
+
args.node_id,
|
469
|
+
args.node_priv_hex,
|
470
|
+
ipfs_config=getattr(args, "ipfs_config", None),
|
471
|
+
ipfs_priv_b64=getattr(args, "ipfs_priv_b64", None),
|
472
|
+
ipfs_peer_id=getattr(args, "ipfs_peer_id", None),
|
473
|
+
expires_in=getattr(args, "expires_in", 10),
|
474
|
+
block_width=getattr(args, "block_width", "u32"),
|
475
|
+
domain=getattr(args, "domain", "HIPPIUS::REGISTER::v1"),
|
476
|
+
nonce_hex=getattr(args, "nonce_hex", None),
|
477
|
+
dry_run=getattr(args, "dry_run", False),
|
448
478
|
)
|
449
479
|
else:
|
450
480
|
# Display the Hippius logo banner with Rich formatting
|
hippius_sdk/cli_handlers.py
CHANGED
@@ -3309,6 +3309,437 @@ def handle_register_coldkey(
|
|
3309
3309
|
dry_run: bool = False,
|
3310
3310
|
) -> int:
|
3311
3311
|
"""Handle miner register-coldkey command"""
|
3312
|
+
try:
|
3313
|
+
# Get current account info
|
3314
|
+
account = get_active_account()
|
3315
|
+
if not account:
|
3316
|
+
error(
|
3317
|
+
"No active account. Please set up an account first with 'hippius account create' or 'hippius seed set'"
|
3318
|
+
)
|
3319
|
+
return 1
|
3320
|
+
|
3321
|
+
account_address = get_account_address(account)
|
3322
|
+
if not account_address:
|
3323
|
+
error(f"Could not get address for account '{account}'")
|
3324
|
+
return 1
|
3325
|
+
|
3326
|
+
info(
|
3327
|
+
f"Registering node with coldkey using account: [bold cyan]{account}[/bold cyan] ({account_address})"
|
3328
|
+
)
|
3329
|
+
|
3330
|
+
# Import and use incentives.py functionality
|
3331
|
+
from hippius_sdk.incentives import (
|
3332
|
+
load_ipfs_seed,
|
3333
|
+
load_main_seed,
|
3334
|
+
encode_account_id,
|
3335
|
+
verify_peer_id,
|
3336
|
+
blake2_256,
|
3337
|
+
manual_encode_challenge,
|
3338
|
+
get_peer_id_from_public_key,
|
3339
|
+
get_public_key_from_peer_id,
|
3340
|
+
)
|
3341
|
+
from substrateinterface import SubstrateInterface, Keypair
|
3342
|
+
from nacl.signing import SigningKey
|
3343
|
+
import base58
|
3344
|
+
import secrets
|
3345
|
+
from binascii import hexlify
|
3346
|
+
|
3347
|
+
# Initialize SubstrateInterface
|
3348
|
+
substrate = SubstrateInterface(url=client.substrate_client.url)
|
3349
|
+
|
3350
|
+
# Get genesis hash and current block
|
3351
|
+
genesis_hash_hex = substrate.get_block_hash(0)
|
3352
|
+
genesis_hash = bytes.fromhex(genesis_hash_hex[2:])
|
3353
|
+
current_block_number = substrate.get_block_number(None)
|
3354
|
+
|
3355
|
+
log(f"Current block number: {current_block_number}")
|
3356
|
+
|
3357
|
+
# Process node_id
|
3358
|
+
if node_id.startswith("0x"):
|
3359
|
+
node_id_bytes = bytes.fromhex(node_id[2:])
|
3360
|
+
else:
|
3361
|
+
node_id_bytes = base58.b58decode(node_id)
|
3362
|
+
|
3363
|
+
# Load IPFS and main seeds
|
3364
|
+
ipfs_seed, peerid_from_config = load_ipfs_seed(ipfs_config, ipfs_priv_b64)
|
3365
|
+
main_seed = load_main_seed(node_priv_hex)
|
3366
|
+
|
3367
|
+
# Create signing keys
|
3368
|
+
main_sk = SigningKey(main_seed)
|
3369
|
+
main_pk = bytes(main_sk.verify_key)
|
3370
|
+
ipfs_sk = SigningKey(ipfs_seed)
|
3371
|
+
ipfs_pk = bytes(ipfs_sk.verify_key)
|
3372
|
+
|
3373
|
+
# Handle IPFS peer ID
|
3374
|
+
if ipfs_peer_id:
|
3375
|
+
ipfs_peer_id_bytes = base58.b58decode(ipfs_peer_id)
|
3376
|
+
elif peerid_from_config:
|
3377
|
+
ipfs_peer_id_bytes = base58.b58decode(peerid_from_config)
|
3378
|
+
else:
|
3379
|
+
if node_type in ["StorageMiner", "Validator"]:
|
3380
|
+
error(
|
3381
|
+
"IPFS PeerID is required for StorageMiner and Validator node types"
|
3382
|
+
)
|
3383
|
+
return 1
|
3384
|
+
ipfs_peer_id_bytes = b""
|
3385
|
+
|
3386
|
+
# Verify keys match node IDs
|
3387
|
+
if not verify_peer_id(main_pk, node_id_bytes, "Ed25519"):
|
3388
|
+
error("Main public key does not match node ID")
|
3389
|
+
return 1
|
3390
|
+
|
3391
|
+
if ipfs_peer_id_bytes and not verify_peer_id(
|
3392
|
+
ipfs_pk, ipfs_peer_id_bytes, "Ed25519"
|
3393
|
+
):
|
3394
|
+
error("IPFS public key does not match peer ID")
|
3395
|
+
return 1
|
3396
|
+
|
3397
|
+
# Create challenge data
|
3398
|
+
domain_bytes = domain.encode()
|
3399
|
+
domain24 = b"HIPPIUS::REGISTER::v1" + b"\x00" * 3
|
3400
|
+
node_id_hash = blake2_256(node_id_bytes)
|
3401
|
+
ipfs_peer_id_hash = blake2_256(ipfs_peer_id_bytes)
|
3402
|
+
|
3403
|
+
nonce = (
|
3404
|
+
bytes.fromhex(nonce_hex[2:])
|
3405
|
+
if nonce_hex and nonce_hex.startswith("0x")
|
3406
|
+
else bytes.fromhex(nonce_hex)
|
3407
|
+
if nonce_hex
|
3408
|
+
else secrets.token_bytes(32)
|
3409
|
+
)
|
3410
|
+
|
3411
|
+
expires_at_block = current_block_number + expires_in
|
3412
|
+
account_bytes = encode_account_id(account_address)
|
3413
|
+
|
3414
|
+
challenge_data = {
|
3415
|
+
"domain": domain24,
|
3416
|
+
"genesis_hash": genesis_hash,
|
3417
|
+
"account": account_bytes,
|
3418
|
+
"node_id_hash": node_id_hash,
|
3419
|
+
"ipfs_peer_id_hash": ipfs_peer_id_hash,
|
3420
|
+
"block_number": current_block_number,
|
3421
|
+
"nonce": nonce,
|
3422
|
+
"expires_at": expires_at_block,
|
3423
|
+
}
|
3424
|
+
|
3425
|
+
challenge_bytes = manual_encode_challenge(challenge_data, block_width)
|
3426
|
+
|
3427
|
+
# Sign challenge
|
3428
|
+
main_sig = main_sk.sign(challenge_bytes).signature
|
3429
|
+
ipfs_sig = ipfs_sk.sign(challenge_bytes).signature
|
3430
|
+
|
3431
|
+
# Build call parameters
|
3432
|
+
call_params = {
|
3433
|
+
"node_type": node_type,
|
3434
|
+
"node_id": node_id,
|
3435
|
+
"node_id_hex": "0x" + hexlify(node_id_bytes).decode(),
|
3436
|
+
"pay_in_credits": pay_in_credits,
|
3437
|
+
"ipfs_node_id": ipfs_peer_id,
|
3438
|
+
"owner": account_address,
|
3439
|
+
"ipfs_peer_id": ipfs_peer_id,
|
3440
|
+
"ipfs_id_hex": "0x" + hexlify(ipfs_peer_id_bytes).decode(),
|
3441
|
+
"main_key_type": "Ed25519",
|
3442
|
+
"main_public_key": "0x" + main_pk.hex(),
|
3443
|
+
"main_sig": "0x" + main_sig.hex(),
|
3444
|
+
"ipfs_key_type": "Ed25519",
|
3445
|
+
"ipfs_public_key": "0x" + ipfs_pk.hex(),
|
3446
|
+
"ipfs_sig": "0x" + ipfs_sig.hex(),
|
3447
|
+
"challenge_bytes": "0x" + challenge_bytes.hex(),
|
3448
|
+
}
|
3449
|
+
|
3450
|
+
if dry_run:
|
3451
|
+
log("Dry run mode - printing payload without submitting")
|
3452
|
+
payload = {
|
3453
|
+
"genesis_hash_hex": "0x" + genesis_hash.hex(),
|
3454
|
+
"current_block_number": current_block_number,
|
3455
|
+
"challenge_bytes_hex": "0x" + challenge_bytes.hex(),
|
3456
|
+
"call_module": "Registration",
|
3457
|
+
"call_function": "register_node_with_coldkey",
|
3458
|
+
"call_params": call_params,
|
3459
|
+
}
|
3460
|
+
console.print(json.dumps(payload, indent=2))
|
3461
|
+
return 0
|
3462
|
+
|
3463
|
+
# Get keypair for signing
|
3464
|
+
from hippius_sdk.config import get_seed_phrase
|
3465
|
+
|
3466
|
+
seed_phrase = get_seed_phrase()
|
3467
|
+
if not seed_phrase:
|
3468
|
+
error("No seed phrase available for signing transaction")
|
3469
|
+
return 1
|
3470
|
+
|
3471
|
+
kp = Keypair.create_from_uri(seed_phrase)
|
3472
|
+
|
3473
|
+
# Submit transaction
|
3474
|
+
log("Submitting registration transaction...")
|
3475
|
+
log(f"Using module: [bold cyan]Registration[/bold cyan]")
|
3476
|
+
call = substrate.compose_call(
|
3477
|
+
call_module="Registration",
|
3478
|
+
call_function="register_node_with_coldkey",
|
3479
|
+
call_params=call_params,
|
3480
|
+
)
|
3481
|
+
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=kp)
|
3482
|
+
receipt = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True)
|
3483
|
+
|
3484
|
+
result = {
|
3485
|
+
"extrinsic_hash": receipt.extrinsic_hash,
|
3486
|
+
"is_success": receipt.is_success,
|
3487
|
+
"error_message": receipt.error_message,
|
3488
|
+
"triggered_events": [str(event) for event in receipt.triggered_events],
|
3489
|
+
}
|
3490
|
+
|
3491
|
+
if receipt.is_success:
|
3492
|
+
success(f"Node registered successfully with coldkey!")
|
3493
|
+
success(f"Transaction hash: {receipt.extrinsic_hash}")
|
3494
|
+
else:
|
3495
|
+
error(f"Registration failed: {receipt.error_message}")
|
3496
|
+
|
3497
|
+
log("Full result:")
|
3498
|
+
console.print(json.dumps(result, indent=2))
|
3499
|
+
|
3500
|
+
return 0 if receipt.is_success else 1
|
3501
|
+
|
3502
|
+
except Exception as e:
|
3503
|
+
error(f"Error registering node with coldkey: {e}")
|
3504
|
+
if hasattr(e, "__traceback__"):
|
3505
|
+
import traceback
|
3506
|
+
|
3507
|
+
traceback.print_exc()
|
3508
|
+
return 1
|
3509
|
+
|
3510
|
+
|
3511
|
+
def handle_register_hotkey(
|
3512
|
+
client: HippiusClient,
|
3513
|
+
coldkey: str,
|
3514
|
+
node_id: str,
|
3515
|
+
node_priv_hex: str,
|
3516
|
+
node_type: str,
|
3517
|
+
ipfs_config: str = None,
|
3518
|
+
ipfs_priv_b64: str = None,
|
3519
|
+
ipfs_peer_id: str = None,
|
3520
|
+
pay_in_credits: bool = False,
|
3521
|
+
expires_in: int = 10,
|
3522
|
+
block_width: str = "u32",
|
3523
|
+
domain: str = "HIPPIUS::REGISTER::v1",
|
3524
|
+
nonce_hex: str = None,
|
3525
|
+
dry_run: bool = False,
|
3526
|
+
) -> int:
|
3527
|
+
"""Handle miner register-hotkey command"""
|
3528
|
+
try:
|
3529
|
+
# Get current account info
|
3530
|
+
account = get_active_account()
|
3531
|
+
if not account:
|
3532
|
+
error(
|
3533
|
+
"No active account. Please set up an account first with 'hippius account create' or 'hippius seed set'"
|
3534
|
+
)
|
3535
|
+
return 1
|
3536
|
+
|
3537
|
+
account_address = get_account_address(account)
|
3538
|
+
if not account_address:
|
3539
|
+
error(f"Could not get address for account '{account}'")
|
3540
|
+
return 1
|
3541
|
+
|
3542
|
+
info(
|
3543
|
+
f"Registering node with hotkey using account: [bold cyan]{account}[/bold cyan] ({account_address})"
|
3544
|
+
)
|
3545
|
+
info(f"Coldkey: [bold yellow]{coldkey}[/bold yellow]")
|
3546
|
+
|
3547
|
+
# Import and use incentives.py functionality
|
3548
|
+
from hippius_sdk.incentives import (
|
3549
|
+
load_ipfs_seed,
|
3550
|
+
load_main_seed,
|
3551
|
+
encode_account_id,
|
3552
|
+
verify_peer_id,
|
3553
|
+
blake2_256,
|
3554
|
+
manual_encode_challenge,
|
3555
|
+
get_peer_id_from_public_key,
|
3556
|
+
get_public_key_from_peer_id,
|
3557
|
+
)
|
3558
|
+
from substrateinterface import SubstrateInterface, Keypair
|
3559
|
+
from nacl.signing import SigningKey
|
3560
|
+
import base58
|
3561
|
+
import secrets
|
3562
|
+
from binascii import hexlify
|
3563
|
+
|
3564
|
+
# Initialize SubstrateInterface
|
3565
|
+
substrate = SubstrateInterface(url=client.substrate_client.url)
|
3566
|
+
|
3567
|
+
# Get genesis hash and current block
|
3568
|
+
genesis_hash_hex = substrate.get_block_hash(0)
|
3569
|
+
genesis_hash = bytes.fromhex(genesis_hash_hex[2:])
|
3570
|
+
current_block_number = substrate.get_block_number(None)
|
3571
|
+
|
3572
|
+
log(f"Current block number: {current_block_number}")
|
3573
|
+
|
3574
|
+
# Process node_id
|
3575
|
+
if node_id.startswith("0x"):
|
3576
|
+
node_id_bytes = bytes.fromhex(node_id[2:])
|
3577
|
+
else:
|
3578
|
+
node_id_bytes = base58.b58decode(node_id)
|
3579
|
+
|
3580
|
+
# Load IPFS and main seeds
|
3581
|
+
ipfs_seed, peerid_from_config = load_ipfs_seed(ipfs_config, ipfs_priv_b64)
|
3582
|
+
main_seed = load_main_seed(node_priv_hex)
|
3583
|
+
|
3584
|
+
# Create signing keys
|
3585
|
+
main_sk = SigningKey(main_seed)
|
3586
|
+
main_pk = bytes(main_sk.verify_key)
|
3587
|
+
ipfs_sk = SigningKey(ipfs_seed)
|
3588
|
+
ipfs_pk = bytes(ipfs_sk.verify_key)
|
3589
|
+
|
3590
|
+
# Handle IPFS peer ID
|
3591
|
+
if ipfs_peer_id:
|
3592
|
+
ipfs_peer_id_bytes = base58.b58decode(ipfs_peer_id)
|
3593
|
+
elif peerid_from_config:
|
3594
|
+
ipfs_peer_id_bytes = base58.b58decode(peerid_from_config)
|
3595
|
+
else:
|
3596
|
+
if node_type in ["StorageMiner", "Validator"]:
|
3597
|
+
error(
|
3598
|
+
"IPFS PeerID is required for StorageMiner and Validator node types"
|
3599
|
+
)
|
3600
|
+
return 1
|
3601
|
+
ipfs_peer_id_bytes = b""
|
3602
|
+
|
3603
|
+
# Verify keys match node IDs
|
3604
|
+
if not verify_peer_id(main_pk, node_id_bytes, "Ed25519"):
|
3605
|
+
error("Main public key does not match node ID")
|
3606
|
+
return 1
|
3607
|
+
|
3608
|
+
if ipfs_peer_id_bytes and not verify_peer_id(
|
3609
|
+
ipfs_pk, ipfs_peer_id_bytes, "Ed25519"
|
3610
|
+
):
|
3611
|
+
error("IPFS public key does not match peer ID")
|
3612
|
+
return 1
|
3613
|
+
|
3614
|
+
# Create challenge data
|
3615
|
+
domain_bytes = domain.encode()
|
3616
|
+
domain24 = b"HIPPIUS::REGISTER::v1" + b"\x00" * 3
|
3617
|
+
node_id_hash = blake2_256(node_id_bytes)
|
3618
|
+
ipfs_peer_id_hash = blake2_256(ipfs_peer_id_bytes)
|
3619
|
+
|
3620
|
+
nonce = (
|
3621
|
+
bytes.fromhex(nonce_hex[2:])
|
3622
|
+
if nonce_hex and nonce_hex.startswith("0x")
|
3623
|
+
else bytes.fromhex(nonce_hex)
|
3624
|
+
if nonce_hex
|
3625
|
+
else secrets.token_bytes(32)
|
3626
|
+
)
|
3627
|
+
|
3628
|
+
expires_at_block = current_block_number + expires_in
|
3629
|
+
account_bytes = encode_account_id(account_address)
|
3630
|
+
|
3631
|
+
challenge_data = {
|
3632
|
+
"domain": domain24,
|
3633
|
+
"genesis_hash": genesis_hash,
|
3634
|
+
"account": account_bytes,
|
3635
|
+
"node_id_hash": node_id_hash,
|
3636
|
+
"ipfs_peer_id_hash": ipfs_peer_id_hash,
|
3637
|
+
"block_number": current_block_number,
|
3638
|
+
"nonce": nonce,
|
3639
|
+
"expires_at": expires_at_block,
|
3640
|
+
}
|
3641
|
+
|
3642
|
+
challenge_bytes = manual_encode_challenge(challenge_data, block_width)
|
3643
|
+
|
3644
|
+
# Sign challenge
|
3645
|
+
main_sig = main_sk.sign(challenge_bytes).signature
|
3646
|
+
ipfs_sig = ipfs_sk.sign(challenge_bytes).signature
|
3647
|
+
|
3648
|
+
# Build call parameters
|
3649
|
+
call_params = {
|
3650
|
+
"coldkey": coldkey,
|
3651
|
+
"node_type": node_type,
|
3652
|
+
"node_id": node_id,
|
3653
|
+
"node_id_hex": "0x" + hexlify(node_id_bytes).decode(),
|
3654
|
+
"pay_in_credits": pay_in_credits,
|
3655
|
+
"ipfs_node_id": ipfs_peer_id,
|
3656
|
+
"ipfs_peer_id": ipfs_peer_id,
|
3657
|
+
"ipfs_id_hex": "0x" + hexlify(ipfs_peer_id_bytes).decode(),
|
3658
|
+
"owner": account_address,
|
3659
|
+
"main_key_type": "Ed25519",
|
3660
|
+
"main_public_key": "0x" + main_pk.hex(),
|
3661
|
+
"main_sig": "0x" + main_sig.hex(),
|
3662
|
+
"ipfs_key_type": "Ed25519",
|
3663
|
+
"ipfs_public_key": "0x" + ipfs_pk.hex(),
|
3664
|
+
"ipfs_sig": "0x" + ipfs_sig.hex(),
|
3665
|
+
"challenge_bytes": "0x" + challenge_bytes.hex(),
|
3666
|
+
}
|
3667
|
+
|
3668
|
+
if dry_run:
|
3669
|
+
log("Dry run mode - printing payload without submitting")
|
3670
|
+
payload = {
|
3671
|
+
"genesis_hash_hex": "0x" + genesis_hash.hex(),
|
3672
|
+
"current_block_number": current_block_number,
|
3673
|
+
"challenge_bytes_hex": "0x" + challenge_bytes.hex(),
|
3674
|
+
"call_module": "Registration",
|
3675
|
+
"call_function": "register_node_with_hotkey",
|
3676
|
+
"call_params": call_params,
|
3677
|
+
}
|
3678
|
+
console.print(json.dumps(payload, indent=2))
|
3679
|
+
return 0
|
3680
|
+
|
3681
|
+
# Get keypair for signing
|
3682
|
+
from hippius_sdk.config import get_seed_phrase
|
3683
|
+
|
3684
|
+
seed_phrase = get_seed_phrase()
|
3685
|
+
if not seed_phrase:
|
3686
|
+
error("No seed phrase available for signing transaction")
|
3687
|
+
return 1
|
3688
|
+
|
3689
|
+
kp = Keypair.create_from_uri(seed_phrase)
|
3690
|
+
|
3691
|
+
# Submit transaction
|
3692
|
+
log("Submitting registration transaction...")
|
3693
|
+
log(f"Using module: [bold cyan]Registration[/bold cyan]")
|
3694
|
+
call = substrate.compose_call(
|
3695
|
+
call_module="Registration",
|
3696
|
+
call_function="register_node_with_hotkey",
|
3697
|
+
call_params=call_params,
|
3698
|
+
)
|
3699
|
+
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=kp)
|
3700
|
+
receipt = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True)
|
3701
|
+
|
3702
|
+
result = {
|
3703
|
+
"extrinsic_hash": receipt.extrinsic_hash,
|
3704
|
+
"is_success": receipt.is_success,
|
3705
|
+
"error_message": receipt.error_message,
|
3706
|
+
"triggered_events": [str(event) for event in receipt.triggered_events],
|
3707
|
+
}
|
3708
|
+
|
3709
|
+
if receipt.is_success:
|
3710
|
+
success(f"Node registered successfully with hotkey!")
|
3711
|
+
success(f"Transaction hash: {receipt.extrinsic_hash}")
|
3712
|
+
else:
|
3713
|
+
error(f"Registration failed: {receipt.error_message}")
|
3714
|
+
|
3715
|
+
log("Full result:")
|
3716
|
+
console.print(json.dumps(result, indent=2))
|
3717
|
+
|
3718
|
+
return 0 if receipt.is_success else 1
|
3719
|
+
|
3720
|
+
except Exception as e:
|
3721
|
+
error(f"Error registering node with hotkey: {e}")
|
3722
|
+
if hasattr(e, "__traceback__"):
|
3723
|
+
import traceback
|
3724
|
+
|
3725
|
+
traceback.print_exc()
|
3726
|
+
return 1
|
3727
|
+
|
3728
|
+
|
3729
|
+
def handle_verify_node(
|
3730
|
+
client: HippiusClient,
|
3731
|
+
node_id: str,
|
3732
|
+
node_priv_hex: str,
|
3733
|
+
ipfs_config: str = None,
|
3734
|
+
ipfs_priv_b64: str = None,
|
3735
|
+
ipfs_peer_id: str = None,
|
3736
|
+
expires_in: int = 10,
|
3737
|
+
block_width: str = "u32",
|
3738
|
+
domain: str = "HIPPIUS::REGISTER::v1",
|
3739
|
+
nonce_hex: str = None,
|
3740
|
+
dry_run: bool = False,
|
3741
|
+
) -> int:
|
3742
|
+
"""Handle miner verify-node command"""
|
3312
3743
|
try:
|
3313
3744
|
# Get current account info
|
3314
3745
|
account = get_active_account()
|
@@ -3321,13 +3752,12 @@ def handle_register_coldkey(
|
|
3321
3752
|
error(f"Could not get address for account '{account}'")
|
3322
3753
|
return 1
|
3323
3754
|
|
3324
|
-
info(f"
|
3755
|
+
info(f"Verifying existing node using account: [bold cyan]{account}[/bold cyan] ({account_address})")
|
3325
3756
|
|
3326
3757
|
# Import and use incentives.py functionality
|
3327
3758
|
from hippius_sdk.incentives import (
|
3328
3759
|
load_ipfs_seed, load_main_seed, encode_account_id, verify_peer_id,
|
3329
|
-
blake2_256, manual_encode_challenge
|
3330
|
-
get_public_key_from_peer_id
|
3760
|
+
blake2_256, manual_encode_challenge
|
3331
3761
|
)
|
3332
3762
|
from substrateinterface import SubstrateInterface, Keypair
|
3333
3763
|
from nacl.signing import SigningKey
|
@@ -3367,9 +3797,7 @@ def handle_register_coldkey(
|
|
3367
3797
|
elif peerid_from_config:
|
3368
3798
|
ipfs_peer_id_bytes = base58.b58decode(peerid_from_config)
|
3369
3799
|
else:
|
3370
|
-
|
3371
|
-
error("IPFS PeerID is required for StorageMiner and Validator node types")
|
3372
|
-
return 1
|
3800
|
+
# For verification, IPFS peer ID might not be required for all node types
|
3373
3801
|
ipfs_peer_id_bytes = b''
|
3374
3802
|
|
3375
3803
|
# Verify keys match node IDs
|
@@ -3411,15 +3839,10 @@ def handle_register_coldkey(
|
|
3411
3839
|
main_sig = main_sk.sign(challenge_bytes).signature
|
3412
3840
|
ipfs_sig = ipfs_sk.sign(challenge_bytes).signature
|
3413
3841
|
|
3414
|
-
# Build call parameters
|
3842
|
+
# Build call parameters for verify_existing_node
|
3415
3843
|
call_params = {
|
3416
|
-
"node_type": node_type,
|
3417
3844
|
"node_id": node_id,
|
3418
3845
|
"node_id_hex": "0x"+hexlify(node_id_bytes).decode(),
|
3419
|
-
"pay_in_credits": pay_in_credits,
|
3420
|
-
"ipfs_node_id": ipfs_peer_id,
|
3421
|
-
"owner": account_address,
|
3422
|
-
"ipfs_peer_id": ipfs_peer_id,
|
3423
3846
|
"ipfs_id_hex": "0x"+hexlify(ipfs_peer_id_bytes).decode(),
|
3424
3847
|
"main_key_type": "Ed25519",
|
3425
3848
|
"main_public_key": "0x"+main_pk.hex(),
|
@@ -3437,14 +3860,15 @@ def handle_register_coldkey(
|
|
3437
3860
|
"current_block_number": current_block_number,
|
3438
3861
|
"challenge_bytes_hex": "0x"+challenge_bytes.hex(),
|
3439
3862
|
"call_module": "Registration",
|
3440
|
-
"call_function": "
|
3863
|
+
"call_function": "verify_existing_node",
|
3441
3864
|
"call_params": call_params
|
3442
3865
|
}
|
3443
3866
|
console.print(json.dumps(payload, indent=2))
|
3444
3867
|
return 0
|
3445
3868
|
|
3446
3869
|
# Get keypair for signing
|
3447
|
-
|
3870
|
+
from hippius_sdk.config import get_seed_phrase
|
3871
|
+
seed_phrase = get_seed_phrase()
|
3448
3872
|
if not seed_phrase:
|
3449
3873
|
error("No seed phrase available for signing transaction")
|
3450
3874
|
return 1
|
@@ -3452,10 +3876,11 @@ def handle_register_coldkey(
|
|
3452
3876
|
kp = Keypair.create_from_uri(seed_phrase)
|
3453
3877
|
|
3454
3878
|
# Submit transaction
|
3455
|
-
log("Submitting
|
3879
|
+
log("Submitting node verification transaction...")
|
3880
|
+
log(f"Using module: [bold cyan]Registration[/bold cyan]")
|
3456
3881
|
call = substrate.compose_call(
|
3457
3882
|
call_module="Registration",
|
3458
|
-
call_function="
|
3883
|
+
call_function="verify_existing_node",
|
3459
3884
|
call_params=call_params
|
3460
3885
|
)
|
3461
3886
|
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=kp)
|
@@ -3469,10 +3894,10 @@ def handle_register_coldkey(
|
|
3469
3894
|
}
|
3470
3895
|
|
3471
3896
|
if receipt.is_success:
|
3472
|
-
success(f"Node
|
3897
|
+
success(f"Node verification successful!")
|
3473
3898
|
success(f"Transaction hash: {receipt.extrinsic_hash}")
|
3474
3899
|
else:
|
3475
|
-
error(f"
|
3900
|
+
error(f"Node verification failed: {receipt.error_message}")
|
3476
3901
|
|
3477
3902
|
log("Full result:")
|
3478
3903
|
console.print(json.dumps(result, indent=2))
|
@@ -3480,30 +3905,27 @@ def handle_register_coldkey(
|
|
3480
3905
|
return 0 if receipt.is_success else 1
|
3481
3906
|
|
3482
3907
|
except Exception as e:
|
3483
|
-
error(f"Error
|
3908
|
+
error(f"Error verifying node: {e}")
|
3484
3909
|
if hasattr(e, '__traceback__'):
|
3485
3910
|
import traceback
|
3486
3911
|
traceback.print_exc()
|
3487
3912
|
return 1
|
3488
3913
|
|
3489
3914
|
|
3490
|
-
def
|
3915
|
+
def handle_verify_coldkey_node(
|
3491
3916
|
client: HippiusClient,
|
3492
|
-
coldkey: str,
|
3493
3917
|
node_id: str,
|
3494
3918
|
node_priv_hex: str,
|
3495
|
-
node_type: str,
|
3496
3919
|
ipfs_config: str = None,
|
3497
3920
|
ipfs_priv_b64: str = None,
|
3498
3921
|
ipfs_peer_id: str = None,
|
3499
|
-
pay_in_credits: bool = False,
|
3500
3922
|
expires_in: int = 10,
|
3501
3923
|
block_width: str = "u32",
|
3502
3924
|
domain: str = "HIPPIUS::REGISTER::v1",
|
3503
3925
|
nonce_hex: str = None,
|
3504
3926
|
dry_run: bool = False,
|
3505
3927
|
) -> int:
|
3506
|
-
"""Handle miner
|
3928
|
+
"""Handle miner verify-coldkey-node command"""
|
3507
3929
|
try:
|
3508
3930
|
# Get current account info
|
3509
3931
|
account = get_active_account()
|
@@ -3516,14 +3938,12 @@ def handle_register_hotkey(
|
|
3516
3938
|
error(f"Could not get address for account '{account}'")
|
3517
3939
|
return 1
|
3518
3940
|
|
3519
|
-
info(f"
|
3520
|
-
info(f"Coldkey: [bold yellow]{coldkey}[/bold yellow]")
|
3941
|
+
info(f"Verifying existing coldkey node using account: [bold cyan]{account}[/bold cyan] ({account_address})")
|
3521
3942
|
|
3522
3943
|
# Import and use incentives.py functionality
|
3523
3944
|
from hippius_sdk.incentives import (
|
3524
3945
|
load_ipfs_seed, load_main_seed, encode_account_id, verify_peer_id,
|
3525
|
-
blake2_256, manual_encode_challenge
|
3526
|
-
get_public_key_from_peer_id
|
3946
|
+
blake2_256, manual_encode_challenge
|
3527
3947
|
)
|
3528
3948
|
from substrateinterface import SubstrateInterface, Keypair
|
3529
3949
|
from nacl.signing import SigningKey
|
@@ -3563,9 +3983,7 @@ def handle_register_hotkey(
|
|
3563
3983
|
elif peerid_from_config:
|
3564
3984
|
ipfs_peer_id_bytes = base58.b58decode(peerid_from_config)
|
3565
3985
|
else:
|
3566
|
-
|
3567
|
-
error("IPFS PeerID is required for StorageMiner and Validator node types")
|
3568
|
-
return 1
|
3986
|
+
# For verification, IPFS peer ID might not be required for all node types
|
3569
3987
|
ipfs_peer_id_bytes = b''
|
3570
3988
|
|
3571
3989
|
# Verify keys match node IDs
|
@@ -3607,17 +4025,11 @@ def handle_register_hotkey(
|
|
3607
4025
|
main_sig = main_sk.sign(challenge_bytes).signature
|
3608
4026
|
ipfs_sig = ipfs_sk.sign(challenge_bytes).signature
|
3609
4027
|
|
3610
|
-
# Build call parameters
|
4028
|
+
# Build call parameters for verify_existing_coldkey_node
|
3611
4029
|
call_params = {
|
3612
|
-
"coldkey": coldkey,
|
3613
|
-
"node_type": node_type,
|
3614
4030
|
"node_id": node_id,
|
3615
4031
|
"node_id_hex": "0x"+hexlify(node_id_bytes).decode(),
|
3616
|
-
"pay_in_credits": pay_in_credits,
|
3617
|
-
"ipfs_node_id": ipfs_peer_id,
|
3618
|
-
"ipfs_peer_id": ipfs_peer_id,
|
3619
4032
|
"ipfs_id_hex": "0x"+hexlify(ipfs_peer_id_bytes).decode(),
|
3620
|
-
"owner": account_address,
|
3621
4033
|
"main_key_type": "Ed25519",
|
3622
4034
|
"main_public_key": "0x"+main_pk.hex(),
|
3623
4035
|
"main_sig": "0x"+main_sig.hex(),
|
@@ -3634,14 +4046,15 @@ def handle_register_hotkey(
|
|
3634
4046
|
"current_block_number": current_block_number,
|
3635
4047
|
"challenge_bytes_hex": "0x"+challenge_bytes.hex(),
|
3636
4048
|
"call_module": "Registration",
|
3637
|
-
"call_function": "
|
4049
|
+
"call_function": "verify_existing_coldkey_node",
|
3638
4050
|
"call_params": call_params
|
3639
4051
|
}
|
3640
4052
|
console.print(json.dumps(payload, indent=2))
|
3641
4053
|
return 0
|
3642
4054
|
|
3643
4055
|
# Get keypair for signing
|
3644
|
-
|
4056
|
+
from hippius_sdk.config import get_seed_phrase
|
4057
|
+
seed_phrase = get_seed_phrase()
|
3645
4058
|
if not seed_phrase:
|
3646
4059
|
error("No seed phrase available for signing transaction")
|
3647
4060
|
return 1
|
@@ -3649,10 +4062,11 @@ def handle_register_hotkey(
|
|
3649
4062
|
kp = Keypair.create_from_uri(seed_phrase)
|
3650
4063
|
|
3651
4064
|
# Submit transaction
|
3652
|
-
log("Submitting
|
4065
|
+
log("Submitting coldkey node verification transaction...")
|
4066
|
+
log(f"Using module: [bold cyan]Registration[/bold cyan]")
|
3653
4067
|
call = substrate.compose_call(
|
3654
4068
|
call_module="Registration",
|
3655
|
-
call_function="
|
4069
|
+
call_function="verify_existing_coldkey_node",
|
3656
4070
|
call_params=call_params
|
3657
4071
|
)
|
3658
4072
|
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=kp)
|
@@ -3666,10 +4080,10 @@ def handle_register_hotkey(
|
|
3666
4080
|
}
|
3667
4081
|
|
3668
4082
|
if receipt.is_success:
|
3669
|
-
success(f"
|
4083
|
+
success(f"Coldkey node verification successful!")
|
3670
4084
|
success(f"Transaction hash: {receipt.extrinsic_hash}")
|
3671
4085
|
else:
|
3672
|
-
error(f"
|
4086
|
+
error(f"Coldkey node verification failed: {receipt.error_message}")
|
3673
4087
|
|
3674
4088
|
log("Full result:")
|
3675
4089
|
console.print(json.dumps(result, indent=2))
|
@@ -3677,7 +4091,7 @@ def handle_register_hotkey(
|
|
3677
4091
|
return 0 if receipt.is_success else 1
|
3678
4092
|
|
3679
4093
|
except Exception as e:
|
3680
|
-
error(f"Error
|
4094
|
+
error(f"Error verifying coldkey node: {e}")
|
3681
4095
|
if hasattr(e, '__traceback__'):
|
3682
4096
|
import traceback
|
3683
4097
|
traceback.print_exc()
|
hippius_sdk/cli_parser.py
CHANGED
@@ -667,64 +667,75 @@ def add_miner_commands(subparsers):
|
|
667
667
|
|
668
668
|
# Register coldkey command
|
669
669
|
register_coldkey_parser = miner_subparsers.add_parser(
|
670
|
-
"register-coldkey",
|
670
|
+
"register-coldkey",
|
671
|
+
help="Register a node with coldkey (current account becomes coldkey)",
|
671
672
|
)
|
672
|
-
|
673
|
+
|
673
674
|
# Required arguments for register-coldkey
|
674
675
|
register_coldkey_parser.add_argument(
|
675
676
|
"--node-id", required=True, help="Your main node_id (libp2p peer ID)"
|
676
677
|
)
|
677
678
|
register_coldkey_parser.add_argument(
|
678
|
-
"--node-priv-hex",
|
679
|
+
"--node-priv-hex",
|
680
|
+
required=True,
|
681
|
+
help="Main libp2p ed25519 private key hex (32/64B)",
|
679
682
|
)
|
680
683
|
register_coldkey_parser.add_argument(
|
681
|
-
"--node-type",
|
684
|
+
"--node-type",
|
685
|
+
required=True,
|
682
686
|
choices=["StorageMiner", "Validator", "ComputeMiner", "StorageS3", "GpuMiner"],
|
683
|
-
help="Type of miner node"
|
687
|
+
help="Type of miner node",
|
684
688
|
)
|
685
|
-
|
689
|
+
|
686
690
|
# IPFS configuration (one required)
|
687
691
|
ipfs_group = register_coldkey_parser.add_mutually_exclusive_group(required=True)
|
688
692
|
ipfs_group.add_argument(
|
689
693
|
"--ipfs-config", help="Path to IPFS config file (e.g. ~/.ipfs/config)"
|
690
694
|
)
|
691
695
|
ipfs_group.add_argument(
|
692
|
-
"--ipfs-priv-b64",
|
696
|
+
"--ipfs-priv-b64",
|
697
|
+
help="IPFS Identity.PrivKey base64 if not using --ipfs-config",
|
693
698
|
)
|
694
|
-
|
699
|
+
|
695
700
|
# Optional arguments
|
696
701
|
register_coldkey_parser.add_argument(
|
697
702
|
"--ipfs-peer-id", help="Optional override IPFS PeerID"
|
698
703
|
)
|
699
704
|
register_coldkey_parser.add_argument(
|
700
|
-
"--pay-in-credits", action="store_true",
|
701
|
-
help="Pay in credits for registration"
|
705
|
+
"--pay-in-credits", action="store_true", help="Pay in credits for registration"
|
702
706
|
)
|
703
707
|
register_coldkey_parser.add_argument(
|
704
|
-
"--expires-in",
|
705
|
-
|
708
|
+
"--expires-in",
|
709
|
+
type=int,
|
710
|
+
default=10,
|
711
|
+
help="Challenge expiration in blocks (default: 10)",
|
706
712
|
)
|
707
713
|
register_coldkey_parser.add_argument(
|
708
|
-
"--block-width",
|
709
|
-
|
714
|
+
"--block-width",
|
715
|
+
choices=["u32", "u64"],
|
716
|
+
default="u32",
|
717
|
+
help="Block number width (default: u32)",
|
710
718
|
)
|
711
719
|
register_coldkey_parser.add_argument(
|
712
|
-
"--domain",
|
713
|
-
|
720
|
+
"--domain",
|
721
|
+
default="HIPPIUS::REGISTER::v1",
|
722
|
+
help="Domain for challenge (default: HIPPIUS::REGISTER::v1)",
|
714
723
|
)
|
715
724
|
register_coldkey_parser.add_argument(
|
716
725
|
"--nonce-hex", help="32-byte hex nonce (optional, random if not provided)"
|
717
726
|
)
|
718
727
|
register_coldkey_parser.add_argument(
|
719
|
-
"--dry-run",
|
720
|
-
|
728
|
+
"--dry-run",
|
729
|
+
action="store_true",
|
730
|
+
help="Do not submit extrinsic; just print payload",
|
721
731
|
)
|
722
732
|
|
723
733
|
# Register hotkey command
|
724
734
|
register_hotkey_parser = miner_subparsers.add_parser(
|
725
|
-
"register-hotkey",
|
735
|
+
"register-hotkey",
|
736
|
+
help="Register a node with hotkey (current account becomes hotkey)",
|
726
737
|
)
|
727
|
-
|
738
|
+
|
728
739
|
# Required arguments for register-hotkey
|
729
740
|
register_hotkey_parser.add_argument(
|
730
741
|
"--coldkey", required=True, help="Coldkey SS58 address"
|
@@ -733,49 +744,183 @@ def add_miner_commands(subparsers):
|
|
733
744
|
"--node-id", required=True, help="Your main node_id (libp2p peer ID)"
|
734
745
|
)
|
735
746
|
register_hotkey_parser.add_argument(
|
736
|
-
"--node-priv-hex",
|
747
|
+
"--node-priv-hex",
|
748
|
+
required=True,
|
749
|
+
help="Main libp2p ed25519 private key hex (32/64B)",
|
737
750
|
)
|
738
751
|
register_hotkey_parser.add_argument(
|
739
|
-
"--node-type",
|
752
|
+
"--node-type",
|
753
|
+
required=True,
|
740
754
|
choices=["StorageMiner", "Validator", "ComputeMiner", "StorageS3", "GpuMiner"],
|
741
|
-
help="Type of miner node"
|
755
|
+
help="Type of miner node",
|
742
756
|
)
|
743
|
-
|
757
|
+
|
744
758
|
# IPFS configuration (one required)
|
745
|
-
ipfs_group_hotkey = register_hotkey_parser.add_mutually_exclusive_group(
|
759
|
+
ipfs_group_hotkey = register_hotkey_parser.add_mutually_exclusive_group(
|
760
|
+
required=True
|
761
|
+
)
|
746
762
|
ipfs_group_hotkey.add_argument(
|
747
763
|
"--ipfs-config", help="Path to IPFS config file (e.g. ~/.ipfs/config)"
|
748
764
|
)
|
749
765
|
ipfs_group_hotkey.add_argument(
|
750
|
-
"--ipfs-priv-b64",
|
766
|
+
"--ipfs-priv-b64",
|
767
|
+
help="IPFS Identity.PrivKey base64 if not using --ipfs-config",
|
751
768
|
)
|
752
|
-
|
769
|
+
|
753
770
|
# Optional arguments
|
754
771
|
register_hotkey_parser.add_argument(
|
755
772
|
"--ipfs-peer-id", help="Optional override IPFS PeerID"
|
756
773
|
)
|
757
774
|
register_hotkey_parser.add_argument(
|
758
|
-
"--pay-in-credits", action="store_true",
|
759
|
-
help="Pay in credits for registration"
|
775
|
+
"--pay-in-credits", action="store_true", help="Pay in credits for registration"
|
760
776
|
)
|
761
777
|
register_hotkey_parser.add_argument(
|
762
|
-
"--expires-in",
|
763
|
-
|
778
|
+
"--expires-in",
|
779
|
+
type=int,
|
780
|
+
default=10,
|
781
|
+
help="Challenge expiration in blocks (default: 10)",
|
764
782
|
)
|
765
783
|
register_hotkey_parser.add_argument(
|
766
|
-
"--block-width",
|
767
|
-
|
784
|
+
"--block-width",
|
785
|
+
choices=["u32", "u64"],
|
786
|
+
default="u32",
|
787
|
+
help="Block number width (default: u32)",
|
768
788
|
)
|
769
789
|
register_hotkey_parser.add_argument(
|
770
|
-
"--domain",
|
771
|
-
|
790
|
+
"--domain",
|
791
|
+
default="HIPPIUS::REGISTER::v1",
|
792
|
+
help="Domain for challenge (default: HIPPIUS::REGISTER::v1)",
|
772
793
|
)
|
773
794
|
register_hotkey_parser.add_argument(
|
774
795
|
"--nonce-hex", help="32-byte hex nonce (optional, random if not provided)"
|
775
796
|
)
|
776
797
|
register_hotkey_parser.add_argument(
|
777
|
-
"--dry-run",
|
778
|
-
|
798
|
+
"--dry-run",
|
799
|
+
action="store_true",
|
800
|
+
help="Do not submit extrinsic; just print payload",
|
801
|
+
)
|
802
|
+
|
803
|
+
# Verify node command
|
804
|
+
verify_node_parser = miner_subparsers.add_parser(
|
805
|
+
"verify-node", help="Verify an existing registered node (proves key ownership)"
|
806
|
+
)
|
807
|
+
|
808
|
+
# Required arguments for verify-node
|
809
|
+
verify_node_parser.add_argument(
|
810
|
+
"--node-id", required=True, help="Your main node_id (libp2p peer ID)"
|
811
|
+
)
|
812
|
+
verify_node_parser.add_argument(
|
813
|
+
"--node-priv-hex",
|
814
|
+
required=True,
|
815
|
+
help="Main libp2p ed25519 private key hex (32/64B)",
|
816
|
+
)
|
817
|
+
|
818
|
+
# IPFS configuration (one required)
|
819
|
+
ipfs_group_verify = verify_node_parser.add_mutually_exclusive_group(required=True)
|
820
|
+
ipfs_group_verify.add_argument(
|
821
|
+
"--ipfs-config", help="Path to IPFS config file (e.g. ~/.ipfs/config)"
|
822
|
+
)
|
823
|
+
ipfs_group_verify.add_argument(
|
824
|
+
"--ipfs-priv-b64",
|
825
|
+
help="IPFS Identity.PrivKey base64 if not using --ipfs-config",
|
826
|
+
)
|
827
|
+
|
828
|
+
# Optional arguments
|
829
|
+
verify_node_parser.add_argument(
|
830
|
+
"--ipfs-peer-id", help="Optional override IPFS PeerID"
|
831
|
+
)
|
832
|
+
verify_node_parser.add_argument(
|
833
|
+
"--expires-in",
|
834
|
+
type=int,
|
835
|
+
default=10,
|
836
|
+
help="Challenge expiration in blocks (default: 10)",
|
837
|
+
)
|
838
|
+
verify_node_parser.add_argument(
|
839
|
+
"--block-width",
|
840
|
+
choices=["u32", "u64"],
|
841
|
+
default="u32",
|
842
|
+
help="Block number width (default: u32)",
|
843
|
+
)
|
844
|
+
verify_node_parser.add_argument(
|
845
|
+
"--domain",
|
846
|
+
default="HIPPIUS::REGISTER::v1",
|
847
|
+
help="Domain for challenge (default: HIPPIUS::REGISTER::v1)",
|
848
|
+
)
|
849
|
+
verify_node_parser.add_argument(
|
850
|
+
"--nonce-hex", help="32-byte hex nonce (optional, random if not provided)"
|
851
|
+
)
|
852
|
+
verify_node_parser.add_argument(
|
853
|
+
"--module",
|
854
|
+
default="Registration",
|
855
|
+
help="Blockchain pallet/module name (default: Registration)",
|
856
|
+
)
|
857
|
+
verify_node_parser.add_argument(
|
858
|
+
"--dry-run",
|
859
|
+
action="store_true",
|
860
|
+
help="Do not submit extrinsic; just print payload",
|
861
|
+
)
|
862
|
+
|
863
|
+
# Verify coldkey node command
|
864
|
+
verify_coldkey_node_parser = miner_subparsers.add_parser(
|
865
|
+
"verify-coldkey-node",
|
866
|
+
help="Verify an existing coldkey-registered node (proves key ownership)",
|
867
|
+
)
|
868
|
+
|
869
|
+
# Required arguments for verify-coldkey-node
|
870
|
+
verify_coldkey_node_parser.add_argument(
|
871
|
+
"--node-id", required=True, help="Your main node_id (libp2p peer ID)"
|
872
|
+
)
|
873
|
+
verify_coldkey_node_parser.add_argument(
|
874
|
+
"--node-priv-hex",
|
875
|
+
required=True,
|
876
|
+
help="Main libp2p ed25519 private key hex (32/64B)",
|
877
|
+
)
|
878
|
+
|
879
|
+
# IPFS configuration (one required)
|
880
|
+
ipfs_group_verify_coldkey = verify_coldkey_node_parser.add_mutually_exclusive_group(
|
881
|
+
required=True
|
882
|
+
)
|
883
|
+
ipfs_group_verify_coldkey.add_argument(
|
884
|
+
"--ipfs-config", help="Path to IPFS config file (e.g. ~/.ipfs/config)"
|
885
|
+
)
|
886
|
+
ipfs_group_verify_coldkey.add_argument(
|
887
|
+
"--ipfs-priv-b64",
|
888
|
+
help="IPFS Identity.PrivKey base64 if not using --ipfs-config",
|
889
|
+
)
|
890
|
+
|
891
|
+
# Optional arguments
|
892
|
+
verify_coldkey_node_parser.add_argument(
|
893
|
+
"--ipfs-peer-id", help="Optional override IPFS PeerID"
|
894
|
+
)
|
895
|
+
verify_coldkey_node_parser.add_argument(
|
896
|
+
"--expires-in",
|
897
|
+
type=int,
|
898
|
+
default=10,
|
899
|
+
help="Challenge expiration in blocks (default: 10)",
|
900
|
+
)
|
901
|
+
verify_coldkey_node_parser.add_argument(
|
902
|
+
"--block-width",
|
903
|
+
choices=["u32", "u64"],
|
904
|
+
default="u32",
|
905
|
+
help="Block number width (default: u32)",
|
906
|
+
)
|
907
|
+
verify_coldkey_node_parser.add_argument(
|
908
|
+
"--domain",
|
909
|
+
default="HIPPIUS::REGISTER::v1",
|
910
|
+
help="Domain for challenge (default: HIPPIUS::REGISTER::v1)",
|
911
|
+
)
|
912
|
+
verify_coldkey_node_parser.add_argument(
|
913
|
+
"--nonce-hex", help="32-byte hex nonce (optional, random if not provided)"
|
914
|
+
)
|
915
|
+
verify_coldkey_node_parser.add_argument(
|
916
|
+
"--module",
|
917
|
+
default="Registration",
|
918
|
+
help="Blockchain pallet/module name (default: Registration)",
|
919
|
+
)
|
920
|
+
verify_coldkey_node_parser.add_argument(
|
921
|
+
"--dry-run",
|
922
|
+
action="store_true",
|
923
|
+
help="Do not submit extrinsic; just print payload",
|
779
924
|
)
|
780
925
|
|
781
926
|
|
File without changes
|
File without changes
|