@@ -626,40 +626,61 @@ def _load_registry_type_map(self, registry):
626
626
registry_type_map = {}
627
627
type_id_to_name = {}
628
628
types = json .loads (registry .registry )["types" ]
629
+ type_by_id = {entry ["id" ]: entry for entry in types }
630
+
631
+ # Pass 1: Gather simple types
629
632
for type_entry in types :
630
- type_type = type_entry ["type" ]
631
633
type_id = type_entry ["id" ]
632
- type_def = type_type ["def" ]
633
- 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
- )
634
+ type_def = type_entry ["type" ]["def" ]
635
+ type_path = type_entry ["type" ].get ("path" )
636
+ if type_entry .get ("params" ) or "variant" in type_def :
638
637
continue
639
- if type_entry .get ("params" ) or type_def .get ("variant" ):
640
- continue # has generics or is Enum
641
638
if type_path :
642
639
type_name = type_path [- 1 ]
643
640
registry_type_map [type_name ] = type_id
644
641
type_id_to_name [type_id ] = type_name
645
642
else :
646
- # probably primitive
647
- if type_def .get ("primitive" ):
648
- type_name = type_def ["primitive" ]
649
- registry_type_map [type_name ] = type_id
650
- type_id_to_name [type_id ] = type_name
651
- for type_entry in types :
652
- type_type = type_entry ["type" ]
653
- type_id = type_entry ["id" ]
654
- type_def = type_type ["def" ]
655
- if type_def .get ("sequence" ):
643
+ # Possibly a primitive
644
+ if "primitive" in type_def :
645
+ prim_name = type_def ["primitive" ]
646
+ registry_type_map [prim_name ] = type_id
647
+ type_id_to_name [type_id ] = prim_name
648
+
649
+ # Pass 2: Resolve remaining types
650
+ pending_ids = set (type_by_id .keys ()) - set (type_id_to_name .keys ())
651
+
652
+ def resolve_type_definition (type_id ):
653
+ type_entry = type_by_id [type_id ]
654
+ type_def = type_entry ["type" ]["def" ]
655
+ type_path = type_entry ["type" ].get ("path" , [])
656
+ type_params = type_entry ["type" ].get ("params" , [])
657
+
658
+ if type_id in type_id_to_name :
659
+ return type_id_to_name [type_id ]
660
+
661
+ # Resolve complex types with paths (including generics like Option etc)
662
+ if type_path :
663
+ type_name = type_path [- 1 ]
664
+ if type_params :
665
+ inner_names = []
666
+ for param in type_params :
667
+ dep_id = param ["type" ]
668
+ if dep_id not in type_id_to_name :
669
+ return None
670
+ inner_names .append (type_id_to_name [dep_id ])
671
+ return f"{ type_name } <{ ', ' .join (inner_names )} >"
672
+ if "variant" in type_def :
673
+ return None
674
+ return type_name
675
+
676
+ elif "sequence" in type_def :
656
677
sequence_type_id = type_def ["sequence" ]["type" ]
657
678
inner_type = type_id_to_name .get (sequence_type_id )
658
679
if inner_type :
659
680
type_name = f"Vec<{ inner_type } >"
660
- type_id_to_name [ type_id ] = type_name
661
- registry_type_map [ type_name ] = type_id
662
- elif type_def . get ( "array" ) :
681
+ return type_name
682
+
683
+ elif "array" in type_def :
663
684
array_type_id = type_def ["array" ]["type" ]
664
685
inner_type = type_id_to_name .get (array_type_id )
665
686
maybe_len = type_def ["array" ].get ("len" )
@@ -668,45 +689,44 @@ def _load_registry_type_map(self, registry):
668
689
type_name = f"[{ inner_type } ; { maybe_len } ]"
669
690
else :
670
691
type_name = f"[{ inner_type } ]"
671
- type_id_to_name [ type_id ] = type_name
672
- registry_type_map [ type_name ] = type_id
673
- elif type_def . get ( "compact" ) :
692
+ return type_name
693
+
694
+ elif "compact" in type_def :
674
695
compact_type_id = type_def ["compact" ]["type" ]
675
696
inner_type = type_id_to_name .get (compact_type_id )
676
697
if inner_type :
677
698
type_name = f"Compact<{ inner_type } >"
678
- type_id_to_name [ type_id ] = type_name
679
- registry_type_map [ type_name ] = type_id
680
- elif type_def . get ( "tuple" ) :
699
+ return type_name
700
+
701
+ elif "tuple" in type_def :
681
702
tuple_type_ids = type_def ["tuple" ]
682
703
type_names = []
683
704
for inner_type_id in tuple_type_ids :
684
- inner_type = type_id_to_name . get ( inner_type_id )
685
- if inner_type :
686
- type_names .append (inner_type )
705
+ if inner_type_id not in type_id_to_name :
706
+ return None
707
+ type_names .append (type_id_to_name [ inner_type_id ] )
687
708
type_name = ", " .join (type_names )
688
709
type_name = f"({ type_name } )"
689
- type_id_to_name [type_id ] = type_name
690
- registry_type_map [type_name ] = type_id
691
- self .registry_type_map = registry_type_map
692
- self .type_id_to_name = type_id_to_name
710
+ return type_name
693
711
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"
712
+ elif "variant" in type_def :
713
+ return None
707
714
708
- registry_type_map [type_name ] = type_id
709
- type_id_to_name [type_id ] = type_name
715
+ return None
716
+
717
+ resolved_type = True
718
+ while resolved_type and pending_ids :
719
+ resolved_type = False
720
+ for type_id in list (pending_ids ):
721
+ name = resolve_type_definition (type_id )
722
+ if name is not None :
723
+ type_id_to_name [type_id ] = name
724
+ registry_type_map [name ] = type_id
725
+ pending_ids .remove (type_id )
726
+ resolved_type = True
727
+
728
+ self .registry_type_map = registry_type_map
729
+ self .type_id_to_name = type_id_to_name
710
730
711
731
def reload_type_registry (
712
732
self , use_remote_preset : bool = True , auto_discover : bool = True
@@ -836,11 +856,10 @@ def _encode_scale(self, type_string, value: Any) -> bytes:
836
856
)
837
857
except KeyError :
838
858
vec_acct_id = "scale_info::152"
839
-
840
859
try :
841
860
optional_acct_u16 = f"scale_info::{ self .registry_type_map ['Option<(AccountId32, u16)>' ]} "
842
861
except KeyError :
843
- optional_acct_u16 = "scale_info::573 "
862
+ optional_acct_u16 = "scale_info::579 "
844
863
845
864
if type_string == "scale_info::0" : # Is an AccountId
846
865
# encode string into AccountId
0 commit comments