hippius 0.2.50__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.50 → hippius-0.2.51}/PKG-INFO +1 -1
  2. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/__init__.py +1 -1
  3. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/cli.py +30 -0
  4. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/cli_handlers.py +376 -0
  5. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/cli_parser.py +123 -0
  6. {hippius-0.2.50 → hippius-0.2.51}/pyproject.toml +1 -1
  7. {hippius-0.2.50 → hippius-0.2.51}/README.md +0 -0
  8. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/cli_assets.py +0 -0
  9. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/cli_rich.py +0 -0
  10. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/client.py +0 -0
  11. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/config.py +0 -0
  12. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/db/README.md +0 -0
  13. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/db/env.db.template +0 -0
  14. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/db/migrations/20241201000001_create_key_storage_tables.sql +0 -0
  15. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/db/migrations/20241202000001_switch_to_subaccount_encryption.sql +0 -0
  16. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/db/setup_database.sh +0 -0
  17. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/db_utils.py +0 -0
  18. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/errors.py +0 -0
  19. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/incentives.py +0 -0
  20. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/ipfs.py +0 -0
  21. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/ipfs_core.py +0 -0
  22. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/key_storage.py +0 -0
  23. {hippius-0.2.50 → hippius-0.2.51}/hippius_sdk/substrate.py +0 -0
  24. {hippius-0.2.50 → 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.50
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.50"
29
+ __version__ = "0.2.51"
30
30
  __all__ = [
31
31
  "HippiusClient",
32
32
  "IPFSClient",
@@ -446,6 +446,36 @@ def main():
446
446
  nonce_hex=getattr(args, "nonce_hex", None),
447
447
  dry_run=getattr(args, "dry_run", False),
448
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),
478
+ )
449
479
  else:
450
480
  # Display the Hippius logo banner with Rich formatting
451
481
  console.print(HERO_TITLE, style="bold cyan")
