From 6fb57aab7d1310109127c86e64c7638977e729e5 Mon Sep 17 00:00:00 2001 From: Shawn <44221603+shaspitz@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:50:00 -0800 Subject: [PATCH] user cli with env (#25) --- standard/bridge-v1/Dockerfile.user | 4 +- standard/bridge-v1/README.md | 38 +++--- standard/bridge-v1/cmd/user_cli/main.go | 112 ++++++++---------- standard/bridge-v1/docker-compose.yml | 11 +- .../bridge-v1/example_config/user_config.yml | 8 -- standard/bridge-v1/example_config/user_key | 1 - 6 files changed, 87 insertions(+), 87 deletions(-) delete mode 100644 standard/bridge-v1/example_config/user_config.yml delete mode 100644 standard/bridge-v1/example_config/user_key diff --git a/standard/bridge-v1/Dockerfile.user b/standard/bridge-v1/Dockerfile.user index af27962..172d74e 100644 --- a/standard/bridge-v1/Dockerfile.user +++ b/standard/bridge-v1/Dockerfile.user @@ -8,7 +8,5 @@ RUN CGO_ENABLED=0 make user-cli FROM alpine:latest COPY --from=builder /app/bin/user_cli /usr/local/bin/user_cli -COPY --from=builder /app/example_config/user_config.yml /example_config/user_config.yml -COPY --from=builder /app/example_config/user_key /example_config/user_key -ENTRYPOINT ["user_cli", "bridge-to-settlement", "--amount", "2", "--dest-addr", "0xeE5d6F3eeF0ecB6EcbaCd51B7E3350B84882bc85", "--config", "/example_config/user_config.yml", "--cancel-pending"] +ENTRYPOINT ["user_cli", "bridge-to-settlement", "--amount", "2", "--dest-addr", "0xeE5d6F3eeF0ecB6EcbaCd51B7E3350B84882bc85", "--cancel-pending"] diff --git a/standard/bridge-v1/README.md b/standard/bridge-v1/README.md index 2cf4348..6f35987 100644 --- a/standard/bridge-v1/README.md +++ b/standard/bridge-v1/README.md @@ -4,29 +4,39 @@ This document outlines multiple iteration plans for a simple lock and mint bridg ## User Quickstart -To bridge from L1 to the mev-commit chain, first configure a yaml file with the format found at `example_config/user_config.yml`, example below: - -```yaml -priv_key_file: "example_config/user_key" # Relative path from working dir -log_level: "debug" -l1_rpc_url: "http://localhost:9545" -settlement_rpc_url: "http://localhost:8545" -l1_chain_id: 39999 -settlement_chain_id: 17864 -l1_contract_addr: "0x1a18dfEc4f2B66207b1Ad30aB5c7A0d62Ef4A40b" -settlement_contract_addr: "0xc1f93bE11D7472c9B9a4d87B41dD0a491F1fbc75" +First build the user cli for your machine from this directory: +```bash +make user_cli +``` + +Set proper environment variables for a cross-chain transfer, example below: + +```bash +export PRIVATE_KEY="0xe82a054e06f89598485134b4f2ce8a612ce7f7f7e14e650f9f20b30efddd0e57" +export LOG_LEVEL="debug" +export L1_RPC_URL="https://ethereum-holesky.publicnode.com" +export SETTLEMENT_RPC_URL="https://chainrpc.testnet.mev-commit.xyz" +export L1_CHAIN_ID="17000" +export SETTLEMENT_CHAIN_ID="17864" +export L1_CONTRACT_ADDR="0xceff0a364f63f621ff6a8b5ce56569ec6f3c6220" +export SETTLEMENT_CONTRACT_ADDR="0xf60f8e762a3fe90fd4d8c005872b6f6e12eda8ca" ``` -To build the user cli, and make a cross chain transfer: +To bridge ether from Holesky to the mev-commit chain, use: ```bash -make user_cli +./bin/user_cli bridge-to-settlement --amount $AMOUNT_IN_WEI --dest-addr $DEST_ADDR ``` +Where `PRIVATE_KEY` corresponds to an account that's funded on Holesky. + +To bridge ether back to Holesky from the mev-commit chain, use: + ```bash -./bin/user_cli bridge-to-l1 --amount $AMOUNT --dest-addr $DEST_ADDR --config "example_config/user_config.yml" +./bin/user_cli bridge-to-l1 --amount $AMOUNT_IN_WEI --dest-addr $DEST_ADDR ``` +Where `PRIVATE_KEY` corresponds to an account that's funded on the mev-commit chain. ## Relayer diff --git a/standard/bridge-v1/cmd/user_cli/main.go b/standard/bridge-v1/cmd/user_cli/main.go index 3c01652..df11cd3 100644 --- a/standard/bridge-v1/cmd/user_cli/main.go +++ b/standard/bridge-v1/cmd/user_cli/main.go @@ -6,9 +6,9 @@ import ( "fmt" "math/big" "os" - "path/filepath" "standard-bridge/pkg/shared" transfer "standard-bridge/pkg/transfer" + "strconv" "strings" "github.com/ethereum/go-ethereum/common" @@ -17,16 +17,6 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/urfave/cli/v2" - "gopkg.in/yaml.v2" -) - -var ( - optionConfig = &cli.StringFlag{ - Name: "config", - Usage: "path to CLI config file", - Required: true, - EnvVars: []string{"STANDARD_BRIDGE_CLI_CONFIG"}, - } ) func main() { @@ -52,7 +42,6 @@ func main() { Name: "cancel-pending", Usage: "Automatically cancel existing pending transactions", }, - optionConfig, }, Action: func(c *cli.Context) error { return bridgeToSettlement(c) @@ -76,7 +65,6 @@ func main() { Name: "cancel-pending", Usage: "Automatically cancel existing pending transactions", }, - optionConfig, }, Action: func(c *cli.Context) error { return bridgeToL1(c) @@ -146,41 +134,15 @@ type preTransferConfig struct { } func preTransfer(c *cli.Context) preTransferConfig { + cfg := loadConfigFromEnv() - configFilePath := c.String(optionConfig.Name) - - var cfg config - buf, err := os.ReadFile(configFilePath) - if err != nil { - log.Fatal().Err(err).Msg("failed to read config file at: " + configFilePath) - } - - if err := yaml.Unmarshal(buf, &cfg); err != nil { - log.Fatal().Err(err).Msg("failed to unmarshal config file at: " + configFilePath) - } - - if err := checkConfig(&cfg); err != nil { + if err := checkEnvConfig(&cfg); err != nil { log.Fatal().Err(err).Msg("invalid config") } + setupLogging(cfg.LogLevel) - lvl, err := zerolog.ParseLevel(cfg.LogLevel) - if err != nil { - log.Fatal().Err(err).Msg("failed to parse log level") - } - zerolog.SetGlobalLevel(lvl) - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) - - privKeyFile := cfg.PrivKeyFile - if strings.HasPrefix(privKeyFile, "~/") { - homeDir, err := os.UserHomeDir() - if err != nil { - log.Err(err).Msg("failed to get user home dir") - } - privKeyFile = filepath.Join(homeDir, privKeyFile[2:]) - } - - privKey, err := crypto.LoadECDSA(privKeyFile) + privKeyTrimmed := strings.TrimPrefix(cfg.PrivKey, "0x") + privKey, err := crypto.HexToECDSA(privKeyTrimmed) if err != nil { log.Err(err).Msg("failed to load private key") } @@ -206,20 +168,44 @@ func preTransfer(c *cli.Context) preTransferConfig { } } -type config struct { - PrivKeyFile string `yaml:"priv_key_file"` - LogLevel string `yaml:"log_level" json:"log_level"` - L1RPCUrl string `yaml:"l1_rpc_url"` - SettlementRPCUrl string `yaml:"settlement_rpc_url"` - L1ChainID int `yaml:"l1_chain_id"` - SettlementChainID int `yaml:"settlement_chain_id"` - L1ContractAddr string `yaml:"l1_contract_addr"` - SettlementContractAddr string `yaml:"settlement_contract_addr"` +type envConfig struct { + PrivKey string + LogLevel string + L1RPCUrl string + SettlementRPCUrl string + L1ChainID int + SettlementChainID int + L1ContractAddr string + SettlementContractAddr string } -func checkConfig(cfg *config) error { - if cfg.PrivKeyFile == "" { - return fmt.Errorf("priv_key_file is required") +func loadConfigFromEnv() envConfig { + l1ChainID := os.Getenv("L1_CHAIN_ID") + l1ChainIDInt, err := strconv.Atoi(l1ChainID) + if err != nil { + log.Fatal().Err(err).Msg("failed to convert L1_CHAIN_ID to int") + } + settlementChainID := os.Getenv("SETTLEMENT_CHAIN_ID") + settlementChainIDInt, err := strconv.Atoi(settlementChainID) + if err != nil { + log.Fatal().Err(err).Msg("failed to convert SETTLEMENT_CHAIN_ID to int") + } + cfg := envConfig{ + PrivKey: os.Getenv("PRIVATE_KEY"), + LogLevel: os.Getenv("LOG_LEVEL"), + L1RPCUrl: os.Getenv("L1_RPC_URL"), + SettlementRPCUrl: os.Getenv("SETTLEMENT_RPC_URL"), + L1ChainID: l1ChainIDInt, + SettlementChainID: settlementChainIDInt, + L1ContractAddr: os.Getenv("L1_CONTRACT_ADDR"), + SettlementContractAddr: os.Getenv("SETTLEMENT_CONTRACT_ADDR"), + } + return cfg +} + +func checkEnvConfig(cfg *envConfig) error { + if cfg.PrivKey == "" { + return fmt.Errorf("private_key is required") } if cfg.LogLevel == "" { cfg.LogLevel = "info" @@ -236,8 +222,6 @@ func checkConfig(cfg *config) error { if !common.IsHexAddress(cfg.L1ContractAddr) || !common.IsHexAddress(cfg.SettlementContractAddr) { return fmt.Errorf("both l1_contract_addr and settlement_contract_addr must be valid hex addresses") } - - // Create clients via url and cross check with expected chain id l1Client, err := ethclient.Dial(cfg.L1RPCUrl) if err != nil { return fmt.Errorf("failed to create l1 client: %v", err) @@ -249,7 +233,6 @@ func checkConfig(cfg *config) error { if obtainedL1ChainID.Cmp(big.NewInt(int64(cfg.L1ChainID))) != 0 { log.Fatal().Msgf("l1 chain id mismatch. Expected: %d, Obtained: %d", cfg.L1ChainID, obtainedL1ChainID) } - settlementClient, err := ethclient.Dial(cfg.SettlementRPCUrl) if err != nil { return fmt.Errorf("failed to create settlement client: %v", err) @@ -261,10 +244,19 @@ func checkConfig(cfg *config) error { if obtainedSettlementChainID.Cmp(big.NewInt(int64(cfg.SettlementChainID))) != 0 { log.Fatal().Msgf("settlement chain id mismatch. Expected: %d, Obtained: %d", cfg.SettlementChainID, obtainedSettlementChainID) } - return nil } +func setupLogging(logLevel string) { + lvl, err := zerolog.ParseLevel(logLevel) + if err != nil { + log.Fatal().Err(err).Msg("failed to parse log level") + } + zerolog.SetGlobalLevel(lvl) + zerolog.TimeFieldFormat = zerolog.TimeFormatUnix + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout}) +} + func handlePendingTxes( ctx context.Context, privateKey *ecdsa.PrivateKey, diff --git a/standard/bridge-v1/docker-compose.yml b/standard/bridge-v1/docker-compose.yml index 9cc2f3a..67da471 100644 --- a/standard/bridge-v1/docker-compose.yml +++ b/standard/bridge-v1/docker-compose.yml @@ -6,7 +6,7 @@ services: dockerfile: Dockerfile.relayer networks: primev_net: - ipv4_address: '172.29.0.102' + ipv4_address: '172.29.0.117' geth-poa_l1_net: ipv4_address: '172.14.0.5' @@ -15,6 +15,15 @@ services: build: context: . dockerfile: Dockerfile.user + environment: + PRIVATE_KEY: "0xe82a054e06f89598485134b4f2ce8a612ce7f7f7e14e650f9f20b30efddd0e57" + LOG_LEVEL: "debug" + L1_RPC_URL: "http://l1-bootnode:8545" + SETTLEMENT_RPC_URL: "http://sl-bootnode:8545" + L1_CHAIN_ID: "39999" + SETTLEMENT_CHAIN_ID: "17864" + L1_CONTRACT_ADDR: "0x1a18dfEc4f2B66207b1Ad30aB5c7A0d62Ef4A40b" + SETTLEMENT_CONTRACT_ADDR: "0xc1f93bE11D7472c9B9a4d87B41dD0a491F1fbc75" networks: primev_net: ipv4_address: '172.29.0.103' diff --git a/standard/bridge-v1/example_config/user_config.yml b/standard/bridge-v1/example_config/user_config.yml deleted file mode 100644 index 6f0b3c7..0000000 --- a/standard/bridge-v1/example_config/user_config.yml +++ /dev/null @@ -1,8 +0,0 @@ -priv_key_file: "example_config/user_key" # Relative path from working dir -log_level: "debug" -l1_rpc_url: "http://l1-bootnode:8545" -settlement_rpc_url: "http://sl-bootnode:8545" -l1_chain_id: 39999 -settlement_chain_id: 17864 -l1_contract_addr: "0x1a18dfEc4f2B66207b1Ad30aB5c7A0d62Ef4A40b" -settlement_contract_addr: "0xc1f93bE11D7472c9B9a4d87B41dD0a491F1fbc75" diff --git a/standard/bridge-v1/example_config/user_key b/standard/bridge-v1/example_config/user_key deleted file mode 100644 index 8e1e2ab..0000000 --- a/standard/bridge-v1/example_config/user_key +++ /dev/null @@ -1 +0,0 @@ -e82a054e06f89598485134b4f2ce8a612ce7f7f7e14e650f9f20b30efddd0e57