Skip to content

Commit dc0d8c6

Browse files
committed
chore: wip
1 parent 33a4d3a commit dc0d8c6

File tree

3 files changed

+494
-48
lines changed

3 files changed

+494
-48
lines changed

cmd/sequence/config.go

Lines changed: 180 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
85163
func 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

Comments
 (0)