1515from hiero_sdk_python .hapi .services import token_create_pb2 , basic_types_pb2
1616from hiero_sdk_python .response_code import ResponseCode
1717from hiero_sdk_python .tokens .token_type import TokenType
18+ from hiero_sdk_python .tokens .supply_type import SupplyType
1819from hiero_sdk_python .account .account_id import AccountId
1920from hiero_sdk_python .crypto .private_key import PrivateKey
2021
@@ -25,14 +26,15 @@ class TokenCreateValidator:
2526 """Token, key and freeze checks for creating a token as per the proto"""
2627
2728 @staticmethod
28- def validate_token_params (token_params ):
29+ def _validate_token_params (token_params ):
2930 """
3031 Ensure valid values for the token characteristics.
3132 """
3233 TokenCreateValidator ._validate_required_fields (token_params )
3334 TokenCreateValidator ._validate_name_and_symbol (token_params )
3435 TokenCreateValidator ._validate_initial_supply (token_params )
3536 TokenCreateValidator ._validate_decimals_and_token_type (token_params )
37+ TokenCreateValidator ._validate_supply_max_and_type (token_params )
3638
3739 @staticmethod
3840 def _validate_required_fields (token_params ):
@@ -70,15 +72,18 @@ def _validate_initial_supply(token_params):
7072 """
7173 Ensure initial supply is a non-negative integer and does not exceed max supply.
7274 """
73- MAX_SUPPLY = 9_223_372_036_854_775_807 # 2^63 - 1
75+ MAXIMUM_SUPPLY = 9_223_372_036_854_775_807 # 2^63 - 1
7476
7577 if (
7678 not isinstance (token_params .initial_supply , int )
7779 or token_params .initial_supply < 0
7880 ):
7981 raise ValueError ("Initial supply must be a non-negative integer" )
80- if token_params .initial_supply > MAX_SUPPLY :
81- raise ValueError (f"Initial supply cannot exceed { MAX_SUPPLY } " )
82+ if token_params .initial_supply > MAXIMUM_SUPPLY :
83+ raise ValueError (f"Initial supply cannot exceed { MAXIMUM_SUPPLY } " )
84+ if token_params .max_supply > MAXIMUM_SUPPLY :
85+ raise ValueError (f"Max supply cannot exceed { MAXIMUM_SUPPLY } " )
86+
8287
8388 @staticmethod
8489 def _validate_decimals_and_token_type (token_params ):
@@ -101,7 +106,7 @@ def _validate_decimals_and_token_type(token_params):
101106 raise ValueError ("A Non-fungible Unique Token requires an initial supply of zero" )
102107
103108 @staticmethod
104- def validate_token_freeze_status (keys , token_params ):
109+ def _validate_token_freeze_status (keys , token_params ):
105110 """Ensure account is not frozen for this token."""
106111 if token_params .freeze_default :
107112 if not keys .freeze_key :
@@ -112,6 +117,27 @@ def validate_token_freeze_status(keys, token_params):
112117 "Token frozen. Please complete a Token Unfreeze Transaction."
113118 )
114119
120+ @staticmethod
121+ def _validate_supply_max_and_type (token_params ):
122+ """Ensure max supply and supply type constraints."""
123+ # An infinite token must have max supply = 0.
124+ # A finite token must have max supply > 0.
125+ if token_params .max_supply != 0 : # Setting a max supply is only approprite for a finite token.
126+ if token_params .supply_type != SupplyType .FINITE :
127+ raise ValueError ("Setting a max supply field requires setting a finite supply type" )
128+
129+ # Finite tokens have the option to set a max supply >0.
130+ # A finite token must have max supply > 0.
131+ if token_params .supply_type == SupplyType .FINITE :
132+ if token_params .max_supply <= 0 :
133+ raise ValueError ("A finite supply token requires max_supply greater than zero 0" )
134+
135+ # Ensure max supply is greater than initial supply
136+ if token_params .initial_supply > token_params .max_supply :
137+ raise ValueError (
138+ "Initial supply cannot exceed the defined max supply for a finite token"
139+ )
140+
115141@dataclass
116142class TokenParams :
117143 """
@@ -124,6 +150,8 @@ class TokenParams:
124150 decimals (optional): The number of decimals for the token. This must be zero for NFTs.
125151 initial_supply (optional): The initial supply of the token.
126152 token_type (optional): The type of the token, defaulting to fungible.
153+ max_supply (optional): The maximum number of fungible tokens or NFT serial numbers that can be in circulation.
154+ supply_type (optional): The token supply status as finite or infinite.
127155 freeze_default (optional): An initial Freeze status for accounts associated to this token.
128156 """
129157
@@ -133,6 +161,8 @@ class TokenParams:
133161 decimals : int = 0 # Default to zero decimals
134162 initial_supply : int = 0 # Default to zero initial supply
135163 token_type : TokenType = TokenType .FUNGIBLE_COMMON # Default to Fungible Common
164+ max_supply : int = 0 # Since defaulting to infinite
165+ supply_type : SupplyType = SupplyType .INFINITE # Default to infinite
136166 freeze_default : bool = False
137167
138168
@@ -192,6 +222,8 @@ def __init__(self, token_params=None, keys=None):
192222 decimals = 0 ,
193223 initial_supply = 0 ,
194224 token_type = TokenType .FUNGIBLE_COMMON ,
225+ max_supply = 0 ,
226+ supply_type = SupplyType .INFINITE ,
195227 freeze_default = False
196228 )
197229
@@ -200,7 +232,6 @@ def __init__(self, token_params=None, keys=None):
200232 self ._keys = keys if keys else TokenKeys ()
201233
202234 self ._default_transaction_fee = DEFAULT_TRANSACTION_FEE
203- self ._is_frozen = False
204235
205236 def set_token_params (self , token_params ):
206237 """
@@ -231,6 +262,11 @@ def set_token_symbol(self, symbol):
231262 self ._token_params .token_symbol = symbol
232263 return self
233264
265+ def set_treasury_account_id (self , account_id ):
266+ self ._require_not_frozen ()
267+ self ._token_params .treasury_account_id = account_id
268+ return self
269+
234270 def set_decimals (self , decimals ):
235271 self ._require_not_frozen ()
236272 self ._token_params .decimals = decimals
@@ -245,11 +281,21 @@ def set_token_type(self, token_type):
245281 self ._require_not_frozen ()
246282 self ._token_params .token_type = token_type
247283 return self
284+
285+ def set_max_supply (self , max_supply ):
286+ self ._require_not_frozen ()
287+ self ._token_params .max_supply = max_supply
288+ return self
248289
249- def set_treasury_account_id (self , account_id ):
290+ def set_supply_type (self , supply_type ):
250291 self ._require_not_frozen ()
251- self ._token_params .treasury_account_id = account_id
292+ self ._token_params .supply_type = supply_type
252293 return self
294+
295+ def set_freeze_default (self , freeze_default ):
296+ self ._require_not_frozen ()
297+ self ._token_params .freeze_default = freeze_default
298+ return self
253299
254300 def set_admin_key (self , key ):
255301 self ._require_not_frozen ()
@@ -266,17 +312,6 @@ def set_freeze_key(self, key):
266312 self ._keys .freeze_key = key
267313 return self
268314
269- def freeze (self ):
270- """Marks the transaction as frozen to prevent further modifications."""
271- self ._is_frozen = True
272-
273- def _require_not_frozen (self ):
274- """
275- Helper method ensuring no changes are made after freeze() has been called.
276- """
277- if self ._is_frozen :
278- raise ValueError ("Transaction is frozen and cannot be modified." )
279-
280315 def build_transaction_body (self ):
281316 """
282317 Builds and returns the protobuf transaction body for token creation.
@@ -289,10 +324,10 @@ def build_transaction_body(self):
289324 """
290325
291326 # Validate all token params
292- TokenCreateValidator .validate_token_params (self ._token_params )
327+ TokenCreateValidator ._validate_token_params (self ._token_params )
293328
294329 # Validate freeze status
295- TokenCreateValidator .validate_token_freeze_status (self ._keys , self ._token_params )
330+ TokenCreateValidator ._validate_token_freeze_status (self ._keys , self ._token_params )
296331
297332 admin_key_proto = None
298333 if self ._keys .admin_key :
@@ -318,13 +353,24 @@ def build_transaction_body(self):
318353 else :
319354 token_type_value = self ._token_params .token_type
320355
356+ # Ensure supply type is correctly set with default to infinite
357+ if self ._token_params .supply_type is None :
358+ supply_type_value = 0 # default INFINITE
359+ elif isinstance (self ._token_params .supply_type , SupplyType ):
360+ supply_type_value = self ._token_params .supply_type .value
361+ else :
362+ supply_type_value = self ._token_params .supply_type
363+
321364 # Construct the TokenCreateTransactionBody
322365 token_create_body = token_create_pb2 .TokenCreateTransactionBody (
323366 name = self ._token_params .token_name ,
324367 symbol = self ._token_params .token_symbol ,
325368 decimals = self ._token_params .decimals ,
326369 initialSupply = self ._token_params .initial_supply ,
327370 tokenType = token_type_value ,
371+ supplyType = supply_type_value ,
372+ maxSupply = self ._token_params .max_supply ,
373+ freezeDefault = self ._token_params .freeze_default ,
328374 treasury = self ._token_params .treasury_account_id .to_proto (),
329375 adminKey = admin_key_proto ,
330376 supplyKey = supply_key_proto ,
@@ -358,25 +404,5 @@ def _execute_transaction(self, client, transaction_proto):
358404 raise Exception (f"Error during transaction submission: { error_code } ({ error_message } )" )
359405
360406 receipt = self .get_receipt (client )
361-
362-
363-
364-
365-
366-
367-
368-
369-
370-
371-
372-
373-
374-
375-
376-
377-
378-
379-
380-
381407 return receipt
382408
0 commit comments