Skip to content

Commit 89f4abc

Browse files
authored
fix: export chainInfo into outputs artifacts (#248)
<!-- 🚨 ATTENTION! 🚨 This PR template is REQUIRED. PRs not following this format will be closed without review. Requirements: - PR title must follow commit conventions: https://www.conventionalcommits.org/en/v1.0.0/ - Label your PR with the correct type (e.g., 🐛 Bug, ✨ Enhancement, 🧪 Test, etc.) - Provide clear and specific details in each section --> **Motivation:** <!-- Explain here the context, and why you're making that change. What is the problem you're trying to solve. --> As a devkit developer, I want consolidated outputs containing all information I would need to import into my app space, so that I do not need to pull details from multiple sources. **Modifications:** <!-- Describe the modifications you've done from a high level. What are the key technical decisions and why were they made? --> - Exports `chainInfo` into L1/L2 deployment outputs **Result:** <!-- *After your change, what will change. --> - Able to import contracts address, abi and chainId from a single output **Testing:** <!-- *List testing procedures taken and useful artifacts. --> - Tested against `hotdog-havoc`
1 parent 3810bd6 commit 89f4abc

File tree

2 files changed

+75
-15
lines changed

2 files changed

+75
-15
lines changed

pkg/commands/deploy_actions.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"math/big"
1010
"os"
1111
"path/filepath"
12+
"strconv"
1213
"strings"
1314
"time"
1415

@@ -34,9 +35,14 @@ type DeployContractTransport struct {
3435
}
3536

3637
type DeployContractJson struct {
37-
Name string `json:"name"`
38-
Address string `json:"address"`
39-
ABI interface{} `json:"abi"`
38+
Name string `json:"name"`
39+
Address string `json:"address"`
40+
ABI interface{} `json:"abi"`
41+
ChainInfo ChainInfo `json:"chainInfo"`
42+
}
43+
44+
type ChainInfo struct {
45+
ChainId int64 `json:"chainId"`
4046
}
4147

4248
func StartDeployL1Action(cCtx *cli.Context) error {
@@ -409,7 +415,14 @@ func DeployL1ContractsAction(cCtx *cli.Context) error {
409415
if err := contracts.Decode(&contractsList); err != nil {
410416
return fmt.Errorf("decode deployed_l1_contracts: %w", err)
411417
}
412-
err = extractContractOutputs(cCtx, contextName, contractsList)
418+
// Get the chainId
419+
chainId := common.GetChildByKey(contextNode, "chains.l1.chain_id")
420+
if chainId == nil {
421+
return fmt.Errorf("chains.l1.chain_id node not found")
422+
}
423+
// Title line to split these logs from the main body for easy identification
424+
logger.Title("Save L1 contract artifacts")
425+
err = extractContractOutputs(cCtx, contextName, contractsList, chainId.Value)
413426
if err != nil {
414427
return fmt.Errorf("failed to write l1 contract artefacts: %w", err)
415428
}
@@ -515,9 +528,14 @@ func DeployL2ContractsAction(cCtx *cli.Context) error {
515528
if err := contracts.Decode(&contractsList); err != nil {
516529
return fmt.Errorf("decode deployed_l2_contracts: %w", err)
517530
}
518-
// Empty log line to split these logs from the main body for easy identification
519-
logger.Title("Save l2 contract artifacts")
520-
err = extractContractOutputs(cCtx, contextName, contractsList)
531+
// Get the chainId
532+
chainId := common.GetChildByKey(contextNode, "chains.l2.chain_id")
533+
if chainId == nil {
534+
return fmt.Errorf("chains.l2.chain_id node not found")
535+
}
536+
// Title line to split these logs from the main body for easy identification
537+
logger.Title("Save L2 contract artifacts")
538+
err = extractContractOutputs(cCtx, contextName, contractsList, chainId.Value)
521539
if err != nil {
522540
return fmt.Errorf("failed to write l2 contract artefacts: %w", err)
523541
}
@@ -839,7 +857,7 @@ func FetchZeusAddressesAction(cCtx *cli.Context) error {
839857
return nil
840858
}
841859

842-
func extractContractOutputs(cCtx *cli.Context, context string, contractsList []DeployContractTransport) error {
860+
func extractContractOutputs(cCtx *cli.Context, context string, contractsList []DeployContractTransport, chainId string) error {
843861
logger := common.LoggerFromContext(cCtx.Context)
844862

845863
// Push contract artefacts to ./contracts/outputs
@@ -848,6 +866,12 @@ func extractContractOutputs(cCtx *cli.Context, context string, contractsList []D
848866
return fmt.Errorf("create output dir: %w", err)
849867
}
850868

869+
// Convert chainId to int
870+
chainIdInt, err := strconv.ParseInt(chainId, 10, 64)
871+
if err != nil {
872+
return fmt.Errorf("failed to convert chainId: %w", err)
873+
}
874+
851875
// For each contract extract details and produce json file in outputs/<context>/<contract.name>.json
852876
for _, contract := range contractsList {
853877
nameVal := contract.Name
@@ -885,6 +909,9 @@ func extractContractOutputs(cCtx *cli.Context, context string, contractsList []D
885909
Name: nameVal,
886910
Address: addressVal,
887911
ABI: abi.ABI,
912+
ChainInfo: ChainInfo{
913+
ChainId: chainIdInt,
914+
},
888915
}
889916

890917
// Marshal with indentation

pkg/common/yaml.go

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,50 @@ func CleanYAML(v interface{}) interface{} {
163163
}
164164

165165
// GetChildByKey returns the value node associated with the given key from a MappingNode
166-
func GetChildByKey(node *yaml.Node, key string) *yaml.Node {
167-
if node == nil || node.Kind != yaml.MappingNode {
166+
func GetChildByKey(node *yaml.Node, path string) *yaml.Node {
167+
if node == nil {
168168
return nil
169169
}
170-
for i := 0; i < len(node.Content); i += 2 {
171-
k := node.Content[i]
172-
if k.Value == key {
173-
return node.Content[i+1]
170+
currNode := node
171+
for _, seg := range strings.Split(path, ".") {
172+
// map lookup part before any index
173+
key, segIdx := seg, -1
174+
if idx := strings.Index(seg, "["); idx >= 0 {
175+
key = seg[:idx]
176+
closeIdxOffset := strings.Index(seg[idx:], "]")
177+
if closeIdxOffset <= 1 {
178+
return nil
179+
}
180+
idxVal, err := strconv.Atoi(seg[idx+1 : idx+closeIdxOffset])
181+
if err != nil {
182+
return nil
183+
}
184+
segIdx = idxVal
185+
}
186+
if key != "" {
187+
if currNode.Kind != yaml.MappingNode {
188+
return nil
189+
}
190+
found := false
191+
for idx := 0; idx+1 < len(currNode.Content); idx += 2 {
192+
if currNode.Content[idx].Value == key {
193+
currNode = currNode.Content[idx+1]
194+
found = true
195+
break
196+
}
197+
}
198+
if !found {
199+
return nil
200+
}
201+
}
202+
if segIdx >= 0 {
203+
if currNode.Kind != yaml.SequenceNode || segIdx < 0 || segIdx >= len(currNode.Content) {
204+
return nil
205+
}
206+
currNode = currNode.Content[segIdx]
174207
}
175208
}
176-
return nil
209+
return currNode
177210
}
178211

179212
// CloneNode performs a deep copy of a *yaml.Node, including its content and comments

0 commit comments

Comments
 (0)