@@ -82,6 +82,84 @@ type TopologyOutput struct {
8282 Weight string `json:"weight,omitempty"`
8383}
8484
85+ func toInt64 (value interface {}) (int64 , error ) {
86+ switch v := value .(type ) {
87+ case string :
88+ n := new (big.Int )
89+ if _ , ok := n .SetString (v , 10 ); ! ok {
90+ return 0 , fmt .Errorf ("invalid number: %s" , v )
91+ }
92+ return n .Int64 (), nil
93+ case float64 :
94+ return int64 (v ), nil
95+ case int64 :
96+ return v , nil
97+ default :
98+ return 0 , fmt .Errorf ("cannot convert %v to int64" , value )
99+ }
100+ }
101+
102+ func convertTree (item map [string ]interface {}) (map [string ]interface {}, error ) {
103+ treeType , ok := item ["type" ].(string )
104+ if ! ok {
105+ return nil , fmt .Errorf ("missing 'type' in tree item" )
106+ }
107+
108+ switch treeType {
109+ case "signer" :
110+ weight , err := toInt64 (item ["weight" ])
111+ if err != nil {
112+ return nil , fmt .Errorf ("invalid weight: %w" , err )
113+ }
114+ return map [string ]interface {}{
115+ "weight" : weight ,
116+ "address" : item ["address" ],
117+ }, nil
118+
119+ case "subdigest" :
120+ return map [string ]interface {}{
121+ "subdigest" : item ["digest" ],
122+ }, nil
123+
124+ case "sapient-signer" :
125+ weight , err := toInt64 (item ["weight" ])
126+ if err != nil {
127+ return nil , fmt .Errorf ("invalid weight: %w" , err )
128+ }
129+ return map [string ]interface {}{
130+ "weight" : weight ,
131+ "address" : item ["address" ],
132+ "imageHash" : item ["imageHash" ],
133+ }, nil
134+
135+ case "nested" :
136+ weight , err := toInt64 (item ["weight" ])
137+ if err != nil {
138+ return nil , fmt .Errorf ("invalid weight: %w" , err )
139+ }
140+ threshold , err := toInt64 (item ["threshold" ])
141+ if err != nil {
142+ return nil , fmt .Errorf ("invalid threshold: %w" , err )
143+ }
144+ nestedTree , ok := item ["tree" ].(map [string ]interface {})
145+ if ! ok {
146+ return nil , fmt .Errorf ("missing or invalid 'tree' in nested item" )
147+ }
148+ convertedTree , err := convertTree (nestedTree )
149+ if err != nil {
150+ return nil , fmt .Errorf ("failed to convert nested tree: %w" , err )
151+ }
152+ return map [string ]interface {}{
153+ "weight" : weight ,
154+ "threshold" : threshold ,
155+ "tree" : convertedTree ,
156+ }, nil
157+
158+ default :
159+ return nil , fmt .Errorf ("unknown tree type: %s" , treeType )
160+ }
161+ }
162+
85163func treeToMap (tree v3.WalletConfigTree ) TopologyOutput {
86164 switch t := tree .(type ) {
87165 case * v3.WalletConfigTreeAddressLeaf :
@@ -342,30 +420,54 @@ func calculateImageHash(params *ConfigImageHashParams) (string, error) {
342420 rawConfig = input
343421 }
344422
345- // Convert topology to tree if present
346- if topology , ok := rawConfig ["topology" ].(map [string ]interface {}); ok {
347- // Convert topology to the expected tree format
348- treeConfig := make (map [string ]interface {})
349- if topology ["type" ] == "signer" {
350- // Convert string weight to int64
351- if weight , ok := topology ["weight" ].(string ); ok {
352- weightInt := new (big.Int )
353- if _ , ok := weightInt .SetString (weight , 10 ); ! ok {
354- return "" , fmt .Errorf ("invalid weight: %s" , weight )
423+ // Convert topology array to tree structure
424+ if topology , ok := rawConfig ["topology" ].([]interface {}); ok {
425+ // Create a tree structure from the topology array
426+ tree := make (map [string ]interface {})
427+ for i , row := range topology {
428+ rowArray , ok := row .([]interface {})
429+ if ! ok {
430+ continue
431+ }
432+ for j , item := range rowArray {
433+ itemMap , ok := item .(map [string ]interface {})
434+ if ! ok {
435+ continue
355436 }
356- if ! weightInt .IsInt64 () {
357- return "" , fmt .Errorf ("weight too large: %s" , weight )
437+
438+ // Convert topology item to tree node
439+ node := make (map [string ]interface {})
440+ switch itemMap ["type" ] {
441+ case "signer" :
442+ node ["weight" ] = itemMap ["weight" ]
443+ node ["address" ] = itemMap ["address" ]
444+ case "subdigest" :
445+ node ["subdigest" ] = itemMap ["digest" ]
446+ case "sapient-signer" :
447+ node ["weight" ] = itemMap ["weight" ]
448+ node ["address" ] = itemMap ["address" ]
449+ node ["imageHash" ] = itemMap ["imageHash" ]
450+ case "nested" :
451+ if nestedTree , ok := itemMap ["tree" ].(map [string ]interface {}); ok {
452+ node ["weight" ] = nestedTree ["weight" ]
453+ node ["threshold" ] = nestedTree ["threshold" ]
454+ node ["tree" ] = nestedTree ["tree" ]
455+ }
456+ }
457+
458+ // Add node to the tree
459+ if i == 0 && j == 0 {
460+ tree = node
461+ } else {
462+ // Create a new node with left and right branches
463+ newNode := make (map [string ]interface {})
464+ newNode ["left" ] = tree
465+ newNode ["right" ] = node
466+ tree = newNode
358467 }
359- treeConfig ["weight" ] = weightInt .Int64 ()
360- } else {
361- treeConfig ["weight" ] = topology ["weight" ]
362468 }
363- treeConfig ["address" ] = topology ["address" ]
364- } else {
365- // Handle other types if needed
366- return "" , fmt .Errorf ("unsupported topology type: %v" , topology ["type" ])
367469 }
368- rawConfig ["tree" ] = treeConfig
470+ rawConfig ["tree" ] = tree
369471 delete (rawConfig , "topology" )
370472 }
371473
@@ -388,11 +490,69 @@ func encodeConfig(params *ConfigEncodeParams) (string, error) {
388490 return "" , fmt .Errorf ("failed to parse raw config: %w" , err )
389491 }
390492
493+ // Check if the config is nested under an "input" field
494+ if input , ok := rawConfig ["input" ].(map [string ]interface {}); ok {
495+ rawConfig = input
496+ }
497+
498+ // Convert topology array to tree structure matching TypeScript
499+ if topology , ok := rawConfig ["topology" ].([]interface {}); ok {
500+ if len (topology ) != 2 {
501+ return "" , fmt .Errorf ("expected exactly two rows in topology" )
502+ }
503+
504+ var subtrees []map [string ]interface {}
505+ for i , row := range topology {
506+ rowArray , ok := row .([]interface {})
507+ if ! ok || len (rowArray ) != 2 {
508+ return "" , fmt .Errorf ("each topology row must have exactly two elements" )
509+ }
510+
511+ leftItem , ok := rowArray [0 ].(map [string ]interface {})
512+ if ! ok {
513+ return "" , fmt .Errorf ("invalid left item in topology row %d" , i )
514+ }
515+ leftNode , err := convertTree (leftItem )
516+ if err != nil {
517+ return "" , fmt .Errorf ("failed to convert left tree item in row %d: %w" , i , err )
518+ }
519+
520+ rightItem , ok := rowArray [1 ].(map [string ]interface {})
521+ if ! ok {
522+ return "" , fmt .Errorf ("invalid right item in topology row %d" , i )
523+ }
524+ rightNode , err := convertTree (rightItem )
525+ if err != nil {
526+ return "" , fmt .Errorf ("failed to convert right tree item in row %d: %w" , i , err )
527+ }
528+
529+ subtree := map [string ]interface {}{
530+ "left" : leftNode ,
531+ "right" : rightNode ,
532+ }
533+ subtrees = append (subtrees , subtree )
534+ }
535+
536+ if len (subtrees ) != 2 {
537+ return "" , fmt .Errorf ("expected exactly two subtrees from topology" )
538+ }
539+
540+ tree := map [string ]interface {}{
541+ "left" : subtrees [0 ],
542+ "right" : subtrees [1 ],
543+ }
544+
545+ rawConfig ["tree" ] = tree
546+ delete (rawConfig , "topology" )
547+ }
548+
391549 config , err := v3 .Core .DecodeWalletConfig (rawConfig )
392550 if err != nil {
393551 return "" , fmt .Errorf ("failed to decode wallet config: %w" , err )
394552 }
395553
554+ spew .Dump (config )
555+
396556 sig , err := config .BuildNoChainIDSignature (context .Background (), func (ctx context.Context , signer common.Address , sigs []core.SignerSignature ) (core.SignerSignatureType , []byte , error ) {
397557 return 0 , nil , core .ErrSigningNoSigner
398558 }, false )
0 commit comments