From 4db4c75961e3569d881ac023ed03f202ec2ae519 Mon Sep 17 00:00:00 2001 From: Jessica G Date: Tue, 27 Jan 2026 20:14:32 -0800 Subject: [PATCH 1/4] chore: update link to maintainer guidelines (#1616) Signed-off-by: Jessica G --- CHANGELOG.md | 1 + MAINTAINERS.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87010709a..d2c0ef073 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -210,6 +210,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. - Enhance TopicInfo `__str__` method and tests with additional coverage, and update the format_key function in `key_format.py` to handle objects with a \_to_proto method. - Update changelog workflow to trigger automatically on pull requests instead of manual dispatch (#1567) - Formatted key-related unit test files (`key_utils_test.py`, `test_key_format.py`, `test_key_list.py`) using the black formatter +- chore: update maintainer guidelines link in MAINTAINERS.md (#1605) ### Fixed - Reduced notification spam by skipping the entire advanced qualification job for non-advanced issues and irrelevant events (#1517) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index c81f6a0f0..a64b69366 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -31,4 +31,4 @@ Maintainers are assigned the following scopes in this repository: ## The Duties of a Maintainer -Maintainers are expected to perform duties in alignment with **[Hiero-Ledger's defined maintainer guidelines](https://github.com/hiero-ledger/governance/blob/main/roles-and-groups.md#maintainers).** +Maintainers are expected to perform duties in alignment with **[Hiero-Ledger's defined maintainer guidelines](https://github.com/hiero-ledger/.github/blob/main/CONTRIBUTING.md#about-users-and-maintainers).** From f33daf948c2c95b39aaedf472830d3fab1500cc0 Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Wed, 28 Jan 2026 13:57:55 +0530 Subject: [PATCH 2/4] test Signed-off-by: mukundkumarjha --- .../query/transaction_record_query.py | 21 +++++++++++++++---- .../transaction/transaction_record.py | 4 +++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/hiero_sdk_python/query/transaction_record_query.py b/src/hiero_sdk_python/query/transaction_record_query.py index 24aeeddf9..999af3f56 100644 --- a/src/hiero_sdk_python/query/transaction_record_query.py +++ b/src/hiero_sdk_python/query/transaction_record_query.py @@ -1,4 +1,4 @@ -from typing import Optional, Any, Union +from typing import Optional, Any, Union, List from hiero_sdk_python.hapi.services import query_header_pb2, transaction_get_record_pb2, query_pb2 from hiero_sdk_python.query.query import Query from hiero_sdk_python.response_code import ResponseCode @@ -16,12 +16,14 @@ class TransactionRecordQuery(Query): Represents a query for a transaction record on the Hedera network. """ - def __init__(self, transaction_id: Optional[TransactionId] = None): + def __init__(self, transaction_id: Optional[TransactionId] = None, include_children: bool = False): """ Initializes the TransactionRecordQuery with the provided transaction ID. """ super().__init__() self.transaction_id : Optional[TransactionId] = transaction_id + self.include_children = include_children + def set_transaction_id(self, transaction_id: TransactionId): """ @@ -34,6 +36,9 @@ def set_transaction_id(self, transaction_id: TransactionId): """ self.transaction_id = transaction_id return self + + def set_include_children(self, include_children): + self.include_children = include_children def _make_request(self): """ @@ -57,6 +62,7 @@ def _make_request(self): query_header = self._make_request_header() transaction_get_record = transaction_get_record_pb2.TransactionGetRecordQuery() transaction_get_record.header.CopyFrom(query_header) + transaction_get_record.include_child_records = self.include_children transaction_get_record.transactionID.CopyFrom(self.transaction_id._to_proto()) query = query_pb2.Query() @@ -182,7 +188,7 @@ def execute(self, client): """ self._before_execute(client) response = self._execute(client) - + #childrens = self._map_record_list(response.child_transaction_records) return TransactionRecord._from_proto(response.transactionGetRecord.transactionRecord, self.transaction_id) def _get_query_response(self, response: Any): @@ -198,4 +204,11 @@ def _get_query_response(self, response: Any): Returns: The transaction get record response object """ - return response.transactionGetRecord \ No newline at end of file + return response.transactionGetRecord + + def _map_record_list(self, proto_records: List[transaction_get_record_pb2.TransactionGetRecordResponse]) -> List[TransactionRecord]: + records: List[TransactionRecord] = [] + for record in proto_records: + records.append(TransactionRecord._from_proto(record, self.transaction_id)) + + return records \ No newline at end of file diff --git a/src/hiero_sdk_python/transaction/transaction_record.py b/src/hiero_sdk_python/transaction/transaction_record.py index 2c13215e4..5081f5240 100644 --- a/src/hiero_sdk_python/transaction/transaction_record.py +++ b/src/hiero_sdk_python/transaction/transaction_record.py @@ -18,7 +18,7 @@ from collections import defaultdict from dataclasses import dataclass, field -from typing import Optional +from typing import Optional, List from hiero_sdk_python.account.account_id import AccountId from hiero_sdk_python.contract.contract_function_result import ContractFunctionResult @@ -73,6 +73,7 @@ class TransactionRecord: prng_number: Optional[int] = None prng_bytes: Optional[bytes] = None + children: List[TransactionId] = None def __repr__(self) -> str: """Returns a human-readable string representation of the TransactionRecord. @@ -166,6 +167,7 @@ def _from_proto(cls, proto: transaction_record_pb2.TransactionRecord, transactio nft_transfers=nft_transfers, transfers=transfers, new_pending_airdrops=new_pending_airdrops, + #childrens = childrens, call_result=( ContractFunctionResult._from_proto(proto.contractCallResult) if proto.HasField("contractCallResult") From dfe203987d01ec536e14ddd2502bb26c76640fdb Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Wed, 28 Jan 2026 15:41:20 +0530 Subject: [PATCH 3/4] Add support for include_children to the TransactionRecordQuery class Signed-off-by: mukundkumarjha --- tests/unit/transaction_record_query_test.py | 26 ++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/unit/transaction_record_query_test.py b/tests/unit/transaction_record_query_test.py index 1b76286ae..6685f53f5 100644 --- a/tests/unit/transaction_record_query_test.py +++ b/tests/unit/transaction_record_query_test.py @@ -11,6 +11,7 @@ transaction_record_pb2, transaction_receipt_pb2, ) +from hiero_sdk_python.hapi.services import query_header_pb2 from tests.unit.mock_server import mock_hedera_servers @@ -92,7 +93,30 @@ def test_transaction_record_query_execute(transaction_id): assert result.transaction_fee == 100000 assert result.transaction_hash == b'\x01' * 48 assert result.transaction_memo == "Test transaction" - + +from hiero_sdk_python.hapi.services import query_header_pb2, transaction_get_record_pb2 +def test_transaction_record_query_with_children_mapping(transaction_id): + + child_proto = transaction_record_pb2.TransactionRecord( + memo="Child Record" + ) + child_proto.transactionID.CopyFrom(transaction_id._to_proto()) + + record_response = transaction_get_record_pb2.TransactionGetRecordResponse() + + record_response.header.nodeTransactionPrecheckCode = ResponseCode.OK + + record_response.transactionRecord.memo = "Parent Record" + record_response.transactionRecord.transactionID.CopyFrom(transaction_id._to_proto()) + + record_response.child_transaction_records.extend([child_proto, child_proto]) + + query = TransactionRecordQuery(transaction_id) + children = query._map_record_list(record_response.child_transaction_records) + + assert len(children) == 2 + assert children[0].transaction_memo == "Child Record" + def get_transaction_record_responses(transaction_record): return [[ response_pb2.Response( From e2e4055a24a1a0c3d2cc2f4671e0092dd57977e9 Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Wed, 28 Jan 2026 15:46:15 +0530 Subject: [PATCH 4/4] feat: implement child transaction records for #1512 Signed-off-by: mukundkumarjha --- CHANGELOG.md | 1 + .../transaction_record_with_children.py | 33 +++++ .../query/transaction_record_query.py | 135 +++++++++++------- .../transaction/transaction_record.py | 81 ++++++----- 4 files changed, 169 insertions(+), 81 deletions(-) create mode 100644 examples/transaction/transaction_record_with_children.py diff --git a/CHANGELOG.md b/CHANGELOG.md index d2c0ef073..125db00c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. - Formatted client_test.py using Black. ### Added +- Added support for include_children to the TransactionRecordQuery class - Added Windows setup guide for SDK developers (`docs/sdk_developers/training/setup/setup_windows.md`) with PowerShell installation instructions. (#1570) - Added a beginner assignment guard that requires completion of a Good First Issue. (#1484) - Added `/unassign` command allowing contributors to remove themselves from assigned issues.(#1472) diff --git a/examples/transaction/transaction_record_with_children.py b/examples/transaction/transaction_record_with_children.py new file mode 100644 index 000000000..7f1da2e43 --- /dev/null +++ b/examples/transaction/transaction_record_with_children.py @@ -0,0 +1,33 @@ +import os +from hiero_sdk_python.client import Client +from hiero_sdk_python.query.transaction_record_query import TransactionRecordQuery + +def main(): + # Setup client + client = Client.for_testnet() + # ... (add operator credentials) ... + + # 1. Execute a transaction that is likely to have child records + # (e.g., a complex Smart Contract call) + print("Executing transaction...") + + # 2. Query the record and explicitly request children + tx_id = "..." # your transaction id + + query = ( + TransactionRecordQuery() + .set_transaction_id(tx_id) + .set_include_children(True) # The new feature! + ) + + record = query.execute(client) + + # 3. Demonstrate accessing the children + print(f"Parent Transaction ID: {record.transaction_id}") + print(f"Number of child records found: {len(record.children)}") + + for i, child in enumerate(record.children): + print(f"Child {i+1} Status: {child.receipt.status}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/hiero_sdk_python/query/transaction_record_query.py b/src/hiero_sdk_python/query/transaction_record_query.py index 999af3f56..7ac4bc35c 100644 --- a/src/hiero_sdk_python/query/transaction_record_query.py +++ b/src/hiero_sdk_python/query/transaction_record_query.py @@ -1,5 +1,9 @@ from typing import Optional, Any, Union, List -from hiero_sdk_python.hapi.services import query_header_pb2, transaction_get_record_pb2, query_pb2 +from hiero_sdk_python.hapi.services import ( + query_header_pb2, + transaction_get_record_pb2, + query_pb2, +) from hiero_sdk_python.query.query import Query from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.transaction.transaction_id import TransactionId @@ -16,19 +20,22 @@ class TransactionRecordQuery(Query): Represents a query for a transaction record on the Hedera network. """ - def __init__(self, transaction_id: Optional[TransactionId] = None, include_children: bool = False): + def __init__( + self, + transaction_id: Optional[TransactionId] = None, + include_children: bool = False, + ): """ Initializes the TransactionRecordQuery with the provided transaction ID. """ super().__init__() - self.transaction_id : Optional[TransactionId] = transaction_id + self.transaction_id: Optional[TransactionId] = transaction_id self.include_children = include_children - - + def set_transaction_id(self, transaction_id: TransactionId): """ Sets the transaction ID for the query. - + Args: transaction_id (TransactionId): The ID of the transaction to query. Returns: @@ -36,14 +43,15 @@ def set_transaction_id(self, transaction_id: TransactionId): """ self.transaction_id = transaction_id return self - + def set_include_children(self, include_children): self.include_children = include_children + return self def _make_request(self): """ Constructs the protobuf request for the transaction record query. - + Builds a TransactionGetRecordQuery protobuf message with the appropriate header and transaction ID. @@ -57,19 +65,27 @@ def _make_request(self): """ try: if not self.transaction_id: - raise ValueError("Transaction ID must be set before making the request.") + raise ValueError( + "Transaction ID must be set before making the request." + ) query_header = self._make_request_header() - transaction_get_record = transaction_get_record_pb2.TransactionGetRecordQuery() + transaction_get_record = ( + transaction_get_record_pb2.TransactionGetRecordQuery() + ) transaction_get_record.header.CopyFrom(query_header) + + transaction_get_record.transactionID.CopyFrom( + self.transaction_id._to_proto() + ) transaction_get_record.include_child_records = self.include_children - transaction_get_record.transactionID.CopyFrom(self.transaction_id._to_proto()) - query = query_pb2.Query() - if not hasattr(query, 'transactionGetRecord'): - raise AttributeError("Query object has no attribute 'transactionGetRecord'") + if not hasattr(query, "transactionGetRecord"): + raise AttributeError( + "Query object has no attribute 'transactionGetRecord'" + ) query.transactionGetRecord.CopyFrom(transaction_get_record) - + return query except Exception as e: print(f"Exception in _make_request: {e}") @@ -78,7 +94,7 @@ def _make_request(self): def _get_method(self, channel: _Channel) -> _Method: """ Returns the appropriate gRPC method for the transaction receipt query. - + Implements the abstract method from Query to provide the specific gRPC method for getting transaction receipts. @@ -89,14 +105,13 @@ def _get_method(self, channel: _Channel) -> _Method: _Method: The method wrapper containing the query function """ return _Method( - transaction_func=None, - query_func=channel.crypto.getTxRecordByTxID + transaction_func=None, query_func=channel.crypto.getTxRecordByTxID ) def _should_retry(self, response: Any) -> _ExecutionState: """ Determines whether the query should be retried based on the response. - + Implements the abstract method from Query to decide whether to retry the query based on the response status code. First checks the header status, then the receipt status. @@ -108,37 +123,45 @@ def _should_retry(self, response: Any) -> _ExecutionState: _ExecutionState: The execution state indicating what to do next """ status = response.transactionGetRecord.header.nodeTransactionPrecheckCode - + retryable_statuses = { ResponseCode.UNKNOWN, ResponseCode.BUSY, ResponseCode.RECEIPT_NOT_FOUND, ResponseCode.RECORD_NOT_FOUND, - ResponseCode.PLATFORM_NOT_ACTIVE + ResponseCode.PLATFORM_NOT_ACTIVE, } - + if status == ResponseCode.OK: - if response.transactionGetRecord.header.responseType == query_header_pb2.ResponseType.COST_ANSWER: + if ( + response.transactionGetRecord.header.responseType + == query_header_pb2.ResponseType.COST_ANSWER + ): return _ExecutionState.FINISHED pass - elif status in retryable_statuses or status == ResponseCode.PLATFORM_TRANSACTION_NOT_CREATED: + elif ( + status in retryable_statuses + or status == ResponseCode.PLATFORM_TRANSACTION_NOT_CREATED + ): return _ExecutionState.RETRY else: return _ExecutionState.ERROR - + status = response.transactionGetRecord.transactionRecord.receipt.status - + if status in retryable_statuses or status == ResponseCode.OK: return _ExecutionState.RETRY elif status == ResponseCode.SUCCESS: return _ExecutionState.FINISHED else: return _ExecutionState.ERROR - - def _map_status_error(self, response: Any) -> Union[PrecheckError,ReceiptStatusError]: + + def _map_status_error( + self, response: Any + ) -> Union[PrecheckError, ReceiptStatusError]: """ Maps a response status code to an appropriate error object. - + Implements the abstract method from Executable to create error objects from response status codes. Checks both the header status and receipt status. @@ -156,23 +179,37 @@ def _map_status_error(self, response: Any) -> Union[PrecheckError,ReceiptStatusE ResponseCode.UNKNOWN, ResponseCode.RECEIPT_NOT_FOUND, ResponseCode.RECORD_NOT_FOUND, - ResponseCode.OK + ResponseCode.OK, } - + if status not in retryable_statuses: return PrecheckError(status) - + receipt = response.transactionGetRecord.transactionRecord.receipt - - return ReceiptStatusError(status, self.transaction_id, TransactionReceipt._from_proto(receipt, self.transaction_id)) - + + return ReceiptStatusError( + status, + self.transaction_id, + TransactionReceipt._from_proto(receipt, self.transaction_id), + ) + + def _map_record_list( + self, + proto_records: List[transaction_get_record_pb2.TransactionGetRecordResponse], + ) -> List[TransactionRecord]: + records: List[TransactionRecord] = [] + for record in proto_records: + records.append(TransactionRecord._from_proto(record, self.transaction_id)) + + return records + def execute(self, client): """ Executes the transaction record query. - + Sends the query to the Hedera network and processes the response to return a TransactionRecord object. - + This function delegates the core logic to `_execute()`, and may propagate exceptions raised by it. Args: @@ -188,27 +225,27 @@ def execute(self, client): """ self._before_execute(client) response = self._execute(client) - #childrens = self._map_record_list(response.child_transaction_records) - return TransactionRecord._from_proto(response.transactionGetRecord.transactionRecord, self.transaction_id) + if not response.HasField("transactionGetRecord"): + raise AttributeError("Response does not contain 'transactionGetRecord'") + record_response = response.transactionGetRecord + children = self._map_record_list(record_response.child_transaction_records) + return TransactionRecord._from_proto( + response.transactionGetRecord.transactionRecord, + self.transaction_id, + children=children, + ) def _get_query_response(self, response: Any): """ Extracts the transaction record response from the full response. - + Implements the abstract method from Query to extract the specific transaction record response object. - + Args: response: The full response from the network - + Returns: The transaction get record response object """ return response.transactionGetRecord - - def _map_record_list(self, proto_records: List[transaction_get_record_pb2.TransactionGetRecordResponse]) -> List[TransactionRecord]: - records: List[TransactionRecord] = [] - for record in proto_records: - records.append(TransactionRecord._from_proto(record, self.transaction_id)) - - return records \ No newline at end of file diff --git a/src/hiero_sdk_python/transaction/transaction_record.py b/src/hiero_sdk_python/transaction/transaction_record.py index 5081f5240..2e5bc86f6 100644 --- a/src/hiero_sdk_python/transaction/transaction_record.py +++ b/src/hiero_sdk_python/transaction/transaction_record.py @@ -36,7 +36,7 @@ class TransactionRecord: Represents a record of a completed transaction on the Hiero network. This class combines detailed information about the a transaction including the transaction ID, receipt, token and NFT transfers, fees & other - metadata such as pseudo-random number generation(PRNG) results and + metadata such as pseudo-random number generation(PRNG) results and pending airdrop records. Attributes: @@ -46,17 +46,17 @@ class TransactionRecord: transaction_fee (Optional[int]): The total network fee (in tinybars) charged for the transaction. receipt (Optional[TransactionReceipt]): The receipt summarizing the outcome and status of the transaction. call_result (Optional[ContractFunctionResult]): The result of a contract call if the transaction was a smart contract execution. - token_transfers (defaultdict[TokenId, defaultdict[AccountId, int]]): - A mapping of token IDs to account-level transfer amounts. - Represents fungible token movements within the transaction. - nft_transfers (defaultdict[TokenId, list[TokenNftTransfer]]): + token_transfers (defaultdict[TokenId, defaultdict[AccountId, int]]): + A mapping of token IDs to account-level transfer amounts. + Represents fungible token movements within the transaction. + nft_transfers (defaultdict[TokenId, list[TokenNftTransfer]]): A mapping of token IDs to lists of NFT transfers for that token. transfers (defaultdict[AccountId, int]): A mapping of account IDs to hbar transfer amounts (positive for credit, negative for debit). new_pending_airdrops (list[PendingAirdropRecord]):A list of new airdrop records created by this transaction. - + prng_number (Optional[int]): A pseudo-random integer generated by the network (if applicable). prng_bytes (Optional[bytes]): A pseudo-random byte array generated by the network (if applicable). - + """ transaction_id: Optional[TransactionId] = None @@ -66,9 +66,15 @@ class TransactionRecord: receipt: Optional[TransactionReceipt] = None call_result: Optional[ContractFunctionResult] = None - token_transfers: defaultdict[TokenId, defaultdict[AccountId, int]] = field(default_factory=lambda: defaultdict(lambda: defaultdict(int))) - nft_transfers: defaultdict[TokenId, list[TokenNftTransfer]] = field(default_factory=lambda: defaultdict(list[TokenNftTransfer])) - transfers: defaultdict[AccountId, int] = field(default_factory=lambda: defaultdict(int)) + token_transfers: defaultdict[TokenId, defaultdict[AccountId, int]] = field( + default_factory=lambda: defaultdict(lambda: defaultdict(int)) + ) + nft_transfers: defaultdict[TokenId, list[TokenNftTransfer]] = field( + default_factory=lambda: defaultdict(list[TokenNftTransfer]) + ) + transfers: defaultdict[AccountId, int] = field( + default_factory=lambda: defaultdict(int) + ) new_pending_airdrops: list[PendingAirdropRecord] = field(default_factory=list) prng_number: Optional[int] = None @@ -77,12 +83,12 @@ class TransactionRecord: def __repr__(self) -> str: """Returns a human-readable string representation of the TransactionRecord. - - This method constructs a detailed string containing all significant fields of the + + This method constructs a detailed string containing all significant fields of the transaction record including transaction ID, hash, memo, fees, status, transfers, and PRNG results. For the receipt status, it attempts to resolve the numeric status to a human-readable ResponseCode name. - + Returns: str: A string representation showing all significant fields of the TransactionRecord. """ @@ -94,21 +100,28 @@ def __repr__(self) -> str: status = ResponseCode(self.receipt.status).name except (ValueError, AttributeError): status = self.receipt.status - return (f"TransactionRecord(transaction_id='{self.transaction_id}', " - f"transaction_hash={self.transaction_hash}, " - f"transaction_memo='{self.transaction_memo}', " - f"transaction_fee={self.transaction_fee}, " - f"receipt_status='{status}', " - f"token_transfers={dict(self.token_transfers)}, " - f"nft_transfers={dict(self.nft_transfers)}, " - f"transfers={dict(self.transfers)}, " - f"new_pending_airdrops={list(self.new_pending_airdrops)}, " - f"call_result={self.call_result}, " - f"prng_number={self.prng_number}, " - f"prng_bytes={self.prng_bytes})") + return ( + f"TransactionRecord(transaction_id='{self.transaction_id}', " + f"transaction_hash={self.transaction_hash}, " + f"transaction_memo='{self.transaction_memo}', " + f"transaction_fee={self.transaction_fee}, " + f"receipt_status='{status}', " + f"token_transfers={dict(self.token_transfers)}, " + f"nft_transfers={dict(self.nft_transfers)}, " + f"transfers={dict(self.transfers)}, " + f"new_pending_airdrops={list(self.new_pending_airdrops)}, " + f"call_result={self.call_result}, " + f"prng_number={self.prng_number}, " + f"prng_bytes={self.prng_bytes})" + ) @classmethod - def _from_proto(cls, proto: transaction_record_pb2.TransactionRecord, transaction_id: Optional[TransactionId] = None) -> 'TransactionRecord': + def _from_proto( + cls, + proto: transaction_record_pb2.TransactionRecord, + transaction_id: Optional[TransactionId] = None, + children=None, + ) -> "TransactionRecord": """Creates a TransactionRecord instance from a protobuf transaction record. This method performs complex data aggregation from the protobuf message, @@ -125,9 +138,9 @@ def _from_proto(cls, proto: transaction_record_pb2.TransactionRecord, transactio into appropriate defaultdict collections for efficient access. Args: - proto (transaction_record_pb2.TransactionRecord): The raw protobuf + proto (transaction_record_pb2.TransactionRecord): The raw protobuf transaction record containing all transaction data. - transaction_id (Optional[TransactionId]): Optional transaction ID to + transaction_id (Optional[TransactionId]): Optional transaction ID to associate with the record. If not provided, will be extracted from the protobuf message if available. @@ -154,9 +167,11 @@ def _from_proto(cls, proto: transaction_record_pb2.TransactionRecord, transactio new_pending_airdrops: list[PendingAirdropRecord] = [] for pending_airdrop in proto.new_pending_airdrops: - new_pending_airdrops.append(PendingAirdropRecord._from_proto(pending_airdrop)) - + new_pending_airdrops.append( + PendingAirdropRecord._from_proto(pending_airdrop) + ) + children: Optional[List["TransactionRecord"]] = None return cls( transaction_id=transaction_id, transaction_hash=proto.transactionHash, @@ -167,7 +182,7 @@ def _from_proto(cls, proto: transaction_record_pb2.TransactionRecord, transactio nft_transfers=nft_transfers, transfers=transfers, new_pending_airdrops=new_pending_airdrops, - #childrens = childrens, + children=children, call_result=( ContractFunctionResult._from_proto(proto.contractCallResult) if proto.HasField("contractCallResult") @@ -233,6 +248,8 @@ def _to_proto(self) -> transaction_record_pb2.TransactionRecord: transfer.amount = amount for pending_airdrop in self.new_pending_airdrops: - record_proto.new_pending_airdrops.add().CopyFrom(pending_airdrop._to_proto()) + record_proto.new_pending_airdrops.add().CopyFrom( + pending_airdrop._to_proto() + ) return record_proto