Skip to content

Commit a6c2ecb

Browse files
committed
feat: implement _from_protobuf for all transaction types and fix dispatch map
Signed-off-by: Mounil Kanakhara <mounilkankhara@gmail.com>
1 parent 1b15756 commit a6c2ecb

48 files changed

Lines changed: 756 additions & 69 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/hiero_sdk_python/account/account_allowance_approve_transaction.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,13 @@ def _get_method(self, channel: _Channel) -> _Method:
366366
_Method: An object containing the transaction function to approve allowances.
367367
"""
368368
return _Method(transaction_func=channel.crypto.approveAllowances, query_func=None)
369+
370+
@classmethod
371+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
372+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
373+
if transaction_body.HasField("cryptoApproveAllowance"):
374+
body = transaction_body.cryptoApproveAllowance
375+
transaction.hbar_allowances = [HbarAllowance._from_proto(a) for a in body.cryptoAllowances]
376+
transaction.token_allowances = [TokenAllowance._from_proto(a) for a in body.tokenAllowances]
377+
transaction.nft_allowances = [TokenNftAllowance._from_proto(a) for a in body.nftAllowances]
378+
return transaction

src/hiero_sdk_python/account/account_allowance_delete_transaction.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,11 @@ def _get_method(self, channel: _Channel) -> _Method:
131131
_Method: An object containing the transaction function to delete allowances.
132132
"""
133133
return _Method(transaction_func=channel.crypto.deleteAllowances, query_func=None)
134+
135+
@classmethod
136+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
137+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
138+
if transaction_body.HasField("cryptoDeleteAllowance"):
139+
body = transaction_body.cryptoDeleteAllowance
140+
transaction.nft_wipe = [TokenNftAllowance._from_wipe_proto(a) for a in body.nftAllowances]
141+
return transaction

src/hiero_sdk_python/account/account_create_transaction.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,9 @@ def _build_proto_body(self) -> crypto_create_pb2.CryptoCreateTransactionBody:
319319
# triggers an INVALID_INITIAL_BALANCE pre-check error instead of a local error.
320320
initialBalance=ctypes.c_uint64(initial_balance_tinybars).value,
321321
receiverSigRequired=self.receiver_signature_required,
322-
autoRenewPeriod=duration_pb2.Duration(seconds=self.auto_renew_period.seconds),
322+
autoRenewPeriod=(
323+
duration_pb2.Duration(seconds=self.auto_renew_period.seconds) if self.auto_renew_period else None
324+
),
323325
memo=self.account_memo,
324326
max_automatic_token_associations=self.max_automatic_token_associations,
325327
alias=self.alias.address_bytes if self.alias else None,
@@ -371,3 +373,27 @@ def _get_method(self, channel: _Channel) -> _Method:
371373
_Method: An instance of _Method containing the transaction and query functions.
372374
"""
373375
return _Method(transaction_func=channel.crypto.createAccount, query_func=None)
376+
377+
@classmethod
378+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
379+
380+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
381+
if transaction_body.HasField("cryptoCreateAccount"):
382+
body = transaction_body.cryptoCreateAccount
383+
if body.HasField("key"):
384+
transaction.key = Key.from_proto_key(body.key)
385+
transaction.initial_balance = body.initialBalance
386+
transaction.receiver_signature_required = body.receiverSigRequired
387+
transaction.auto_renew_period = None
388+
if body.HasField("autoRenewPeriod"):
389+
transaction.auto_renew_period = Duration._from_proto(body.autoRenewPeriod)
390+
transaction.account_memo = body.memo if body.memo else None
391+
transaction.max_automatic_token_associations = body.max_automatic_token_associations
392+
transaction.alias = EvmAddress.from_bytes(body.alias) if body.alias else None
393+
transaction.decline_staking_reward = body.decline_reward
394+
staked_id = body.WhichOneof("staked_id")
395+
if staked_id == "staked_account_id":
396+
transaction.staked_account_id = AccountId._from_proto(body.staked_account_id)
397+
elif staked_id == "staked_node_id":
398+
transaction.staked_node_id = body.staked_node_id
399+
return transaction

src/hiero_sdk_python/account/account_delete_transaction.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,14 @@ def _get_method(self, channel: _Channel) -> _Method:
128128
delete accounts.
129129
"""
130130
return _Method(transaction_func=channel.crypto.cryptoDelete, query_func=None)
131+
132+
@classmethod
133+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
134+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
135+
if transaction_body.HasField("cryptoDelete"):
136+
body = transaction_body.cryptoDelete
137+
if body.HasField("deleteAccountID"):
138+
transaction.account_id = AccountId._from_proto(body.deleteAccountID)
139+
if body.HasField("transferAccountID"):
140+
transaction.transfer_account_id = AccountId._from_proto(body.transferAccountID)
141+
return transaction

