hippius 0.2.49__tar.gz → 0.2.51__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {hippius-0.2.49 → hippius-0.2.51}/PKG-INFO +1 -1
  2. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/__init__.py +1 -1
  3. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/cli.py +48 -18
  4. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/cli_handlers.py +459 -45
  5. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/cli_parser.py +182 -37
  6. {hippius-0.2.49 → hippius-0.2.51}/pyproject.toml +1 -1
  7. {hippius-0.2.49 → hippius-0.2.51}/README.md +0 -0
  8. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/cli_assets.py +0 -0
  9. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/cli_rich.py +0 -0
  10. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/client.py +0 -0
  11. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/config.py +0 -0
  12. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/db/README.md +0 -0
  13. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/db/env.db.template +0 -0
  14. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/db/migrations/20241201000001_create_key_storage_tables.sql +0 -0
  15. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/db/migrations/20241202000001_switch_to_subaccount_encryption.sql +0 -0
  16. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/db/setup_database.sh +0 -0
  17. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/db_utils.py +0 -0
  18. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/errors.py +0 -0
  19. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/incentives.py +0 -0
  20. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/ipfs.py +0 -0
  21. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/ipfs_core.py +0 -0
  22. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/key_storage.py +0 -0
  23. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/substrate.py +0 -0
  24. {hippius-0.2.49 → hippius-0.2.51}/hippius_sdk/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hippius
3
- Version: 0.2.49
3
+ Version: 0.2.51
4
4
  Summary: Python SDK and CLI for Hippius blockchain storage
5
5
  Home-page: https://github.com/thenervelab/hippius-sdk
6
6
  Author: Dubs
@@ -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.49"
29
+ __version__ = "0.2.51"
30
30
  __all__ = [
31
31
  "HippiusClient",
32
32
  "IPFSClient",
@@ -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, '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),
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, '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),
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
@@ -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"Registering node with coldkey using account: [bold cyan]{account}[/bold cyan] ({account_address})")
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, get_peer_id_from_public_key,
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
- if node_type in ["StorageMiner", "Validator"]:
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": "register_node_with_coldkey",
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
- seed_phrase = client.substrate_client._get_seed_phrase()
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 registration transaction...")
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="register_node_with_coldkey",
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 registered successfully with coldkey!")
3897
+ success(f"Node verification successful!")
3473
3898
  success(f"Transaction hash: {receipt.extrinsic_hash}")
3474
3899
  else:
3475
- error(f"Registration failed: {receipt.error_message}")
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 registering node with coldkey: {e}")
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 handle_register_hotkey(
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 register-hotkey command"""
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"Registering node with hotkey using account: [bold cyan]{account}[/bold cyan] ({account_address})")
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, get_peer_id_from_public_key,
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
- if node_type in ["StorageMiner", "Validator"]:
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": "register_node_with_hotkey",
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
- seed_phrase = client.substrate_client._get_seed_phrase()
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 registration transaction...")
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="register_node_with_hotkey",
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"Node registered successfully with hotkey!")
4083
+ success(f"Coldkey node verification successful!")
3670
4084
  success(f"Transaction hash: {receipt.extrinsic_hash}")
3671
4085
  else:
3672
- error(f"Registration failed: {receipt.error_message}")
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 registering node with hotkey: {e}")
4094
+ error(f"Error verifying coldkey node: {e}")
3681
4095
  if hasattr(e, '__traceback__'):
3682
4096
  import traceback
3683
4097
  traceback.print_exc()
@@ -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", help="Register a node with coldkey (current account becomes 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", required=True, help="Main libp2p ed25519 private key hex (32/64B)"
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", required=True,
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", help="IPFS Identity.PrivKey base64 if not using --ipfs-config"
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", type=int, default=10,
705
- help="Challenge expiration in blocks (default: 10)"
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", choices=["u32", "u64"], default="u32",
709
- help="Block number width (default: u32)"
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", default="HIPPIUS::REGISTER::v1",
713
- help="Domain for challenge (default: HIPPIUS::REGISTER::v1)"
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", action="store_true",
720
- help="Do not submit extrinsic; just print payload"
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", help="Register a node with hotkey (current account becomes 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", required=True, help="Main libp2p ed25519 private key hex (32/64B)"
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", required=True,
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(required=True)
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", help="IPFS Identity.PrivKey base64 if not using --ipfs-config"
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", type=int, default=10,
763
- help="Challenge expiration in blocks (default: 10)"
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", choices=["u32", "u64"], default="u32",
767
- help="Block number width (default: u32)"
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", default="HIPPIUS::REGISTER::v1",
771
- help="Domain for challenge (default: HIPPIUS::REGISTER::v1)"
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", action="store_true",
778
- help="Do not submit extrinsic; just print payload"
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
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "hippius"
3
- version = "0.2.49"
3
+ version = "0.2.51"
4
4
  description = "Python SDK and CLI for Hippius blockchain storage"
5
5
  authors = ["Dubs <dubs@dubs.rs>"]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes