Skip to content

Commit

Permalink
Merge pull request #26 from Layr-Labs/fireblocks-credentials-secret-m…
Browse files Browse the repository at this point in the history
…anager

Read fireblocks credentials from aws secret manager
  • Loading branch information
ian-shim authored Apr 3, 2024
2 parents 2c8dd5d + 55caa18 commit 1651a5d
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 26 deletions.
31 changes: 31 additions & 0 deletions flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,43 @@ var (
Value: 3,
EnvVar: envVarPrefix + "RETRY_SYNC_N_TIMES",
}
UseFireblocksFlag = cli.BoolTFlag{
Name: "use-fireblocks",
Usage: "Use Fireblocks to sign transactions. Ignores ecdsa-private-key. Fireblocks credentials must be provided.",
Required: false,
EnvVar: envVarPrefix + "USE_FIREBLOCKS",
}
SecretManagerRegionFlag = cli.StringFlag{
Name: "secret-manager-region",
Usage: "Region of the secret manager",
EnvVar: envVarPrefix + "SECRET_MANAGER_REGION",
}
SecretManagerEcdsaPrivateKeyNameFlag = cli.StringFlag{
Name: "secret-manager-ecdsa-private-key-name",
Usage: "Name of the secret in the secret manager that contains the Ethereum ecdsa private key. If not set, ecdsa-private-key must be specified.",
EnvVar: envVarPrefix + "SECRET_MANAGER_ECDSA_PRIVATE_KEY_NAME",
}
EcdsaPrivateKeyFlag = cli.StringFlag{
Name: "ecdsa-private-key",
Usage: "Ethereum ecdsa private key. If not set, Fireblocks credentials must be set.",
EnvVar: envVarPrefix + "ECDSA_PRIVATE_KEY",
}
// Fireblocks flags
SecretManagerFireblocksAPIKeyNameFlag = cli.StringFlag{
Name: "secret-manager-fireblocks-api-key-name",
Usage: "Name of the secret in the secret manager that contains the Fireblocks API Key.",
EnvVar: envVarPrefix + "SECRET_MANAGER_FIREBLOCKS_API_KEY_NAME",
}
FireblocksAPIKeyFlag = cli.StringFlag{
Name: "fireblocks-api-key",
Usage: "Fireblocks API Key. Ignored if ecdsa-private-key is set.",
EnvVar: envVarPrefix + "FIREBLOCKS_API_KEY",
}
SecretManagerFireblocksAPISecretNameFlag = cli.StringFlag{
Name: "secret-manager-fireblocks-api-secret-name",
Usage: "Name of the secret in the secret manager that contains the Fireblocks API Secret.",
EnvVar: envVarPrefix + "SECRET_MANAGER_FIREBLOCKS_API_SECRET_NAME",
}
FireblocksAPISecretPathFlag = cli.StringFlag{
Name: "fireblocks-api-secret-path",
Usage: "Path to Fireblocks API Secret. Ignored if ecdsa-private-key is set.",
Expand Down Expand Up @@ -126,8 +152,13 @@ var OptionalFlags = []cli.Flag{
ReaderTimeoutDurationFlag,
WriterTimeoutDurationFlag,
retrySyncNTimes,
UseFireblocksFlag,
SecretManagerRegionFlag,
SecretManagerEcdsaPrivateKeyNameFlag,
EcdsaPrivateKeyFlag,
SecretManagerFireblocksAPIKeyNameFlag,
FireblocksAPIKeyFlag,
SecretManagerFireblocksAPISecretNameFlag,
FireblocksAPISecretPathFlag,
FireblocksBaseURLFlag,
FireblocksVaultAccountNameFlag,
Expand Down
16 changes: 15 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/Layr-Labs/avs-sync
go 1.21.2

require (
github.com/Layr-Labs/eigensdk-go v0.1.4-0.20240329184527-d5c0a153a1c4
github.com/Layr-Labs/eigensdk-go v0.1.4-0.20240330002735-c0efcad71d31
github.com/ethereum/go-ethereum v1.13.14
github.com/prometheus/client_golang v1.19.0
github.com/testcontainers/testcontainers-go v0.29.1
Expand All @@ -17,6 +17,20 @@ require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.26.0 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.9 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.9 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 // indirect
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 // indirect
github.com/aws/smithy-go v1.20.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
Expand Down
32 changes: 30 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Layr-Labs/eigensdk-go v0.1.4-0.20240329184527-d5c0a153a1c4 h1:D58ekIT4cQlumjetYfwpzLeNHEOAYg/YjaB3LR2YxRY=
github.com/Layr-Labs/eigensdk-go v0.1.4-0.20240329184527-d5c0a153a1c4/go.mod h1:HOSNuZcwaKbP4cnNk9c1hK2B2RitcMQ36Xj2msBBBpE=
github.com/Layr-Labs/eigensdk-go v0.1.4-0.20240330002735-c0efcad71d31 h1:edCd/bQIrnlImZe6os35okWDb1I4S/QeQ4voF/xPhok=
github.com/Layr-Labs/eigensdk-go v0.1.4-0.20240330002735-c0efcad71d31/go.mod h1:HOSNuZcwaKbP4cnNk9c1hK2B2RitcMQ36Xj2msBBBpE=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
Expand All @@ -17,6 +17,34 @@ github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDO
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40=
github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o=
github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA=
github.com/aws/aws-sdk-go-v2 v1.26.0/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I=
github.com/aws/aws-sdk-go-v2/config v1.27.9 h1:gRx/NwpNEFSk+yQlgmk1bmxxvQ5TyJ76CWXs9XScTqg=
github.com/aws/aws-sdk-go-v2/config v1.27.9/go.mod h1:dK1FQfpwpql83kbD873E9vz4FyAxuJtR22wzoXn3qq0=
github.com/aws/aws-sdk-go-v2/credentials v1.17.9 h1:N8s0/7yW+h8qR8WaRlPQeJ6czVMNQVNtNdUqf6cItao=
github.com/aws/aws-sdk-go-v2/credentials v1.17.9/go.mod h1:446YhIdmSV0Jf/SLafGZalQo+xr2iw7/fzXGDPTU1yQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 h1:af5YzcLf80tv4Em4jWVD75lpnOHSBkPUZxZfGkrI3HI=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0/go.mod h1:nQ3how7DMnFMWiU1SpECohgC82fpn4cKZ875NDMmwtA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 h1:0ScVK/4qZ8CIW0k8jOeFVsyS/sAiXpYxRBLolMkuLQM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4/go.mod h1:84KyjNZdHC6QZW08nfHI6yZgPd+qRgaWcYsyLUo3QY8=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 h1:sHmMWWX5E7guWEFQ9SVo6A3S4xpPrWnd77a6y4WM6PU=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4/go.mod h1:WjpDrhWisWOIoS9n3nk67A3Ll1vfULJ9Kq6h29HTD48=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 h1:b+E7zIUHMmcB4Dckjpkapoy47W6C9QBv/zoUP+Hn8Kc=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6/go.mod h1:S2fNV0rxrP78NhPbCZeQgY8H9jdDMeGtwcfZIRxzBqU=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.5 h1:1i3Pq5g1NaXI/u8lTHRVMHyCc0HoZzSk2EFmiy14Hbk=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.5/go.mod h1:slgOMs1CQu8UVgwoFqEvCi71L4HVoZgM0r8MtcNP6Mc=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 h1:mnbuWHOcM70/OFUlZZ5rcdfA8PflGXXiefU/O+1S3+8=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.3/go.mod h1:5HFu51Elk+4oRBZVxmHrSds5jFXmFj8C3w7DVF2gnrs=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 h1:uLq0BKatTmDzWa/Nu4WO0M1AaQDaPpwTKAeByEc6WFM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3/go.mod h1:b+qdhjnxj8GSR6t5YfphOffeoQSQ1KmpoVVuBn+PWxs=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 h1:J/PpTf/hllOjx8Xu9DMflff3FajfLxqM5+tepvVXmxg=
github.com/aws/aws-sdk-go-v2/service/sts v1.28.5/go.mod h1:0ih0Z83YDH/QeQ6Ori2yGE2XvWYv/Xm+cZc01LC6oK0=
github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw=
github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88=
Expand Down
84 changes: 61 additions & 23 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package main

import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"log"
"os"
"time"

"github.com/Layr-Labs/eigensdk-go/aws/secretmanager"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/eth"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/fireblocks"
Expand Down Expand Up @@ -61,30 +63,46 @@ func avsSyncMain(cliCtx *cli.Context) error {
}

var wallet walletsdk.Wallet
operatorEcdsaPrivKeyHexStr := cliCtx.String(EcdsaPrivateKeyFlag.Name)
if len(operatorEcdsaPrivKeyHexStr) > 0 {
ecdsaPrivKey, err := crypto.HexToECDSA(operatorEcdsaPrivKeyHexStr)
if err != nil {
return fmt.Errorf("Cannot create ecdsa private key: %w", err)
if cliCtx.Bool(UseFireblocksFlag.Name) {
var apiKey string
var secretKey []byte
var err error

region := cliCtx.String(SecretManagerRegionFlag.Name)
if len(region) >= 0 {
logger.Info("Using secret manager to read fireblocks api key and secret")
smFireblocksAPIKeyName := cliCtx.String(SecretManagerFireblocksAPIKeyNameFlag.Name)
smFireblockAPISecretName := cliCtx.String(SecretManagerFireblocksAPISecretNameFlag.Name)
if len(smFireblocksAPIKeyName) > 0 && len(smFireblockAPISecretName) > 0 {
apiKey, err = secretmanager.ReadStringFromSecretManager(context.Background(), smFireblocksAPIKeyName, region)
if err != nil {
return fmt.Errorf("Cannot read fireblocks api key from secret manager: %w", err)
}
secretKeyStr, err := secretmanager.ReadStringFromSecretManager(context.Background(), smFireblockAPISecretName, region)
if err != nil {
return fmt.Errorf("Cannot read fireblocks secret from secret manager: %w", err)
}
secretKey = []byte(secretKeyStr)
}
}

signerV2, address, err := signerv2.SignerFromConfig(signerv2.Config{PrivateKey: ecdsaPrivKey}, chainid)
if err != nil {
return err
// If the secret manager values are not set, try to read from flags
if len(apiKey) == 0 || len(secretKey) == 0 {
logger.Info("Reading fireblocks api key and secret from flags")
apiKey = cliCtx.String(FireblocksAPIKeyFlag.Name)
secretPath := cliCtx.String(FireblocksAPISecretPathFlag.Name)
secretKey, err = os.ReadFile(secretPath)
if err != nil {
return fmt.Errorf("Cannot read fireblocks secret from %s: %w", secretPath, err)
}
}
wallet, err = walletsdk.NewPrivateKeyWallet(ethHttpClient, signerV2, address, logger)
if err != nil {
return err
}
} else {
fbAPIKey := cliCtx.String(FireblocksAPIKeyFlag.Name)
fbSecretPath := cliCtx.String(FireblocksAPISecretPathFlag.Name)

fbBaseURL := cliCtx.String(FireblocksBaseURLFlag.Name)
fbVaultAccountName := cliCtx.String(FireblocksVaultAccountNameFlag.Name)
if fbAPIKey == "" {
if apiKey == "" {
return errors.New("Fireblocks API key is not set")
}
if fbSecretPath == "" {
if len(secretKey) == 0 {
return errors.New("Fireblocks API secret is not set")
}
if fbBaseURL == "" {
Expand All @@ -94,13 +112,9 @@ func avsSyncMain(cliCtx *cli.Context) error {
return errors.New("Fireblocks vault account name is not set")
}

secretKey, err := os.ReadFile(fbSecretPath)
if err != nil {
return fmt.Errorf("Cannot read fireblocks secret from %s: %w", fbSecretPath, err)
}
fireblocksClient, err := fireblocks.NewClient(
fbAPIKey,
[]byte(secretKey),
apiKey,
secretKey,
fbBaseURL,
writerTimeout,
logger,
Expand All @@ -112,6 +126,30 @@ func avsSyncMain(cliCtx *cli.Context) error {
if err != nil {
return err
}
} else {
logger.Info("Using ecdsa private key to create wallet")
var ecdsaPrivKey *ecdsa.PrivateKey
smOperatorEcdsaPrivKeyHexStr := cliCtx.String(SecretManagerEcdsaPrivateKeyNameFlag.Name)
if len(smOperatorEcdsaPrivKeyHexStr) > 0 {
ecdsaPrivKey, err = crypto.HexToECDSA(smOperatorEcdsaPrivKeyHexStr)
if err != nil {
return fmt.Errorf("Cannot create ecdsa private key: %w", err)
}
} else {
operatorEcdsaPrivKeyHexStr := cliCtx.String(EcdsaPrivateKeyFlag.Name)
ecdsaPrivKey, err = crypto.HexToECDSA(operatorEcdsaPrivKeyHexStr)
if err != nil {
return fmt.Errorf("Cannot create ecdsa private key: %w", err)
}
}
signerV2, address, err := signerv2.SignerFromConfig(signerv2.Config{PrivateKey: ecdsaPrivKey}, chainid)
if err != nil {
return err
}
wallet, err = walletsdk.NewPrivateKeyWallet(ethHttpClient, signerV2, address, logger)
if err != nil {
return err
}
}

sender, err := wallet.SenderAddress(context.Background())
Expand Down

0 comments on commit 1651a5d

Please sign in to comment.