diff --git a/src/hiero_sdk_python/nodes/node_create_transaction.py b/src/hiero_sdk_python/nodes/node_create_transaction.py index 472d08c25..58fd99e9f 100644 --- a/src/hiero_sdk_python/nodes/node_create_transaction.py +++ b/src/hiero_sdk_python/nodes/node_create_transaction.py @@ -7,7 +7,7 @@ from hiero_sdk_python.account.account_id import AccountId from hiero_sdk_python.address_book.endpoint import Endpoint from hiero_sdk_python.channels import _Channel -from hiero_sdk_python.crypto.public_key import PublicKey +from hiero_sdk_python.crypto.key import Key from hiero_sdk_python.executable import _Method from hiero_sdk_python.hapi.services.node_create_pb2 import NodeCreateTransactionBody from hiero_sdk_python.hapi.services.schedulable_transaction_body_pb2 import ( @@ -29,7 +29,7 @@ class NodeCreateParams: service_endpoints (list[Endpoint]): The service endpoints of the node. gossip_ca_certificate (bytes, optional): The gossip ca certificate of the node. grpc_certificate_hash (bytes, optional): The grpc certificate hash of the node. - admin_key (PublicKey, optional): The admin key of the node. + admin_key (Key, optional): The admin key of the node. decline_reward (bool, optional): The decline reward of the node. grpc_web_proxy_endpoint (Endpoint, optional): The grpc web proxy endpoint of the node. """ @@ -40,7 +40,7 @@ class NodeCreateParams: service_endpoints: list[Endpoint] = field(default_factory=list) gossip_ca_certificate: bytes | None = None grpc_certificate_hash: bytes | None = None - admin_key: PublicKey | None = None + admin_key: Key | None = None decline_reward: bool | None = None grpc_web_proxy_endpoint: Endpoint | None = None associated_registered_nodes: list[int] = field(default_factory=list) @@ -73,7 +73,7 @@ def __init__(self, node_create_params: NodeCreateParams | None = None): self.service_endpoints: list[Endpoint] = node_create_params.service_endpoints self.gossip_ca_certificate: bytes | None = node_create_params.gossip_ca_certificate self.grpc_certificate_hash: bytes | None = node_create_params.grpc_certificate_hash - self.admin_key: PublicKey | None = node_create_params.admin_key + self.admin_key: Key | None = node_create_params.admin_key self.decline_reward: bool | None = node_create_params.decline_reward self.grpc_web_proxy_endpoint: Endpoint | None = node_create_params.grpc_web_proxy_endpoint self.associated_registered_nodes: list[int] = node_create_params.associated_registered_nodes @@ -168,12 +168,12 @@ def set_grpc_certificate_hash(self, grpc_certificate_hash: bytes | None) -> Node self.grpc_certificate_hash = grpc_certificate_hash return self - def set_admin_key(self, admin_key: PublicKey | None) -> NodeCreateTransaction: + def set_admin_key(self, admin_key: Key | None) -> NodeCreateTransaction: """ Sets the admin key for this node create transaction. Args: - admin_key (PublicKey): + admin_key (Key): The admin key of the node. Returns: @@ -255,7 +255,7 @@ def _build_proto_body(self) -> NodeCreateTransactionBody: service_endpoint=[endpoint._to_proto() for endpoint in self.service_endpoints or []], gossip_ca_certificate=self.gossip_ca_certificate, grpc_certificate_hash=self.grpc_certificate_hash, - admin_key=self.admin_key._to_proto() if self.admin_key else None, + admin_key=self.admin_key.to_proto_key() if self.admin_key else None, decline_reward=self.decline_reward, grpc_proxy_endpoint=(self.grpc_web_proxy_endpoint._to_proto() if self.grpc_web_proxy_endpoint else None), associated_registered_node=self.associated_registered_nodes, @@ -317,7 +317,7 @@ def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map): if pb.grpc_certificate_hash: transaction.grpc_certificate_hash = pb.grpc_certificate_hash if pb.HasField("admin_key"): - transaction.admin_key = PublicKey._from_proto(pb.admin_key) + transaction.admin_key = Key.from_proto_key(pb.admin_key) if pb.decline_reward: transaction.decline_reward = pb.decline_reward if pb.HasField("grpc_proxy_endpoint"): diff --git a/src/hiero_sdk_python/nodes/node_update_transaction.py b/src/hiero_sdk_python/nodes/node_update_transaction.py index 92d2d81ac..ecb14e30b 100644 --- a/src/hiero_sdk_python/nodes/node_update_transaction.py +++ b/src/hiero_sdk_python/nodes/node_update_transaction.py @@ -10,7 +10,7 @@ from hiero_sdk_python.account.account_id import AccountId from hiero_sdk_python.address_book.endpoint import Endpoint from hiero_sdk_python.channels import _Channel -from hiero_sdk_python.crypto.public_key import PublicKey +from hiero_sdk_python.crypto.key import Key from hiero_sdk_python.executable import _Method from hiero_sdk_python.hapi.services.node_update_pb2 import ( AssociatedRegisteredNodeList, @@ -36,7 +36,7 @@ class NodeUpdateParams: service_endpoints (list[Endpoint]): The service endpoints of the node. gossip_ca_certificate (bytes, None): The gossip ca certificate of the node. grpc_certificate_hash (bytes, None): The grpc certificate hash of the node. - admin_key (PublicKey, optional): The admin key of the node. + admin_key (Key, optional): The admin key of the node. decline_reward (bool, optional): The decline reward of the node. grpc_web_proxy_endpoint (Endpoint, optional): The grpc web proxy endpoint of the node. """ @@ -48,7 +48,7 @@ class NodeUpdateParams: service_endpoints: list[Endpoint] = field(default_factory=list) gossip_ca_certificate: bytes | None = None grpc_certificate_hash: bytes | None = None - admin_key: PublicKey | None = None + admin_key: Key | None = None decline_reward: bool | None = None grpc_web_proxy_endpoint: Endpoint | None = None associated_registered_nodes: list[int] | None = None @@ -82,7 +82,7 @@ def __init__(self, node_update_params: NodeUpdateParams | None = None): self.service_endpoints: list[Endpoint] = node_update_params.service_endpoints self.gossip_ca_certificate: bytes | None = node_update_params.gossip_ca_certificate self.grpc_certificate_hash: bytes | None = node_update_params.grpc_certificate_hash - self.admin_key: PublicKey | None = node_update_params.admin_key + self.admin_key: Key | None = node_update_params.admin_key self.decline_reward: bool | None = node_update_params.decline_reward self.grpc_web_proxy_endpoint: Endpoint | None = node_update_params.grpc_web_proxy_endpoint self.associated_registered_nodes: list[int] | None = node_update_params.associated_registered_nodes @@ -192,12 +192,12 @@ def set_grpc_certificate_hash(self, grpc_certificate_hash: bytes | None) -> Node self.grpc_certificate_hash = grpc_certificate_hash return self - def set_admin_key(self, admin_key: PublicKey | None) -> NodeUpdateTransaction: + def set_admin_key(self, admin_key: Key | None) -> NodeUpdateTransaction: """ Sets the admin key for this node update transaction. Args: - admin_key (PublicKey): + admin_key (Key): The admin key of the node. Returns: @@ -306,7 +306,7 @@ def _build_proto_body(self) -> NodeUpdateTransactionBody: grpc_certificate_hash=( BytesValue(value=self.grpc_certificate_hash) if self.grpc_certificate_hash is not None else None ), - admin_key=self._convert_to_proto(self.admin_key), + admin_key=self.admin_key.to_proto_key() if self.admin_key else None, decline_reward=(BoolValue(value=self.decline_reward) if self.decline_reward is not None else None), grpc_proxy_endpoint=self._convert_to_proto(self.grpc_web_proxy_endpoint), ) @@ -377,7 +377,7 @@ def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map): if pb.HasField("grpc_certificate_hash"): transaction.grpc_certificate_hash = pb.grpc_certificate_hash.value if pb.HasField("admin_key"): - transaction.admin_key = PublicKey._from_proto(pb.admin_key) + transaction.admin_key = Key.from_proto_key(pb.admin_key) if pb.HasField("decline_reward"): transaction.decline_reward = pb.decline_reward.value if pb.HasField("grpc_proxy_endpoint"): diff --git a/tests/unit/node_create_transaction_test.py b/tests/unit/node_create_transaction_test.py index 6c768d346..19fa16987 100644 --- a/tests/unit/node_create_transaction_test.py +++ b/tests/unit/node_create_transaction_test.py @@ -14,6 +14,7 @@ from hiero_sdk_python.hapi.services.schedulable_transaction_body_pb2 import ( SchedulableTransactionBody, ) +from hiero_sdk_python.hapi.services.transaction_pb2 import TransactionBody from hiero_sdk_python.nodes.node_create_transaction import ( NodeCreateParams, NodeCreateTransaction, @@ -330,3 +331,36 @@ def test_to_proto(mock_client): assert proto.signedTransactionBytes assert len(proto.signedTransactionBytes) > 0 + + +def test_node_create_transaction_build_with_private_key(): + """NodeCreateTransaction should accept PrivateKey and serialize the PublicKey in the proto.""" + private_key = PrivateKey.generate() + public_key = private_key.public_key() + + tx = NodeCreateTransaction().set_admin_key(private_key) + + body = tx._build_proto_body() + + # In the proto we should have the public key not the private one + assert body.admin_key.ed25519 == public_key.to_bytes_raw() + + +def test_node_create_transaction_from_protobuf_with_admin_key(): + """NodeCreateTransaction should deserialize the admin_key from the proto correctly.""" + private_key = PrivateKey.generate() + + transaction = NodeCreateTransaction().set_admin_key(private_key) + body = transaction._build_proto_body() + + transaction_body = TransactionBody() + transaction_body.nodeCreate.CopyFrom(body) + + parsed_transaction = NodeCreateTransaction._from_protobuf( + transaction_body, + b"", + None, + ) + + assert parsed_transaction.admin_key is not None + assert parsed_transaction.admin_key.to_proto_key() == body.admin_key diff --git a/tests/unit/node_update_transaction_test.py b/tests/unit/node_update_transaction_test.py index b5bc95a43..a2e1c0f72 100644 --- a/tests/unit/node_update_transaction_test.py +++ b/tests/unit/node_update_transaction_test.py @@ -14,6 +14,7 @@ from hiero_sdk_python.hapi.services.schedulable_transaction_body_pb2 import ( SchedulableTransactionBody, ) +from hiero_sdk_python.hapi.services.transaction_pb2 import TransactionBody from hiero_sdk_python.nodes.node_update_transaction import ( NodeUpdateParams, NodeUpdateTransaction, @@ -351,3 +352,36 @@ def test_to_proto(mock_client): assert proto.signedTransactionBytes assert len(proto.signedTransactionBytes) > 0 + + +def test_node_update_transaction_build_with_private_key(): + """NodeUpdateTransaction should accept PrivateKey and serialize the PublicKey in the proto.""" + private_key = PrivateKey.generate() + public_key = private_key.public_key() + + tx = NodeUpdateTransaction().set_admin_key(private_key) + + body = tx._build_proto_body() + + # In the proto we should have the public key not the private one + assert body.admin_key.ed25519 == public_key.to_bytes_raw() + + +def test_node_update_transaction_from_protobuf_with_admin_key(): + """NodeUpdateTransaction should deserialize the admin_key from the proto correctly.""" + private_key = PrivateKey.generate() + + transaction = NodeUpdateTransaction().set_admin_key(private_key) + body = transaction._build_proto_body() + + transaction_body = TransactionBody() + transaction_body.nodeUpdate.CopyFrom(body) + + parsed_transaction = NodeUpdateTransaction._from_protobuf( + transaction_body, + b"", + None, + ) + + assert parsed_transaction.admin_key is not None + assert parsed_transaction.admin_key.to_proto_key() == body.admin_key