src/hiero_sdk_python/account/account_update_transaction.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,31 @@ def _get_method(self, channel: _Channel) -> _Method:
352352
_Method: An object containing the transaction function to update an account.
353353
"""
354354
return _Method(transaction_func=channel.crypto.updateAccount, query_func=None)
355+
356+
@classmethod
357+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map): # noqa: PLR0912
358+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
359+
if transaction_body.HasField("cryptoUpdateAccount"):
360+
body = transaction_body.cryptoUpdateAccount
361+
if body.HasField("accountIDToUpdate"):
362+
transaction.account_id = AccountId._from_proto(body.accountIDToUpdate)
363+
if body.HasField("key"):
364+
transaction.key = Key.from_proto_key(body.key)
365+
if body.HasField("autoRenewPeriod"):
366+
transaction.auto_renew_period = Duration._from_proto(body.autoRenewPeriod)
367+
if body.HasField("memo"):
368+
transaction.account_memo = body.memo.value
369+
if body.HasField("expirationTime"):
370+
transaction.expiration_time = Timestamp._from_protobuf(body.expirationTime)
371+
if body.HasField("receiverSigRequiredWrapper"):
372+
transaction.receiver_signature_required = body.receiverSigRequiredWrapper.value
373+
if body.HasField("max_automatic_token_associations"):
374+
transaction.max_automatic_token_associations = body.max_automatic_token_associations.value
375+
if body.HasField("decline_reward"):
376+
transaction.decline_staking_reward = body.decline_reward.value
377+
staked_id = body.WhichOneof("staked_id")
378+
if staked_id == "staked_account_id":
379+
transaction.staked_account_id = AccountId._from_proto(body.staked_account_id)
380+
elif staked_id == "staked_node_id":
381+
transaction.staked_node_id = body.staked_node_id
382+
return transaction

src/hiero_sdk_python/consensus/topic_create_transaction.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,3 +278,23 @@ def _get_method(self, channel: _Channel) -> _Method:
278278
_Method: The method for executing the transaction.
279279
"""
280280
return _Method(transaction_func=channel.topic.createTopic, query_func=None)
281+
282+
@classmethod
283+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map): # noqa: PLR0912
284+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
285+
if transaction_body.HasField("consensusCreateTopic"):
286+
body = transaction_body.consensusCreateTopic
287+
transaction.memo = body.memo if body.memo else ""
288+
if body.HasField("adminKey"):
289+
transaction.admin_key = Key.from_proto_key(body.adminKey)
290+
if body.HasField("submitKey"):
291+
transaction.submit_key = Key.from_proto_key(body.submitKey)
292+
if body.HasField("autoRenewPeriod"):
293+
transaction.auto_renew_period = Duration._from_proto(body.autoRenewPeriod)
294+
if body.HasField("autoRenewAccount"):
295+
transaction.auto_renew_account = AccountId._from_proto(body.autoRenewAccount)
296+
if body.HasField("fee_schedule_key"):
297+
transaction.fee_schedule_key = Key.from_proto_key(body.fee_schedule_key)
298+
transaction.custom_fees = [CustomFixedFee._from_topic_fee_proto(f) for f in body.custom_fees]
299+
transaction.fee_exempt_keys = [Key.from_proto_key(k) for k in body.fee_exempt_key_list]
300+
return transaction

