66from dataclasses import dataclass
77from typing import Optional
88
9- from google .protobuf .wrappers_pb2 import BoolValue , StringValue
9+ from google .protobuf .wrappers_pb2 import BoolValue , Int32Value , StringValue
1010
1111from hiero_sdk_python .account .account_id import AccountId
1212from hiero_sdk_python .channels import _Channel
@@ -35,6 +35,14 @@ class AccountUpdateParams:
3535 account_memo (Optional[str]): The new memo for the account.
3636 receiver_signature_required (Optional[bool]): Whether receiver signature is required.
3737 expiration_time (Optional[Timestamp]): The new expiration time for the account.
38+ max_automatic_token_associations (Optional[int]): The maximum number of tokens that
39+ can be auto-associated with this account. Use -1 for unlimited, 0 for none.
40+ staked_account_id (Optional[AccountId]): The account to which this account is staking
41+ its balances. Mutually exclusive with staked_node_id.
42+ staked_node_id (Optional[int]): The node ID to which this account is staking
43+ its balances. Mutually exclusive with staked_account_id.
44+ decline_staking_reward (Optional[bool]): If true, the account declines receiving
45+ staking rewards.
3846 """
3947
4048 account_id : Optional [AccountId ] = None
@@ -43,6 +51,10 @@ class AccountUpdateParams:
4351 account_memo : Optional [str ] = None
4452 receiver_signature_required : Optional [bool ] = None
4553 expiration_time : Optional [Timestamp ] = None
54+ max_automatic_token_associations : Optional [int ] = None
55+ staked_account_id : Optional [AccountId ] = None
56+ staked_node_id : Optional [int ] = None
57+ decline_staking_reward : Optional [bool ] = None
4658
4759
4860class AccountUpdateTransaction (Transaction ):
@@ -70,6 +82,10 @@ def __init__(self, account_params: Optional[AccountUpdateParams] = None):
7082 self .account_memo = params .account_memo
7183 self .receiver_signature_required = params .receiver_signature_required
7284 self .expiration_time = params .expiration_time
85+ self .max_automatic_token_associations = params .max_automatic_token_associations
86+ self .staked_account_id = params .staked_account_id
87+ self .staked_node_id = params .staked_node_id
88+ self .decline_staking_reward = params .decline_staking_reward
7389
7490 def set_account_id (self , account_id : Optional [AccountId ]) -> "AccountUpdateTransaction" :
7591 """
@@ -161,6 +177,121 @@ def set_expiration_time(
161177 self .expiration_time = expiration_time
162178 return self
163179
180+ def set_max_automatic_token_associations (
181+ self , max_automatic_token_associations : Optional [int ]
182+ ) -> "AccountUpdateTransaction" :
183+ """
184+ Sets the maximum number of tokens that can be auto-associated with this account.
185+
186+ Args:
187+ max_automatic_token_associations (Optional[int]): The maximum number of tokens
188+ that can be auto-associated. Use -1 for unlimited, 0 for none.
189+ Must be >= -1.
190+
191+ Returns:
192+ AccountUpdateTransaction: This transaction instance.
193+
194+ Raises:
195+ ValueError: If max_automatic_token_associations is less than -1.
196+ """
197+ self ._require_not_frozen ()
198+ if max_automatic_token_associations is not None and max_automatic_token_associations < - 1 :
199+ raise ValueError (
200+ "max_automatic_token_associations must be -1 (unlimited) or a non-negative integer."
201+ )
202+ self .max_automatic_token_associations = max_automatic_token_associations
203+ return self
204+
205+ def set_staked_account_id (
206+ self , staked_account_id : Optional [AccountId ]
207+ ) -> "AccountUpdateTransaction" :
208+ """
209+ Sets the account to which this account is staking its balances.
210+
211+ This field is mutually exclusive with staked_node_id. Setting this will
212+ clear any previously set staked_node_id. Passing ``None`` (or calling
213+ :func:`clear_staked_account_id`) removes staking and sends the sentinel
214+ AccountId (0.0.0) to the network.
215+
216+ Args:
217+ staked_account_id (Optional[AccountId]): The account to which this account
218+ will stake its balances. ``None`` clears the staking configuration.
219+
220+ Returns:
221+ AccountUpdateTransaction: This transaction instance.
222+ """
223+ self ._require_not_frozen ()
224+ if staked_account_id is None :
225+ return self .clear_staked_account_id ()
226+ self .staked_account_id = staked_account_id
227+ self .staked_node_id = None # Clear the other field in the oneOf
228+ return self
229+
230+ def set_staked_node_id (
231+ self , staked_node_id : Optional [int ]
232+ ) -> "AccountUpdateTransaction" :
233+ """
234+ Sets the node ID to which this account is staking its balances.
235+
236+ This field is mutually exclusive with staked_account_id. Setting this will
237+ clear any previously set staked_account_id. Passing ``None`` (or calling
238+ :func:`clear_staked_node_id`) removes staking and sends the sentinel value (-1).
239+
240+ Args:
241+ staked_node_id (Optional[int]): The node ID to which this account will stake
242+ its balances. ``None`` clears the staking configuration.
243+
244+ Returns:
245+ AccountUpdateTransaction: This transaction instance.
246+ """
247+ self ._require_not_frozen ()
248+ if staked_node_id is None :
249+ return self .clear_staked_node_id ()
250+ self .staked_node_id = staked_node_id
251+ self .staked_account_id = None # Clear the other field in the oneOf
252+ return self
253+
254+ def clear_staked_account_id (self ) -> "AccountUpdateTransaction" :
255+ """
256+ Clears staking to an account by setting the sentinel AccountId (0.0.0).
257+
258+ Returns:
259+ AccountUpdateTransaction: This transaction instance.
260+ """
261+ self ._require_not_frozen ()
262+ self .staked_account_id = AccountId (0 , 0 , 0 )
263+ self .staked_node_id = None
264+ return self
265+
266+ def clear_staked_node_id (self ) -> "AccountUpdateTransaction" :
267+ """
268+ Clears staking to a node by setting the sentinel node ID (-1).
269+
270+ Returns:
271+ AccountUpdateTransaction: This transaction instance.
272+ """
273+ self ._require_not_frozen ()
274+ self .staked_node_id = - 1
275+ self .staked_account_id = None
276+ return self
277+
278+ def set_decline_staking_reward (
279+ self , decline_staking_reward : Optional [bool ]
280+ ) -> "AccountUpdateTransaction" :
281+ """
282+ Sets whether the account declines receiving staking rewards.
283+
284+ Args:
285+ decline_staking_reward (Optional[bool]): If True, the account declines receiving
286+ staking rewards. If False or None, the account will receive rewards.
287+
288+ Returns:
289+ AccountUpdateTransaction: This transaction instance.
290+ """
291+ self ._require_not_frozen ()
292+ self .decline_staking_reward = decline_staking_reward
293+ return self
294+
164295 def _build_proto_body (self ):
165296 """
166297 Returns the protobuf body for the account update transaction.
@@ -174,7 +305,7 @@ def _build_proto_body(self):
174305 if self .account_id is None :
175306 raise ValueError ("Missing required AccountID to update" )
176307
177- return CryptoUpdateTransactionBody (
308+ proto_body = CryptoUpdateTransactionBody (
178309 accountIDToUpdate = self .account_id ._to_proto (),
179310 key = self .key ._to_proto () if self .key else None ,
180311 memo = StringValue (value = self .account_memo ) if self .account_memo is not None else None ,
@@ -187,8 +318,26 @@ def _build_proto_body(self):
187318 if self .receiver_signature_required is not None
188319 else None
189320 ),
321+ max_automatic_token_associations = (
322+ Int32Value (value = self .max_automatic_token_associations )
323+ if self .max_automatic_token_associations is not None
324+ else None
325+ ),
326+ decline_reward = (
327+ BoolValue (value = self .decline_staking_reward )
328+ if self .decline_staking_reward is not None
329+ else None
330+ ),
190331 )
191332
333+ # Handle staked_id oneOf: only one can be set
334+ if self .staked_account_id is not None :
335+ proto_body .staked_account_id .CopyFrom (self .staked_account_id ._to_proto ())
336+ elif self .staked_node_id is not None :
337+ proto_body .staked_node_id = self .staked_node_id
338+
339+ return proto_body
340+
192341 def build_transaction_body (self ):
193342 """
194343 Builds the transaction body for this account update transaction.
@@ -227,3 +376,4 @@ def _get_method(self, channel: _Channel) -> _Method:
227376 _Method: An object containing the transaction function to update an account.
228377 """
229378 return _Method (transaction_func = channel .crypto .updateAccount , query_func = None )
379+
0 commit comments