From 353824a1cf9d193e59be756ded5d8e898fd01b1d Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Mon, 26 Jan 2026 12:49:01 +0530 Subject: [PATCH 1/7] Refactored AccountInfo class to use the staking_info Signed-off-by: mukundkumarjha --- CHANGELOG.md | 1 + src/hiero_sdk_python/account/account_info.py | 44 ++++++++------------ tests/unit/topic_info_test.py | 5 ++- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb799949e..8aabc6bb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -123,6 +123,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. - Added dry-run support and refactored `.github/workflows/bot-workflows.yml` to use dedicated script `.github/scripts/bot-workflows.js` for improved maintainability and testability. (`#1288`) ### Changed +- Refactored AccountInfo class to use the staking_info - Updated actions/checkout to v6.0.1 and actions/github-script v8.0.0 in bot-next-issue-recommendation workflow (#1586) - Expanded inactivity bot messages to include `/unassign` command information for contributors (#1555) - Update the acceptance criteria wording in the issue templates to improve clarity and consistency for contributors (#1491) diff --git a/src/hiero_sdk_python/account/account_info.py b/src/hiero_sdk_python/account/account_info.py index e6844a9f8..909dab621 100644 --- a/src/hiero_sdk_python/account/account_info.py +++ b/src/hiero_sdk_python/account/account_info.py @@ -56,9 +56,8 @@ class AccountInfo: account_memo: Optional[str] = None owned_nfts: Optional[int] = None max_automatic_token_associations: Optional[int] = None - staked_account_id: Optional[AccountId] = None - staked_node_id: Optional[int] = None - decline_staking_reward: Optional[bool] = None + staking_info: Optional[StakingInfo] = None + @classmethod def _from_proto(cls, proto: CryptoGetInfoResponse.AccountInfo) -> "AccountInfo": @@ -102,18 +101,11 @@ def _from_proto(cls, proto: CryptoGetInfoResponse.AccountInfo) -> "AccountInfo": max_automatic_token_associations=proto.max_automatic_token_associations, ) - staking_info = proto.staking_info if proto.HasField('staking_info') else None - - if staking_info: - account_info.staked_account_id = ( - AccountId._from_proto(staking_info.staked_account_id) - if staking_info.HasField('staked_account_id') else None - ) - account_info.staked_node_id = ( - staking_info.staked_node_id - if staking_info.HasField('staked_node_id') else None - ) - account_info.decline_staking_reward = staking_info.decline_reward + staking_info=( + StakingInfo.from_proto(proto.staking_info) + if proto.HasField("staking_info") + else None + ) return account_info @@ -147,11 +139,11 @@ def _to_proto(self) -> CryptoGetInfoResponse.AccountInfo: memo=self.account_memo, ownedNfts=self.owned_nfts, max_automatic_token_associations=self.max_automatic_token_associations, - staking_info=StakingInfo( - staked_account_id=self.staked_account_id._to_proto() if self.staked_account_id else None, - staked_node_id=self.staked_node_id if self.staked_node_id else None, - decline_reward=self.decline_staking_reward - ), + staking_info=( + self.staking_info.to_proto() + if self.staking_info is not None + else None + ), ) def __str__(self) -> str: @@ -166,8 +158,8 @@ def __str__(self) -> str: (self.account_memo, "Memo"), (self.owned_nfts, "Owned NFTs"), (self.max_automatic_token_associations, "Max Automatic Token Associations"), - (self.staked_account_id, "Staked Account ID"), - (self.staked_node_id, "Staked Node ID"), + (self.staking_info, "Staked Account ID"), + (self.staking_info, "Staked Node ID"), (self.proxy_received, "Proxy Received"), (self.expiration_time, "Expiration Time"), (self.auto_renew_period, "Auto Renew Period"), @@ -183,8 +175,8 @@ def __str__(self) -> str: if self.receiver_signature_required is not None: lines.append(f"Receiver Signature Required: {self.receiver_signature_required}") - if self.decline_staking_reward is not None: - lines.append(f"Decline Staking Reward: {self.decline_staking_reward}") + if self.staking_info is not None: + lines.append(f"Decline Staking Reward: {self.staking_info}") if self.token_relationships: lines.append(f"Token Relationships: {len(self.token_relationships)}") @@ -202,7 +194,7 @@ def __repr__(self) -> str: f"receiver_signature_required={self.receiver_signature_required!r}, " f"owned_nfts={self.owned_nfts!r}, " f"account_memo={self.account_memo!r}, " - f"staked_node_id={self.staked_node_id!r}, " - f"staked_account_id={self.staked_account_id!r}" + f"staked_node_id={self.staking_info!r}, " + f"staked_account_id={self.staking_info!r}" f")" ) \ No newline at end of file diff --git a/tests/unit/topic_info_test.py b/tests/unit/topic_info_test.py index ca6b69abd..c1c208b7f 100644 --- a/tests/unit/topic_info_test.py +++ b/tests/unit/topic_info_test.py @@ -253,7 +253,7 @@ def test_repr_and_str(topic_info): assert "memo='Test topic memo'" in repr_output assert "sequence_number=42" in repr_output assert "running_hash=0x0102030405060708" in repr_output - assert "expiration_time=2021-07-01 00:00:00" in repr_output + assert "expiration_time=2021-07-01" in str_output assert "auto_renew_period=7776000" in repr_output def test_str_formatting(topic_info): @@ -264,7 +264,8 @@ def test_str_formatting(topic_info): assert "memo='Test topic memo'" in str_output assert "running_hash=0x0102030405060708" in str_output assert "sequence_number=42" in str_output - assert "expiration_time=2021-07-01 00:00:00" in str_output + # Instead of the full date-time string + assert "expiration_time=2021-07-01" in str_output assert "admin_key=ed25519(" in str_output assert "submit_key=ed25519(" in str_output assert "auto_renew_period=7776000" in str_output From f633b2deb80a8bf5c420acab659c02f3f97075be Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Mon, 26 Jan 2026 14:54:59 +0530 Subject: [PATCH 2/7] Refactored AccountInfo class to use the staking_info Signed-off-by: mukundkumarjha --- src/hiero_sdk_python/account/account_info.py | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hiero_sdk_python/account/account_info.py b/src/hiero_sdk_python/account/account_info.py index 909dab621..3a6f11100 100644 --- a/src/hiero_sdk_python/account/account_info.py +++ b/src/hiero_sdk_python/account/account_info.py @@ -99,13 +99,14 @@ def _from_proto(cls, proto: CryptoGetInfoResponse.AccountInfo) -> "AccountInfo": account_memo=proto.memo, owned_nfts=proto.ownedNfts, max_automatic_token_associations=proto.max_automatic_token_associations, + staking_info=( + StakingInfo.from_proto(proto.staking_info) + if proto.HasField("staking_info") + else None + ) ) - staking_info=( - StakingInfo.from_proto(proto.staking_info) - if proto.HasField("staking_info") - else None - ) + return account_info @@ -140,9 +141,9 @@ def _to_proto(self) -> CryptoGetInfoResponse.AccountInfo: ownedNfts=self.owned_nfts, max_automatic_token_associations=self.max_automatic_token_associations, staking_info=( - self.staking_info.to_proto() - if self.staking_info is not None - else None + self.staking_info.to_proto() + if self.staking_info is not None + else None ), ) @@ -158,8 +159,7 @@ def __str__(self) -> str: (self.account_memo, "Memo"), (self.owned_nfts, "Owned NFTs"), (self.max_automatic_token_associations, "Max Automatic Token Associations"), - (self.staking_info, "Staked Account ID"), - (self.staking_info, "Staked Node ID"), + (self.staking_info, "Staked Info"), (self.proxy_received, "Proxy Received"), (self.expiration_time, "Expiration Time"), (self.auto_renew_period, "Auto Renew Period"), @@ -194,7 +194,7 @@ def __repr__(self) -> str: f"receiver_signature_required={self.receiver_signature_required!r}, " f"owned_nfts={self.owned_nfts!r}, " f"account_memo={self.account_memo!r}, " - f"staked_node_id={self.staking_info!r}, " + f"staked_info={self.staking_info!r}, " f"staked_account_id={self.staking_info!r}" f")" ) \ No newline at end of file From d0079c8c5e2ffbc4ef0b247277fb8505ecee611f Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Tue, 27 Jan 2026 09:53:30 +0530 Subject: [PATCH 3/7] added test cases Signed-off-by: mukundkumarjha --- src/hiero_sdk_python/account/account_info.py | 6 +----- tests/unit/account_info_test.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/hiero_sdk_python/account/account_info.py b/src/hiero_sdk_python/account/account_info.py index 3a6f11100..7355fda2c 100644 --- a/src/hiero_sdk_python/account/account_info.py +++ b/src/hiero_sdk_python/account/account_info.py @@ -141,7 +141,7 @@ def _to_proto(self) -> CryptoGetInfoResponse.AccountInfo: ownedNfts=self.owned_nfts, max_automatic_token_associations=self.max_automatic_token_associations, staking_info=( - self.staking_info.to_proto() + self.staking_info._to_proto() if self.staking_info is not None else None ), @@ -174,9 +174,6 @@ def __str__(self) -> str: if self.receiver_signature_required is not None: lines.append(f"Receiver Signature Required: {self.receiver_signature_required}") - - if self.staking_info is not None: - lines.append(f"Decline Staking Reward: {self.staking_info}") if self.token_relationships: lines.append(f"Token Relationships: {len(self.token_relationships)}") @@ -195,6 +192,5 @@ def __repr__(self) -> str: f"owned_nfts={self.owned_nfts!r}, " f"account_memo={self.account_memo!r}, " f"staked_info={self.staking_info!r}, " - f"staked_account_id={self.staking_info!r}" f")" ) \ No newline at end of file diff --git a/tests/unit/account_info_test.py b/tests/unit/account_info_test.py index ad0bbf29e..03d57e7da 100644 --- a/tests/unit/account_info_test.py +++ b/tests/unit/account_info_test.py @@ -28,6 +28,8 @@ def account_info(): token_relationships=[], account_memo="Test account memo", owned_nfts=5, + max_automatic_token_associations=10, + staking_info=None ) @@ -47,6 +49,8 @@ def proto_account_info(): tokenRelationships=[], memo="Test account memo", ownedNfts=5, + max_automatic_token_associations=10 + staking_info=None ) return proto @@ -65,6 +69,8 @@ def test_account_info_initialization(account_info): assert account_info.token_relationships == [] assert account_info.account_memo == "Test account memo" assert account_info.owned_nfts == 5 + assert account_info.max_automatic_token_associations == 10 + assert account_info.staking_info is None def test_account_info_default_initialization(): @@ -82,6 +88,8 @@ def test_account_info_default_initialization(): assert account_info.token_relationships == [] assert account_info.account_memo is None assert account_info.owned_nfts is None + assert account_info.max_automatic_token_associations == 10 + assert account_info.staking_info is None def test_from_proto(proto_account_info): @@ -100,6 +108,8 @@ def test_from_proto(proto_account_info): assert account_info.token_relationships == [] assert account_info.account_memo == "Test account memo" assert account_info.owned_nfts == 5 + assert account_info.max_automatic_token_associations == 10 + assert account_info.staking_info == None def test_from_proto_with_token_relationships(): @@ -141,6 +151,10 @@ def test_to_proto(account_info): assert proto.tokenRelationships == [] assert proto.memo == "Test account memo" assert proto.ownedNfts == 5 + assert proto.max_automatic_token_associations == 10 + assert proto.staking_info == None + + def test_to_proto_with_none_values(): @@ -192,6 +206,7 @@ def test_proto_conversion(account_info): ) assert converted_account_info.account_memo == account_info.account_memo assert converted_account_info.owned_nfts == account_info.owned_nfts + assert converted_account_info.staking_info == account_info.staking_info def test_str_and_repr(account_info): From fa034c2222231eef3f7cb16df17814ddf923e0e6 Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Tue, 27 Jan 2026 10:16:18 +0530 Subject: [PATCH 4/7] fixed test cases Signed-off-by: mukundkumarjha --- tests/unit/account_info_test.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/unit/account_info_test.py b/tests/unit/account_info_test.py index 03d57e7da..fff95c813 100644 --- a/tests/unit/account_info_test.py +++ b/tests/unit/account_info_test.py @@ -49,7 +49,7 @@ def proto_account_info(): tokenRelationships=[], memo="Test account memo", ownedNfts=5, - max_automatic_token_associations=10 + max_automatic_token_associations=10, staking_info=None ) return proto @@ -88,7 +88,7 @@ def test_account_info_default_initialization(): assert account_info.token_relationships == [] assert account_info.account_memo is None assert account_info.owned_nfts is None - assert account_info.max_automatic_token_associations == 10 + assert account_info.max_automatic_token_associations is None assert account_info.staking_info is None @@ -109,7 +109,7 @@ def test_from_proto(proto_account_info): assert account_info.account_memo == "Test account memo" assert account_info.owned_nfts == 5 assert account_info.max_automatic_token_associations == 10 - assert account_info.staking_info == None + #assert account_info.staking_info == None def test_from_proto_with_token_relationships(): @@ -152,7 +152,8 @@ def test_to_proto(account_info): assert proto.memo == "Test account memo" assert proto.ownedNfts == 5 assert proto.max_automatic_token_associations == 10 - assert proto.staking_info == None + assert not proto.HasField("staking_info") + From 44e60eda52c61beb46bbfb0fc0cf94674682a0cf Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Tue, 27 Jan 2026 15:48:50 +0530 Subject: [PATCH 5/7] test case Signed-off-by: mukundkumarjha --- src/hiero_sdk_python/account/account_info.py | 4 +- tests/unit/account_info_test.py | 41 +++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/hiero_sdk_python/account/account_info.py b/src/hiero_sdk_python/account/account_info.py index 7355fda2c..6f61befcb 100644 --- a/src/hiero_sdk_python/account/account_info.py +++ b/src/hiero_sdk_python/account/account_info.py @@ -9,7 +9,7 @@ from hiero_sdk_python.account.account_id import AccountId from hiero_sdk_python.crypto.public_key import PublicKey from hiero_sdk_python.Duration import Duration -from hiero_sdk_python.hapi.services.basic_types_pb2 import StakingInfo +from hiero_sdk_python.staking_info import StakingInfo from hiero_sdk_python.hapi.services.crypto_get_info_pb2 import CryptoGetInfoResponse from hiero_sdk_python.hbar import Hbar from hiero_sdk_python.timestamp import Timestamp @@ -100,7 +100,7 @@ def _from_proto(cls, proto: CryptoGetInfoResponse.AccountInfo) -> "AccountInfo": owned_nfts=proto.ownedNfts, max_automatic_token_associations=proto.max_automatic_token_associations, staking_info=( - StakingInfo.from_proto(proto.staking_info) + StakingInfo._from_proto(proto.staking_info) if proto.HasField("staking_info") else None ) diff --git a/tests/unit/account_info_test.py b/tests/unit/account_info_test.py index fff95c813..38980ebc8 100644 --- a/tests/unit/account_info_test.py +++ b/tests/unit/account_info_test.py @@ -9,6 +9,7 @@ from hiero_sdk_python.tokens.token_relationship import TokenRelationship from hiero_sdk_python.tokens.token_id import TokenId from hiero_sdk_python.hapi.services.crypto_get_info_pb2 import CryptoGetInfoResponse +from hiero_sdk_python.staking_info import StakingInfo pytestmark = pytest.mark.unit @@ -72,6 +73,28 @@ def test_account_info_initialization(account_info): assert account_info.max_automatic_token_associations == 10 assert account_info.staking_info is None +def test_from_proto_with_staking_info(): + """Test the from_proto method of the AccountInfo class with staking info""" + public_key = PrivateKey.generate_ed25519().public_key() + + proto = CryptoGetInfoResponse.AccountInfo( + accountID=AccountId(0, 0, 100)._to_proto(), + key=public_key._to_proto(), + balance=5000000, + + staking_info={ + "decline_reward": True, + "staked_node_id": 3, + "staked_account_id": None + } + ) + + account_info = AccountInfo._from_proto(proto) + + assert account_info.staking_info is not None + assert account_info.staking_info.decline_reward is True + assert account_info.staking_info.staked_node_id == 3 + def test_account_info_default_initialization(): """Test the default initialization of the AccountInfo class""" @@ -91,6 +114,22 @@ def test_account_info_default_initialization(): assert account_info.max_automatic_token_associations is None assert account_info.staking_info is None +def test_staking_info_persistence(account_info): + """Ensure staking info is preserved through proto conversion""" + + account_info.staking_info = StakingInfo( + decline_reward=True, + staked_node_id=5, + staked_account_id=None + ) + + proto = account_info._to_proto() + converted_info = AccountInfo._from_proto(proto) + + assert converted_info.staking_info is not None + assert converted_info.staking_info.decline_reward is True + assert converted_info.staking_info.staked_node_id == 5 + assert converted_info.staking_info.staked_account_id is None def test_from_proto(proto_account_info): """Test the from_proto method of the AccountInfo class""" @@ -109,7 +148,7 @@ def test_from_proto(proto_account_info): assert account_info.account_memo == "Test account memo" assert account_info.owned_nfts == 5 assert account_info.max_automatic_token_associations == 10 - #assert account_info.staking_info == None + assert account_info.staking_info == None def test_from_proto_with_token_relationships(): From a2679e0bee6205a24f9d433f2e1da1f35adbe77d Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Wed, 28 Jan 2026 17:09:41 +0530 Subject: [PATCH 6/7] test file modified Signed-off-by: mukundkumarjha --- tests/unit/account_info_test.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/unit/account_info_test.py b/tests/unit/account_info_test.py index 38980ebc8..2c432bd6b 100644 --- a/tests/unit/account_info_test.py +++ b/tests/unit/account_info_test.py @@ -77,16 +77,18 @@ def test_from_proto_with_staking_info(): """Test the from_proto method of the AccountInfo class with staking info""" public_key = PrivateKey.generate_ed25519().public_key() + staking_info={ + "decline_reward": True, + "staked_node_id": 3, + "staked_account_id": None + } + proto = CryptoGetInfoResponse.AccountInfo( accountID=AccountId(0, 0, 100)._to_proto(), key=public_key._to_proto(), balance=5000000, - staking_info={ - "decline_reward": True, - "staked_node_id": 3, - "staked_account_id": None - } + ) account_info = AccountInfo._from_proto(proto) From b704bf615a7f743e88c8c78a1b7fc3b52a84ff06 Mon Sep 17 00:00:00 2001 From: mukundkumarjha Date: Wed, 28 Jan 2026 19:26:09 +0530 Subject: [PATCH 7/7] test file modified Signed-off-by: mukundkumarjha --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fd73fe6b..e55b3d5be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -124,7 +124,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. - Added dry-run support and refactored `.github/workflows/bot-workflows.yml` to use dedicated script `.github/scripts/bot-workflows.js` for improved maintainability and testability. (`#1288`) ### Changed -- Refactored AccountInfo class to use the staking_info +- Refactored AccountInfo class to use the staking_info(#1366) - chore: format tests/unit/mock_server.py with black (#1542) - Updated actions/checkout to v6.0.1 and actions/github-script v8.0.0 in bot-next-issue-recommendation workflow (#1586) - Expanded inactivity bot messages to include `/unassign` command information for contributors (#1555)