src/hiero_sdk_python/consensus/topic_delete_transaction.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,12 @@ def _get_method(self, channel: _Channel) -> _Method:
9494
_Method: The method to execute the transaction.
9595
"""
9696
return _Method(transaction_func=channel.topic.deleteTopic, query_func=None)
97+
98+
@classmethod
99+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
100+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
101+
if transaction_body.HasField("consensusDeleteTopic"):
102+
body = transaction_body.consensusDeleteTopic
103+
if body.HasField("topicID"):
104+
transaction.topic_id = TopicId._from_proto(body.topicID)
105+
return transaction

src/hiero_sdk_python/consensus/topic_message_submit_transaction.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def _build_proto_body(self) -> consensus_submit_message_pb2.ConsensusSubmitMessa
170170
ConsensusSubmitMessageTransactionBody: The protobuf body for this transaction.
171171
172172
Raises:
173-
ValueError: If required fields (message) are missing.
173+
ValueError: If required fields (topic_id, message) are missing.
174174
"""
175175
if not self.message:
176176
raise ValueError("Missing required fields: message.")
@@ -233,6 +233,17 @@ def _get_method(self, channel: _Channel) -> _Method:
233233
"""
234234
return _Method(transaction_func=channel.topic.submitMessage, query_func=None)
235235

236+
@classmethod
237+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
238+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
239+
if transaction_body.HasField("consensusSubmitMessage"):
240+
body = transaction_body.consensusSubmitMessage
241+
if body.HasField("topicID"):
242+
transaction.topic_id = TopicId._from_proto(body.topicID)
243+
transaction.message = body.message.decode("utf-8") if body.message else None
244+
transaction._total_chunks = transaction.get_required_chunks()
245+
return transaction
246+
236247
def sign(self, private_key: PrivateKey) -> TopicMessageSubmitTransaction:
237248
"""
238249
Signs the transaction using the provided private key.

