@@ -631,6 +631,11 @@ def _load_registry_type_map(self, registry):
631631 type_id = type_entry ["id" ]
632632 type_def = type_type ["def" ]
633633 type_path = type_type .get ("path" )
634+ if type_path and type_path [- 1 ] == "Option" :
635+ self ._handle_option_type (
636+ type_entry , type_id , registry_type_map , type_id_to_name
637+ )
638+ continue
634639 if type_entry .get ("params" ) or type_def .get ("variant" ):
635640 continue # has generics or is Enum
636641 if type_path :
@@ -686,6 +691,23 @@ def _load_registry_type_map(self, registry):
686691 self .registry_type_map = registry_type_map
687692 self .type_id_to_name = type_id_to_name
688693
694+ def _handle_option_type (
695+ self , type_entry , type_id , registry_type_map , type_id_to_name
696+ ):
697+ params = type_entry ["type" ].get ("params" , [])
698+ if params :
699+ inner_names = []
700+ for param in params :
701+ inner_id = param ["type" ]
702+ inner_name = type_id_to_name .get (inner_id , f"Type{ inner_id } " )
703+ inner_names .append (inner_name )
704+ type_name = f"Option<{ ', ' .join (inner_names )} >"
705+ else :
706+ type_name = "Option"
707+
708+ registry_type_map [type_name ] = type_id
709+ type_id_to_name [type_id ] = type_name
710+
689711 def reload_type_registry (
690712 self , use_remote_preset : bool = True , auto_discover : bool = True
691713 ):
@@ -815,10 +837,28 @@ def _encode_scale(self, type_string, value: Any) -> bytes:
815837 except KeyError :
816838 vec_acct_id = "scale_info::152"
817839
840+ try :
841+ optional_acct_u16 = f"scale_info::{ self .registry_type_map ['Option<(AccountId32, u16)>' ]} "
842+ except KeyError :
843+ optional_acct_u16 = "scale_info::573"
844+
818845 if type_string == "scale_info::0" : # Is an AccountId
819846 # encode string into AccountId
820847 ## AccountId is a composite type with one, unnamed field
821- return bytes .fromhex (ss58_decode (value , SS58_FORMAT ))
848+ return self ._encode_account_id (value )
849+
850+ elif type_string == optional_acct_u16 :
851+ if value is None :
852+ return b"\x00 " # None
853+
854+ if not isinstance (value , (list , tuple )) or len (value ) != 2 :
855+ raise ValueError ("Expected tuple of (account_id, u16)" )
856+ account_id , u16_value = value
857+
858+ result = b"\x01 "
859+ result += self ._encode_account_id (account_id )
860+ result += u16_value .to_bytes (2 , "little" )
861+ return result
822862
823863 elif type_string == vec_acct_id : # Vec<AccountId>
824864 if not isinstance (value , (list , tuple )):
@@ -833,12 +873,7 @@ def _encode_scale(self, type_string, value: Any) -> bytes:
833873
834874 # Encode each AccountId
835875 for account in value :
836- if isinstance (account , bytes ):
837- result += account # Already encoded
838- else :
839- result += bytes .fromhex (
840- ss58_decode (account , SS58_FORMAT )
841- ) # SS58 string
876+ result += self ._encode_account_id (account )
842877 return result
843878
844879 if isinstance (value , ScaleType ):
@@ -852,3 +887,16 @@ def _encode_scale(self, type_string, value: Any) -> bytes:
852887 encode_by_type_string (type_string , self .runtime .registry , value )
853888 )
854889 return result
890+
891+ def _encode_account_id (self , account ) -> bytes :
892+ """Encode an account ID into bytes.
893+
894+ Args:
895+ account: Either bytes (already encoded) or SS58 string
896+
897+ Returns:
898+ bytes: The encoded account ID
899+ """
900+ if isinstance (account , bytes ):
901+ return account # Already encoded
902+ return bytes .fromhex (ss58_decode (account , SS58_FORMAT )) # SS58 string
0 commit comments