@@ -3462,6 +3462,7 @@ def handle_register_coldkey(
3462
3462
 
3463
3463
  # Get keypair for signing
3464
3464
  from hippius_sdk.config import get_seed_phrase
3465
+
3465
3466
  seed_phrase = get_seed_phrase()
3466
3467
  if not seed_phrase:
3467
3468
  error("No seed phrase available for signing transaction")
@@ -3471,6 +3472,7 @@ def handle_register_coldkey(
3471
3472
 
3472
3473
  # Submit transaction
3473
3474
  log("Submitting registration transaction...")
3475
+ log(f"Using module: [bold cyan]Registration[/bold cyan]")
3474
3476
  call = substrate.compose_call(
3475
3477
  call_module="Registration",
3476
3478
  call_function="register_node_with_coldkey",
@@ -3678,6 +3680,7 @@ def handle_register_hotkey(
3678
3680
 
3679
3681
  # Get keypair for signing
3680
3682
  from hippius_sdk.config import get_seed_phrase
3683
+
3681
3684
  seed_phrase = get_seed_phrase()
3682
3685
  if not seed_phrase:
3683
3686
  error("No seed phrase available for signing transaction")
@@ -3687,6 +3690,7 @@ def handle_register_hotkey(
3687
3690
 
3688
3691
  # Submit transaction
3689
3692
  log("Submitting registration transaction...")
3693
+ log(f"Using module: [bold cyan]Registration[/bold cyan]")
3690
3694
  call = substrate.compose_call(
3691
3695
  call_module="Registration",
3692
3696
  call_function="register_node_with_hotkey",
@@ -3720,3 +3724,375 @@ def handle_register_hotkey(
3720
3724
 
3721
3725
  traceback.print_exc()
3722
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"""
3743
+ try:
3744
+ # Get current account info
3745
+ account = get_active_account()
3746
+ if not account:
3747
+ error("No active account. Please set up an account first with 'hippius account create' or 'hippius seed set'")
3748
+ return 1
3749
+
3750
+ account_address = get_account_address(account)
3751
+ if not account_address:
3752
+ error(f"Could not get address for account '{account}'")
3753
+ return 1
3754
+
3755
+ info(f"Verifying existing node using account: [bold cyan]{account}[/bold cyan] ({account_address})")
3756
+
3757
+ # Import and use incentives.py functionality
3758
+ from hippius_sdk.incentives import (
3759
+ load_ipfs_seed, load_main_seed, encode_account_id, verify_peer_id,
3760
+ blake2_256, manual_encode_challenge
3761
+ )
3762
+ from substrateinterface import SubstrateInterface, Keypair
3763
+ from nacl.signing import SigningKey
3764
+ import base58
3765
+ import secrets
3766
+ from binascii import hexlify
3767
+
3768
+ # Initialize SubstrateInterface
3769
+ substrate = SubstrateInterface(url=client.substrate_client.url)
3770
+
3771
+ # Get genesis hash and current block
3772
+ genesis_hash_hex = substrate.get_block_hash(0)
3773
+ genesis_hash = bytes.fromhex(genesis_hash_hex[2:])
3774
+ current_block_number = substrate.get_block_number(None)
3775
+
3776
+ log(f"Current block number: {current_block_number}")
3777
+
3778
+ # Process node_id
3779
+ if node_id.startswith("0x"):
3780
+ node_id_bytes = bytes.fromhex(node_id[2:])
3781
+ else:
3782
+ node_id_bytes = base58.b58decode(node_id)
3783
+
3784
+ # Load IPFS and main seeds
3785
+ ipfs_seed, peerid_from_config = load_ipfs_seed(ipfs_config, ipfs_priv_b64)
3786
+ main_seed = load_main_seed(node_priv_hex)
3787
+
3788
+ # Create signing keys
3789
+ main_sk = SigningKey(main_seed)
3790
+ main_pk = bytes(main_sk.verify_key)
3791
+ ipfs_sk = SigningKey(ipfs_seed)
3792
+ ipfs_pk = bytes(ipfs_sk.verify_key)
3793
+
3794
+ # Handle IPFS peer ID
3795
+ if ipfs_peer_id:
3796
+ ipfs_peer_id_bytes = base58.b58decode(ipfs_peer_id)
3797
+ elif peerid_from_config:
3798
+ ipfs_peer_id_bytes = base58.b58decode(peerid_from_config)
3799
+ else:
3800
+ # For verification, IPFS peer ID might not be required for all node types
3801
+ ipfs_peer_id_bytes = b''
3802
+
3803
+ # Verify keys match node IDs
3804
+ if not verify_peer_id(main_pk, node_id_bytes, "Ed25519"):
3805
+ error("Main public key does not match node ID")
3806
+ return 1
3807
+
3808
+ if ipfs_peer_id_bytes and not verify_peer_id(ipfs_pk, ipfs_peer_id_bytes, "Ed25519"):
3809
+ error("IPFS public key does not match peer ID")
3810
+ return 1
3811
+
3812
+ # Create challenge data
3813
+ domain_bytes = domain.encode()
3814
+ domain24 = b"HIPPIUS::REGISTER::v1" + b"\x00"*3
3815
+ node_id_hash = blake2_256(node_id_bytes)
3816
+ ipfs_peer_id_hash = blake2_256(ipfs_peer_id_bytes)
3817
+
3818
+ nonce = (bytes.fromhex(nonce_hex[2:]) if nonce_hex and nonce_hex.startswith("0x")
3819
+ else bytes.fromhex(nonce_hex) if nonce_hex
3820
+ else secrets.token_bytes(32))
3821
+
3822
+ expires_at_block = current_block_number + expires_in
3823
+ account_bytes = encode_account_id(account_address)
3824
+
3825
+ challenge_data = {
3826
+ 'domain': domain24,
3827
+ 'genesis_hash': genesis_hash,
3828
+ 'account': account_bytes,
3829
+ 'node_id_hash': node_id_hash,
3830
+ 'ipfs_peer_id_hash': ipfs_peer_id_hash,
3831
+ 'block_number': current_block_number,
3832
+ 'nonce': nonce,
3833
+ 'expires_at': expires_at_block,
3834
+ }
3835
+
3836
+ challenge_bytes = manual_encode_challenge(challenge_data, block_width)
3837
+
3838
+ # Sign challenge
3839
+ main_sig = main_sk.sign(challenge_bytes).signature
3840
+ ipfs_sig = ipfs_sk.sign(challenge_bytes).signature
3841
+
3842
+ # Build call parameters for verify_existing_node
3843
+ call_params = {
3844
+ "node_id": node_id,
3845
+ "node_id_hex": "0x"+hexlify(node_id_bytes).decode(),
3846
+ "ipfs_id_hex": "0x"+hexlify(ipfs_peer_id_bytes).decode(),
3847
+ "main_key_type": "Ed25519",
3848
+ "main_public_key": "0x"+main_pk.hex(),
3849
+ "main_sig": "0x"+main_sig.hex(),
3850
+ "ipfs_key_type": "Ed25519",
3851
+ "ipfs_public_key": "0x"+ipfs_pk.hex(),
3852
+ "ipfs_sig": "0x"+ipfs_sig.hex(),
3853
+ "challenge_bytes": "0x"+challenge_bytes.hex(),
3854
+ }
3855
+
3856
+ if dry_run:
3857
+ log("Dry run mode - printing payload without submitting")
3858
+ payload = {
3859
+ "genesis_hash_hex": "0x"+genesis_hash.hex(),
3860
+ "current_block_number": current_block_number,
3861
+ "challenge_bytes_hex": "0x"+challenge_bytes.hex(),
3862
+ "call_module": "Registration",
3863
+ "call_function": "verify_existing_node",
3864
+ "call_params": call_params
3865
+ }
3866
+ console.print(json.dumps(payload, indent=2))
3867
+ return 0
3868
+
3869
+ # Get keypair for signing
3870
+ from hippius_sdk.config import get_seed_phrase
3871
+ seed_phrase = get_seed_phrase()
3872
+ if not seed_phrase:
3873
+ error("No seed phrase available for signing transaction")
3874
+ return 1
3875
+
3876
+ kp = Keypair.create_from_uri(seed_phrase)
3877
+
3878
+ # Submit transaction
3879
+ log("Submitting node verification transaction...")
3880
+ log(f"Using module: [bold cyan]Registration[/bold cyan]")
3881
+ call = substrate.compose_call(
3882
+ call_module="Registration",
3883
+ call_function="verify_existing_node",
3884
+ call_params=call_params
3885
+ )
3886
+ extrinsic = substrate.create_signed_extrinsic(call=call, keypair=kp)
3887
+ receipt = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True)
3888
+
3889
+ result = {
3890
+ "extrinsic_hash": receipt.extrinsic_hash,
3891
+ "is_success": receipt.is_success,
3892
+ "error_message": receipt.error_message,
3893
+ "triggered_events": [str(event) for event in receipt.triggered_events]
3894
+ }
3895
+
3896
+ if receipt.is_success:
3897
+ success(f"Node verification successful!")
3898
+ success(f"Transaction hash: {receipt.extrinsic_hash}")
3899
+ else:
3900
+ error(f"Node verification failed: {receipt.error_message}")
3901
+
3902
+ log("Full result:")
3903
+ console.print(json.dumps(result, indent=2))
3904
+
3905
+ return 0 if receipt.is_success else 1
3906
+
3907
+ except Exception as e:
3908
+ error(f"Error verifying node: {e}")
3909
+ if hasattr(e, '__traceback__'):
3910
+ import traceback
3911
+ traceback.print_exc()
3912
+ return 1
3913
+
3914
+
3915
+ def handle_verify_coldkey_node(
3916
+ client: HippiusClient,
3917
+ node_id: str,
3918
+ node_priv_hex: str,
3919
+ ipfs_config: str = None,
3920
+ ipfs_priv_b64: str = None,
3921
+ ipfs_peer_id: str = None,
3922
+ expires_in: int = 10,
3923
+ block_width: str = "u32",
3924
+ domain: str = "HIPPIUS::REGISTER::v1",
3925
+ nonce_hex: str = None,
3926
+ dry_run: bool = False,
3927
+ ) -> int:
3928
+ """Handle miner verify-coldkey-node command"""
3929
+ try:
3930
+ # Get current account info
3931
+ account = get_active_account()
3932
+ if not account:
3933
+ error("No active account. Please set up an account first with 'hippius account create' or 'hippius seed set'")
3934
+ return 1
3935
+
3936
+ account_address = get_account_address(account)
3937
+ if not account_address:
3938
+ error(f"Could not get address for account '{account}'")
3939
+ return 1
3940
+
3941
+ info(f"Verifying existing coldkey node using account: [bold cyan]{account}[/bold cyan] ({account_address})")
3942
+
3943
+ # Import and use incentives.py functionality
3944
+ from hippius_sdk.incentives import (
3945
+ load_ipfs_seed, load_main_seed, encode_account_id, verify_peer_id,
3946
+ blake2_256, manual_encode_challenge
3947
+ )
3948
+ from substrateinterface import SubstrateInterface, Keypair
3949
+ from nacl.signing import SigningKey
3950
+ import base58
3951
+ import secrets
3952
+ from binascii import hexlify
3953
+
3954
+ # Initialize SubstrateInterface
3955
+ substrate = SubstrateInterface(url=client.substrate_client.url)
3956
+
3957
+ # Get genesis hash and current block
3958
+ genesis_hash_hex = substrate.get_block_hash(0)
3959
+ genesis_hash = bytes.fromhex(genesis_hash_hex[2:])
3960
+ current_block_number = substrate.get_block_number(None)
3961
+
3962
+ log(f"Current block number: {current_block_number}")
3963
+
3964
+ # Process node_id
3965
+ if node_id.startswith("0x"):
3966
+ node_id_bytes = bytes.fromhex(node_id[2:])
3967
+ else:
3968
+ node_id_bytes = base58.b58decode(node_id)
3969
+
3970
+ # Load IPFS and main seeds
3971
+ ipfs_seed, peerid_from_config = load_ipfs_seed(ipfs_config, ipfs_priv_b64)
3972
+ main_seed = load_main_seed(node_priv_hex)
3973
+
3974
+ # Create signing keys
3975
+ main_sk = SigningKey(main_seed)
3976
+ main_pk = bytes(main_sk.verify_key)
3977
+ ipfs_sk = SigningKey(ipfs_seed)
3978
+ ipfs_pk = bytes(ipfs_sk.verify_key)
3979
+
3980
+ # Handle IPFS peer ID
3981
+ if ipfs_peer_id:
3982
+ ipfs_peer_id_bytes = base58.b58decode(ipfs_peer_id)
3983
+ elif peerid_from_config:
3984
+ ipfs_peer_id_bytes = base58.b58decode(peerid_from_config)
3985
+ else:
3986
+ # For verification, IPFS peer ID might not be required for all node types
3987
+ ipfs_peer_id_bytes = b''
3988
+
3989
+ # Verify keys match node IDs
3990
+ if not verify_peer_id(main_pk, node_id_bytes, "Ed25519"):
3991
+ error("Main public key does not match node ID")
3992
+ return 1
3993
+
3994
+ if ipfs_peer_id_bytes and not verify_peer_id(ipfs_pk, ipfs_peer_id_bytes, "Ed25519"):
3995
+ error("IPFS public key does not match peer ID")
3996
+ return 1
3997
+
3998
+ # Create challenge data
3999
+ domain_bytes = domain.encode()
4000
+ domain24 = b"HIPPIUS::REGISTER::v1" + b"\x00"*3
4001
+ node_id_hash = blake2_256(node_id_bytes)
4002
+ ipfs_peer_id_hash = blake2_256(ipfs_peer_id_bytes)
4003
+
4004
+ nonce = (bytes.fromhex(nonce_hex[2:]) if nonce_hex and nonce_hex.startswith("0x")
4005
+ else bytes.fromhex(nonce_hex) if nonce_hex
4006
+ else secrets.token_bytes(32))
4007
+
4008
+ expires_at_block = current_block_number + expires_in
4009
+ account_bytes = encode_account_id(account_address)
4010
+
4011
+ challenge_data = {
4012
+ 'domain': domain24,
4013
+ 'genesis_hash': genesis_hash,
4014
+ 'account': account_bytes,
4015
+ 'node_id_hash': node_id_hash,
4016
+ 'ipfs_peer_id_hash': ipfs_peer_id_hash,
4017
+ 'block_number': current_block_number,
4018
+ 'nonce': nonce,
4019
+ 'expires_at': expires_at_block,
4020
+ }
4021
+
4022
+ challenge_bytes = manual_encode_challenge(challenge_data, block_width)
4023
+
4024
+ # Sign challenge
4025
+ main_sig = main_sk.sign(challenge_bytes).signature
4026
+ ipfs_sig = ipfs_sk.sign(challenge_bytes).signature
4027
+
4028
+ # Build call parameters for verify_existing_coldkey_node
4029
+ call_params = {
4030
+ "node_id": node_id,
4031
+ "node_id_hex": "0x"+hexlify(node_id_bytes).decode(),
4032
+ "ipfs_id_hex": "0x"+hexlify(ipfs_peer_id_bytes).decode(),
4033
+ "main_key_type": "Ed25519",
4034
+ "main_public_key": "0x"+main_pk.hex(),
4035
+ "main_sig": "0x"+main_sig.hex(),
4036
+ "ipfs_key_type": "Ed25519",
4037
+ "ipfs_public_key": "0x"+ipfs_pk.hex(),
4038
+ "ipfs_sig": "0x"+ipfs_sig.hex(),
4039
+ "challenge_bytes": "0x"+challenge_bytes.hex(),
4040
+ }
4041
+
4042
+ if dry_run:
4043
+ log("Dry run mode - printing payload without submitting")
4044
+ payload = {
4045
+ "genesis_hash_hex": "0x"+genesis_hash.hex(),
4046
+ "current_block_number": current_block_number,
4047
+ "challenge_bytes_hex": "0x"+challenge_bytes.hex(),
4048
+ "call_module": "Registration",
4049
+ "call_function": "verify_existing_coldkey_node",
4050
+ "call_params": call_params
4051
+ }
4052
+ console.print(json.dumps(payload, indent=2))
4053
+ return 0
4054
+
4055
+ # Get keypair for signing
4056
+ from hippius_sdk.config import get_seed_phrase
4057
+ seed_phrase = get_seed_phrase()
4058
+ if not seed_phrase:
4059
+ error("No seed phrase available for signing transaction")
4060
+ return 1
4061
+
4062
+ kp = Keypair.create_from_uri(seed_phrase)
4063
+
4064
+ # Submit transaction
4065
+ log("Submitting coldkey node verification transaction...")
4066
+ log(f"Using module: [bold cyan]Registration[/bold cyan]")
4067
+ call = substrate.compose_call(
4068
+ call_module="Registration",
4069
+ call_function="verify_existing_coldkey_node",
4070
+ call_params=call_params
4071
+ )
4072
+ extrinsic = substrate.create_signed_extrinsic(call=call, keypair=kp)
4073
+ receipt = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True)
4074
+
4075
+ result = {
4076
+ "extrinsic_hash": receipt.extrinsic_hash,
4077
+ "is_success": receipt.is_success,
4078
+ "error_message": receipt.error_message,
4079
+ "triggered_events": [str(event) for event in receipt.triggered_events]
4080
+ }
4081
+
4082
+ if receipt.is_success:
4083
+ success(f"Coldkey node verification successful!")
4084
+ success(f"Transaction hash: {receipt.extrinsic_hash}")
4085
+ else:
4086
+ error(f"Coldkey node verification failed: {receipt.error_message}")
4087
+
4088
+ log("Full result:")
4089
+ console.print(json.dumps(result, indent=2))
4090
+
4091
+ return 0 if receipt.is_success else 1
4092
+
4093
+ except Exception as e:
4094
+ error(f"Error verifying coldkey node: {e}")
4095
+ if hasattr(e, '__traceback__'):
4096
+ import traceback
4097
+ traceback.print_exc()
4098
+ return 1
@@ -800,6 +800,129 @@ def add_miner_commands(subparsers):
800
800
  help="Do not submit extrinsic; just print payload",
801
801
  )
802
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",
924
+ )
925
+
803
926
 
804
927
  def get_subparser(command: str) -> argparse.ArgumentParser:
805
928
  """Get a subparser for a specific command.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "hippius"
3
- version = "0.2.50"
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