src/hiero_sdk_python/consensus/topic_update_transaction.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def __init__(
3333
memo: str | None = None,
3434
admin_key: Key | None = None,
3535
submit_key: Key | None = None,
36-
auto_renew_period: Duration | None = Duration(7890000),
36+
auto_renew_period: Duration | None = None,
3737
auto_renew_account: AccountId | None = None,
3838
expiration_time: Timestamp | None = None,
3939
custom_fees: list[CustomFixedFee] | None = None,
@@ -57,7 +57,7 @@ def __init__(
5757
"""
5858
super().__init__()
5959
self.topic_id: TopicId | None = topic_id
60-
self.memo: str = memo or ""
60+
self.memo: str | None = memo
6161
self.admin_key: Key | None = admin_key
6262
self.submit_key: Key | None = submit_key
6363
self.auto_renew_period: Duration | None = auto_renew_period
@@ -312,3 +312,32 @@ def _get_method(self, channel: _Channel) -> _Method:
312312
_Method: The method to execute the transaction.
313313
"""
314314
return _Method(transaction_func=channel.topic.updateTopic, query_func=None)
315+
316+
@classmethod
317+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map): # noqa: PLR0912
318+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
319+
if transaction_body.HasField("consensusUpdateTopic"):
320+
body = transaction_body.consensusUpdateTopic
321+
transaction.memo = None
322+
transaction.auto_renew_period = None
323+
if body.HasField("topicID"):
324+
transaction.topic_id = TopicId._from_proto(body.topicID)
325+
if body.HasField("memo"):
326+
transaction.memo = body.memo.value
327+
if body.HasField("adminKey"):
328+
transaction.admin_key = Key.from_proto_key(body.adminKey)
329+
if body.HasField("submitKey"):
330+
transaction.submit_key = Key.from_proto_key(body.submitKey)
331+
if body.HasField("autoRenewPeriod"):
332+
transaction.auto_renew_period = Duration._from_proto(body.autoRenewPeriod)
333+
if body.HasField("autoRenewAccount"):
334+
transaction.auto_renew_account = AccountId._from_proto(body.autoRenewAccount)
335+
if body.HasField("expirationTime"):
336+
transaction.expiration_time = Timestamp._from_protobuf(body.expirationTime)
337+
if body.HasField("fee_schedule_key"):
338+
transaction.fee_schedule_key = Key.from_proto_key(body.fee_schedule_key)
339+
if body.HasField("custom_fees"):
340+
transaction.custom_fees = [CustomFixedFee._from_topic_fee_proto(f) for f in body.custom_fees.fees]
341+
if body.HasField("fee_exempt_key_list"):
342+
transaction.fee_exempt_keys = [Key.from_proto_key(k) for k in body.fee_exempt_key_list.keys]
343+
return transaction

src/hiero_sdk_python/contract/contract_create_transaction.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from hiero_sdk_python.contract.contract_function_parameters import (
1111
ContractFunctionParameters,
1212
)
13+
from hiero_sdk_python.crypto.key import Key
1314
from hiero_sdk_python.crypto.public_key import PublicKey
1415
from hiero_sdk_python.Duration import Duration
1516
from hiero_sdk_python.executable import _Method
@@ -387,6 +388,40 @@ def build_scheduled_body(self) -> SchedulableTransactionBody:
387388
schedulable_body.contractCreateInstance.CopyFrom(contract_create_body)
388389
return schedulable_body
389390

391+
@classmethod
392+
def _from_protobuf(cls, transaction_body, body_bytes: bytes, sig_map):
393+
transaction = super()._from_protobuf(transaction_body, body_bytes, sig_map)
394+
if transaction_body.HasField("contractCreateInstance"):
395+
body = transaction_body.contractCreateInstance
396+
if body.HasField("adminKey"):
397+
transaction.admin_key = Key.from_proto_key(body.adminKey)
398+
transaction.gas = body.gas
399+
transaction.initial_balance = body.initialBalance
400+
if body.HasField("proxyAccountID"):
401+
transaction.proxy_account_id = AccountId._from_proto(body.proxyAccountID)
402+
transaction.auto_renew_period = (
403+
Duration._from_proto(body.autoRenewPeriod)
404+
if body.HasField("autoRenewPeriod")
405+
else Duration(DEFAULT_AUTO_RENEW_PERIOD)
406+
)
407+
transaction.parameters = body.constructorParameters if body.constructorParameters else None
408+
transaction.contract_memo = body.memo if body.memo else None
409+
transaction.max_automatic_token_associations = body.max_automatic_token_associations
410+
if body.HasField("auto_renew_account_id"):
411+
transaction.auto_renew_account_id = AccountId._from_proto(body.auto_renew_account_id)
412+
transaction.decline_reward = body.decline_reward
413+
initcode_source = body.WhichOneof("initcodeSource")
414+
if initcode_source == "fileID":
415+
transaction.bytecode_file_id = FileId._from_proto(body.fileID)
416+
elif initcode_source == "initcode":
417+
transaction.bytecode = body.initcode
418+
staked_id = body.WhichOneof("staked_id")
419+
if staked_id == "staked_account_id":
420+
transaction.staked_account_id = AccountId._from_proto(body.staked_account_id)
421+
elif staked_id == "staked_node_id":
422+
transaction.staked_node_id = body.staked_node_id
423+
return transaction
424+
390425
def _get_method(self, channel: _Channel) -> _Method:
391426
"""
392427
Gets the method to execute the contract create transaction.

0 commit comments

Comments
 (0)