1+ """TCK RPC handlers for account-related endpoints."""
2+
13from __future__ import annotations
24
35from hiero_sdk_python .account .account_create_transaction import AccountCreateTransaction
46from hiero_sdk_python .account .account_id import AccountId
7+ from hiero_sdk_python .account .account_info import AccountInfo
58from hiero_sdk_python .hbar import Hbar
9+ from hiero_sdk_python .query .account_info_query import AccountInfoQuery
610from hiero_sdk_python .response_code import ResponseCode
711from hiero_sdk_python .transaction .transaction_receipt import TransactionReceipt
812from tck .handlers .registry import rpc_method
9- from tck .param .account import CreateAccountParams
10- from tck .response .account import CreateAccountResponse
13+ from tck .param .account import CreateAccountParams , GetAccountInfoParams
14+ from tck .response .account import (
15+ CreateAccountResponse ,
16+ GetAccountInfoResponse ,
17+ StakingInfoResponse ,
18+ TokenRelationshipResponse ,
19+ )
1120from tck .util .client_utils import get_client
1221from tck .util .constants import DEFAULT_GRPC_TIMEOUT
1322from tck .util .key_utils import get_key_from_string
@@ -51,6 +60,7 @@ def _build_create_account_transaction(params: CreateAccountParams) -> AccountCre
5160
5261@rpc_method ("createAccount" )
5362def create_account (params : CreateAccountParams ) -> CreateAccountResponse :
63+ """Create a new account using TCK createAccount parameters."""
5464 client = get_client (params .sessionId )
5565
5666 transaction = _build_create_account_transaction (params )
@@ -66,3 +76,100 @@ def create_account(params: CreateAccountParams) -> CreateAccountResponse:
6676 account_id = str (receipt .account_id )
6777
6878 return CreateAccountResponse (account_id , ResponseCode (receipt .status ).name )
79+
80+
81+ def _enum_name (value ) -> str | None :
82+ if value is None :
83+ return None
84+ return getattr (value , "name" , str (value ))
85+
86+
87+ def _serialize_key (key ) -> str | None :
88+ if key is None :
89+ return None
90+
91+ to_string_der = getattr (key , "to_string_der" , None )
92+ if callable (to_string_der ):
93+ return to_string_der ()
94+
95+ return key .to_bytes ().hex ()
96+
97+
98+ def _to_staking_info_response (info : AccountInfo ) -> StakingInfoResponse | None :
99+ if info .staking_info is None :
100+ return None
101+
102+ staking_info = info .staking_info
103+ return StakingInfoResponse (
104+ declineStakingReward = staking_info .decline_reward ,
105+ stakePeriodStart = str (staking_info .stake_period_start ) if staking_info .stake_period_start is not None else None ,
106+ pendingReward = str (staking_info .pending_reward .to_tinybars ())
107+ if staking_info .pending_reward is not None
108+ else "0" ,
109+ stakedToMe = str (staking_info .staked_to_me .to_tinybars ()) if staking_info .staked_to_me is not None else "0" ,
110+ stakedAccountId = str (staking_info .staked_account_id ) if staking_info .staked_account_id is not None else None ,
111+ stakedNodeId = str (staking_info .staked_node_id ) if staking_info .staked_node_id is not None else None ,
112+ )
113+
114+
115+ def _to_token_relationships_response (info : AccountInfo ) -> dict [str , TokenRelationshipResponse ]:
116+ token_relationships_response : dict [str , TokenRelationshipResponse ] = {}
117+
118+ for relationship in info .token_relationships :
119+ token_id = str (relationship .token_id ) if relationship .token_id is not None else None
120+ if token_id is None :
121+ continue
122+
123+ token_relationships_response [token_id ] = TokenRelationshipResponse (
124+ tokenId = token_id ,
125+ symbol = relationship .symbol ,
126+ balance = str (relationship .balance ) if relationship .balance is not None else "0" ,
127+ kycStatus = _enum_name (relationship .kyc_status ),
128+ freezeStatus = _enum_name (relationship .freeze_status ),
129+ decimals = str (relationship .decimals ) if relationship .decimals is not None else None ,
130+ automaticAssociation = relationship .automatic_association ,
131+ )
132+
133+ return token_relationships_response
134+
135+
136+ def _build_account_info_response (info : AccountInfo ) -> GetAccountInfoResponse :
137+ auto_renew_period_seconds = str (info .auto_renew_period .seconds ) if info .auto_renew_period is not None else "0"
138+
139+ return GetAccountInfoResponse (
140+ accountId = str (info .account_id ) if info .account_id is not None else None ,
141+ contractAccountId = info .contract_account_id or "" ,
142+ isDeleted = bool (info .is_deleted ),
143+ proxyAccountId = "" ,
144+ proxyReceived = str (info .proxy_received .to_tinybars ()) if info .proxy_received is not None else "0" ,
145+ key = _serialize_key (info .key ),
146+ balance = str (info .balance .to_tinybars ()) if info .balance is not None else "0" ,
147+ sendRecordThreshold = "0" ,
148+ receiveRecordThreshold = "0" ,
149+ isReceiverSignatureRequired = bool (info .receiver_signature_required ),
150+ expirationTime = str (info .expiration_time ) if info .expiration_time is not None else None ,
151+ autoRenewPeriod = auto_renew_period_seconds ,
152+ tokenRelationships = _to_token_relationships_response (info ),
153+ accountMemo = info .account_memo or "" ,
154+ ownedNfts = str (info .owned_nfts ) if info .owned_nfts is not None else "0" ,
155+ maxAutomaticTokenAssociations = str (info .max_automatic_token_associations )
156+ if info .max_automatic_token_associations is not None
157+ else "0" ,
158+ aliasKey = "" ,
159+ ledgerId = "" ,
160+ ethereumNonce = "0" ,
161+ stakingInfo = _to_staking_info_response (info ),
162+ )
163+
164+
165+ @rpc_method ("getAccountInfo" )
166+ def get_account_info (params : GetAccountInfoParams ) -> GetAccountInfoResponse :
167+ """Query account info and map SDK fields to the TCK response contract."""
168+ client = get_client (params .sessionId )
169+
170+ query = AccountInfoQuery ().set_grpc_deadline (DEFAULT_GRPC_TIMEOUT )
171+ if params .accountId is not None :
172+ query .set_account_id (AccountId .from_string (params .accountId ))
173+
174+ info = query .execute (client )
175+ return _build_account_info_response (info )
0 commit comments