From 1930f44112ab2f23b6bfda1298a428430762b7d8 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Sat, 7 Dec 2024 14:01:48 -0800 Subject: [PATCH 1/5] feat: bls signer abstraction --- crypto/bls/attestation.go | 12 ++ signer/README.md | 19 ---- signer/basic_signer.go | 188 ------------------------------- signer/bls/cerberus/cerberus.go | 89 +++++++++++++++ signer/bls/errors.go | 7 ++ signer/bls/local/local.go | 42 +++++++ signer/bls/signer.go | 12 ++ signer/bls/types.go | 17 +++ signer/gen.go | 3 - signer/go.mod | 38 +++++++ signer/go.sum | 145 ++++++++++++++++++++++++ signer/mockdata/dummy.key.json | 1 - signer/mocks/signer.go | 72 ------------ signer/privatekey_signer.go | 71 ------------ signer/privatekey_signer_test.go | 88 --------------- signer/signer.go | 22 ---- 16 files changed, 362 insertions(+), 464 deletions(-) delete mode 100644 signer/README.md delete mode 100644 signer/basic_signer.go create mode 100644 signer/bls/cerberus/cerberus.go create mode 100644 signer/bls/errors.go create mode 100644 signer/bls/local/local.go create mode 100644 signer/bls/signer.go create mode 100644 signer/bls/types.go delete mode 100644 signer/gen.go create mode 100644 signer/go.mod create mode 100644 signer/go.sum delete mode 100644 signer/mockdata/dummy.key.json delete mode 100644 signer/mocks/signer.go delete mode 100644 signer/privatekey_signer.go delete mode 100644 signer/privatekey_signer_test.go delete mode 100644 signer/signer.go diff --git a/crypto/bls/attestation.go b/crypto/bls/attestation.go index 4de764d5..77ec287f 100644 --- a/crypto/bls/attestation.go +++ b/crypto/bls/attestation.go @@ -13,7 +13,10 @@ import ( "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254/fp" "github.com/consensys/gnark-crypto/ecc/bn254/fr" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" ) // We are using similar structure for saving bls keys as ethereum keystore @@ -282,3 +285,12 @@ func (k *KeyPair) GetPubKeyG2() *G2Point { func (k *KeyPair) GetPubKeyG1() *G1Point { return k.PubKey } + +// GetOperatorID hashes the G1Point (public key of an operator) to generate the operator ID. +// It does it to match how it's hashed in solidity: `keccak256(abi.encodePacked(pk.X, pk.Y))` +// Ref: https://github.com/Layr-Labs/eigenlayer-contracts/blob/avs-unstable/src/contracts/libraries/BN254.sol#L285 +func (p *G1Point) GetOperatorID() string { + x := p.X.BigInt(new(big.Int)) + y := p.Y.BigInt(new(big.Int)) + return crypto.Keccak256Hash(append(math.U256Bytes(x), math.U256Bytes(y)...)).Hex() +} diff --git a/signer/README.md b/signer/README.md deleted file mode 100644 index a7057dab..00000000 --- a/signer/README.md +++ /dev/null @@ -1,19 +0,0 @@ -## Signer - -> [!WARNING] -> signer is deprecated. Please use [signerv2](../signerv2/README.md) instead. - -This module is used for initializing the signer used to sign smart contract transactions. - -There are two types of signer we support -#### Private Key signer -This expects an ECDSA key as argument -``` -signer, err := NewPrivateKeySigner(privateKey, chainID) -``` - -#### Private key from local keystore -This expects a local path to encrypted ECDSA key json file and password to decrypt it. -``` -signer, err := NewPrivateKeyFromKeystoreSigner(path, password, chainID) -``` \ No newline at end of file diff --git a/signer/basic_signer.go b/signer/basic_signer.go deleted file mode 100644 index 8ff440bb..00000000 --- a/signer/basic_signer.go +++ /dev/null @@ -1,188 +0,0 @@ -package signer - -import ( - "context" - "crypto/ecdsa" - "fmt" - "math/big" - - "github.com/Layr-Labs/eigensdk-go/logging" - "github.com/Layr-Labs/eigensdk-go/utils" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - gethcommon "github.com/ethereum/go-ethereum/common" - gethtypes "github.com/ethereum/go-ethereum/core/types" -) - -// exported as the default so that users can call NewBasicSigner with it if they don't know any better -var FallbackGasTipCap = big.NewInt(15000000000) - -type ethClient interface { - bind.ContractBackend - - ChainID(ctx context.Context) (*big.Int, error) - TransactionReceipt(ctx context.Context, txHash gethcommon.Hash) (*gethtypes.Receipt, error) -} - -// Deprecated: Use SignerV2 instead -type BasicSigner struct { - logger logging.Logger - ethClient ethClient - privateKey *ecdsa.PrivateKey - accountAddress gethcommon.Address - contracts map[gethcommon.Address]*bind.BoundContract - fallbackGasTipCap *big.Int -} - -func NewBasicSigner( - privateKey *ecdsa.PrivateKey, - client ethClient, - logger logging.Logger, - fallbackGasTipCap *big.Int, -) (*BasicSigner, error) { - - accountAddress, err := utils.EcdsaPrivateKeyToAddress(privateKey) - if err != nil { - return nil, utils.WrapError("Cannot get account address", err) - } - - return &BasicSigner{ - logger: logger, - ethClient: client, - privateKey: privateKey, - accountAddress: accountAddress, - contracts: make(map[gethcommon.Address]*bind.BoundContract), - fallbackGasTipCap: fallbackGasTipCap, - }, nil -} - -// TODO: is this the right place to put this? -// -// it's needed when making calls calls using the bindings, eg -// AvsContractBindings.TaskManager.CreateNewTask(w.NoSendTransactOpts, numToSquare) -func (s *BasicSigner) GetNoSendTransactOpts() (*bind.TransactOpts, error) { - chainIDBigInt, err := s.ethClient.ChainID(context.Background()) - if err != nil { - return nil, utils.WrapError("Cannot get chainId", err) - } - opts, err := bind.NewKeyedTransactorWithChainID(s.privateKey, chainIDBigInt) - if err != nil { - return nil, utils.WrapError("Cannot create NoSendTransactOpts", err) - } - opts.NoSend = true - return opts, nil -} - -// EstimateGasPriceAndLimitAndSendTx sends and returns an otherwise identical txn -// to the one provided but with updated gas prices sampled from the existing network -// conditions and an accurate gasLimit -// -// Note: tx must be a to a contract, not an EOA -// -// Slightly modified from: -// https://github.com/ethereum-optimism/optimism/blob/ec266098641820c50c39c31048aa4e953bece464/batch-submitter/drivers/sequencer/driver.go#L314 -func (s *BasicSigner) EstimateGasPriceAndLimitAndSendTx( - ctx context.Context, - tx *gethtypes.Transaction, - tag string, -) (*gethtypes.Receipt, error) { - s.logger.Debug("Entering EstimateGasPriceAndLimitAndSendTx function...") - defer s.logger.Debug("Exiting EstimateGasPriceAndLimitAndSendTx function...") - - gasTipCap, err := s.ethClient.SuggestGasTipCap(ctx) - if err != nil { - // If the transaction failed because the backend does not support - // eth_maxPriorityFeePerGas, fallback to using the default constant. - // Currently Alchemy is the only backend provider that exposes this - // method, so in the event their API is unreachable we can fallback to a - // degraded mode of operation. This also applies to our test - // environments, as hardhat doesn't support the query either. - s.logger.Info("eth_maxPriorityFeePerGas is unsupported by current backend, using fallback gasTipCap") - gasTipCap = s.fallbackGasTipCap - } - - header, err := s.ethClient.HeaderByNumber(ctx, nil) - if err != nil { - return nil, err - } - gasFeeCap := new(big.Int).Add(header.BaseFee, gasTipCap) - - // The estimated gas limits performed by RawTransact fail semi-regularly - // with out of gas exceptions. To remedy this we extract the internal calls - // to perform gas price/gas limit estimation here and add a buffer to - // account for any network variability. - gasLimit, err := s.ethClient.EstimateGas(ctx, ethereum.CallMsg{ - From: s.accountAddress, - To: tx.To(), - GasTipCap: gasTipCap, - GasFeeCap: gasFeeCap, - Value: nil, - Data: tx.Data(), - }) - - if err != nil { - return nil, err - } - - opts, err := bind.NewKeyedTransactorWithChainID(s.privateKey, tx.ChainId()) - if err != nil { - return nil, utils.WrapError("Cannot create transactOpts", err) - } - opts.Context = ctx - opts.Nonce = new(big.Int).SetUint64(tx.Nonce()) - opts.GasTipCap = gasTipCap - opts.GasFeeCap = gasFeeCap - opts.GasLimit = addGasBuffer(gasLimit) - - contract := s.contracts[*tx.To()] - // if the contract has not been cached - if contract == nil { - // create a dummy bound contract tied to the `to` address of the transaction - contract = bind.NewBoundContract(*tx.To(), abi.ABI{}, s.ethClient, s.ethClient, s.ethClient) - // cache the contract for later use - s.contracts[*tx.To()] = contract - } - - tx, err = contract.RawTransact(opts, tx.Data()) - if err != nil { - return nil, utils.WrapError(fmt.Errorf("Failed to send transaction with tag: %v", tag), err) - } - - receipt, err := s.EnsureTransactionEvaled( - tx, - tag, - ) - if err != nil { - return nil, err - } - - return receipt, err -} - -func (s *BasicSigner) EnsureTransactionEvaled(tx *gethtypes.Transaction, tag string) (*gethtypes.Receipt, error) { - receipt, err := bind.WaitMined(context.Background(), s.ethClient, tx) - if err != nil { - return nil, utils.WrapError(fmt.Errorf("Failed to wait for transaction to mine with tag: %v", tag), err) - } - if receipt.Status != 1 { - return nil, fmt.Errorf( - "Transaction failed (tag: %v, txHash: %v, status: %v, gasUsed: %v)", - tag, - tx.Hash().Hex(), - receipt.Status, - receipt.GasUsed, - ) - } - s.logger.Debug("successfully submitted transaction", - "txHash", receipt.TxHash.Hex(), - "tag", tag, - "gasUsed", receipt.GasUsed, - ) - return receipt, nil -} - -func addGasBuffer(gasLimit uint64) uint64 { - return 6 * gasLimit / 5 // add 20% buffer to gas limit -} diff --git a/signer/bls/cerberus/cerberus.go b/signer/bls/cerberus/cerberus.go new file mode 100644 index 00000000..7c49bc3c --- /dev/null +++ b/signer/bls/cerberus/cerberus.go @@ -0,0 +1,89 @@ +package cerberus + +import ( + "context" + "encoding/hex" + "fmt" + "log" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + sdkBls "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/eigensdk-go/signer/bls" + + v1 "github.com/Layr-Labs/cerberus-api/pkg/api/v1" +) + +type Config struct { + URL string + PublicKeyHex string + + // Optional: in case if your signer uses local keystore + Password string + + EnableTLS bool + TLSCertFilePath string + + SigningTimeout time.Duration +} + +type Signer struct { + client v1.SignerClient + pubKeyHex string + password string +} + +func New(cfg Config) (Signer, error) { + opts := make([]grpc.DialOption, 0) + if cfg.EnableTLS { + creds, err := credentials.NewClientTLSFromFile(cfg.TLSCertFilePath, "") + if err != nil { + log.Fatalf("could not load tls cert: %s", err) + } + opts = append(opts, grpc.WithTransportCredentials(creds)) + } + + conn, err := grpc.NewClient(cfg.URL, opts...) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + + client := v1.NewSignerClient(conn) + return Signer{ + client: client, + pubKeyHex: cfg.PublicKeyHex, + password: cfg.Password, + }, nil +} + +func (s *Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { + if len(msg) != 32 { + return nil, bls.ErrInvalidMessageLength + } + + var data [32]byte + copy(data[:], msg) + + resp, err := s.client.SignGeneric(ctx, &v1.SignGenericRequest{ + Data: data[:], + PublicKey: s.pubKeyHex, + Password: s.password, + }) + if err != nil { + return nil, err + } + + return resp.Signature, nil +} + +func (s *Signer) GetOperatorId() (string, error) { + pkBytes, err := hex.DecodeString(s.pubKeyHex) + if err != nil { + return "", fmt.Errorf("failed to decode BLS public key: %w", err) + } + pubkey := new(sdkBls.G1Point) + publicKey := pubkey.Deserialize(pkBytes) + return publicKey.GetOperatorID(), nil +} diff --git a/signer/bls/errors.go b/signer/bls/errors.go new file mode 100644 index 00000000..1e249d55 --- /dev/null +++ b/signer/bls/errors.go @@ -0,0 +1,7 @@ +package bls + +import "errors" + +var ( + ErrInvalidMessageLength = errors.New("invalid message length. must be 32 bytes") +) diff --git a/signer/bls/local/local.go b/signer/bls/local/local.go new file mode 100644 index 00000000..c389fa58 --- /dev/null +++ b/signer/bls/local/local.go @@ -0,0 +1,42 @@ +package local + +import ( + "context" + + sdkBls "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/eigensdk-go/signer/bls" +) + +type Config struct { + Path string + Password string +} + +type Signer struct { + key *sdkBls.KeyPair +} + +func New(cfg Config) *Signer { + keyPair, err := sdkBls.ReadPrivateKeyFromFile(cfg.Path, cfg.Password) + if err != nil { + return nil + } + return &Signer{ + key: keyPair, + } +} + +func (s *Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { + if len(msg) != 32 { + return nil, bls.ErrInvalidMessageLength + } + + var data [32]byte + copy(data[:], msg) + + return s.key.SignMessage(data).Serialize(), nil +} + +func (s *Signer) GetOperatorId() (string, error) { + return s.key.PubKey.GetOperatorID(), nil +} diff --git a/signer/bls/signer.go b/signer/bls/signer.go new file mode 100644 index 00000000..a9d80d0a --- /dev/null +++ b/signer/bls/signer.go @@ -0,0 +1,12 @@ +package bls + +import "context" + +type Signer interface { + // Sign signs the message using the BLS signature scheme + Sign(ctx context.Context, msg []byte) ([]byte, error) + + // GetOperatorId returns the operator ID of the signer. + // This is hash of the G1 public key of the signer + GetOperatorId() (string, error) +} diff --git a/signer/bls/types.go b/signer/bls/types.go new file mode 100644 index 00000000..ce62d2d1 --- /dev/null +++ b/signer/bls/types.go @@ -0,0 +1,17 @@ +package bls + +type SignerConfig struct { + // Local keystore params + // Path to the key file + Path string + // Password to decrypt the key file + Password string + + // Params for cerberus signer + // CerberusUrl of the cerberus signer + CerberusUrl string + // PublicKeyHex is the public key of the cerberus signer + PublicKeyHex string + // CerberusPassword is the password to encrypt the key if cerberus using local keystore + CerberusPassword string +} diff --git a/signer/gen.go b/signer/gen.go deleted file mode 100644 index b85daadf..00000000 --- a/signer/gen.go +++ /dev/null @@ -1,3 +0,0 @@ -package signer - -//go:generate mockgen -destination=./mocks/signer.go -package=mocks github.com/Layr-Labs/eigensdk-go/signer Signer diff --git a/signer/go.mod b/signer/go.mod new file mode 100644 index 00000000..2e2af7c2 --- /dev/null +++ b/signer/go.mod @@ -0,0 +1,38 @@ +module github.com/Layr-Labs/eigensdk-go/signer + +go 1.21 + +replace github.com/Layr-Labs/eigensdk-go => ../../eigensdk-go + +require ( + github.com/Layr-Labs/cerberus-api v0.0.1 + github.com/Layr-Labs/eigensdk-go v0.1.13 + google.golang.org/grpc v1.64.1 +) + +require ( + github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-ethereum v1.14.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/supranational/blst v0.3.11 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.17.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) diff --git a/signer/go.sum b/signer/go.sum new file mode 100644 index 00000000..b1459292 --- /dev/null +++ b/signer/go.sum @@ -0,0 +1,145 @@ +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/cerberus-api v0.0.1 h1:MSLVdxtRS1qnwLks3COnnUw/M3tjLGtbSGaLde86HRg= +github.com/Layr-Labs/cerberus-api v0.0.1/go.mod h1:Lm4fhzy0S3P7GjerzuseGaBFVczsIKmEhIjcT52Hluo= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +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/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= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= +github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.0 h1:pcFh8CdCIt2kmEpK0OIatq67Ln9uGDYY3d5XnE0LJG4= +github.com/cockroachdb/pebble v1.1.0/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.0 h1:xRWC5NlB6g1x7vNy4HDBLuqVNbtLrc7v8S6+Uxim1LU= +github.com/ethereum/go-ethereum v1.14.0/go.mod h1:1STrq471D0BQbCX9He0hUj4bHxX2k6mt5nOQJhDNOJ8= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/signer/mockdata/dummy.key.json b/signer/mockdata/dummy.key.json deleted file mode 100644 index f9a4685e..00000000 --- a/signer/mockdata/dummy.key.json +++ /dev/null @@ -1 +0,0 @@ -{"address":"d4ee935d77b590aa64aed7b02dd66f1383006684","crypto":{"cipher":"aes-128-ctr","ciphertext":"10eca95bf52cb5baab31cb49045ddbe9bcb00b6e91564d5116ca85033577576e","cipherparams":{"iv":"7ab87b9ea99fcb66e7228d8ab49ae941"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"7712a47bbd000afcb603c9bb9fb06125a117fa34b34c7770aee03f22b7179648"},"mac":"2a4dea47769b5707382403378a92e61d2a182860438e1cbceac35117b0d1e482"},"id":"11fdd2cd-7f1e-4f31-834c-5fa98d7cd06d","version":3} \ No newline at end of file diff --git a/signer/mocks/signer.go b/signer/mocks/signer.go deleted file mode 100644 index ccaf9cae..00000000 --- a/signer/mocks/signer.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Layr-Labs/eigensdk-go/signer (interfaces: Signer) -// -// Generated by this command: -// -// mockgen -destination=./mocks/signer.go -package=mocks github.com/Layr-Labs/eigensdk-go/signer Signer -// - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - reflect "reflect" - - bind "github.com/ethereum/go-ethereum/accounts/abi/bind" - common "github.com/ethereum/go-ethereum/common" - types "github.com/ethereum/go-ethereum/core/types" - gomock "go.uber.org/mock/gomock" -) - -// MockSigner is a mock of Signer interface. -type MockSigner struct { - ctrl *gomock.Controller - recorder *MockSignerMockRecorder -} - -// MockSignerMockRecorder is the mock recorder for MockSigner. -type MockSignerMockRecorder struct { - mock *MockSigner -} - -// NewMockSigner creates a new mock instance. -func NewMockSigner(ctrl *gomock.Controller) *MockSigner { - mock := &MockSigner{ctrl: ctrl} - mock.recorder = &MockSignerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSigner) EXPECT() *MockSignerMockRecorder { - return m.recorder -} - -// GetTxOpts mocks base method. -func (m *MockSigner) GetTxOpts() *bind.TransactOpts { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTxOpts") - ret0, _ := ret[0].(*bind.TransactOpts) - return ret0 -} - -// GetTxOpts indicates an expected call of GetTxOpts. -func (mr *MockSignerMockRecorder) GetTxOpts() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxOpts", reflect.TypeOf((*MockSigner)(nil).GetTxOpts)) -} - -// SendToExternal mocks base method. -func (m *MockSigner) SendToExternal(arg0 context.Context, arg1 *types.Transaction) (common.Hash, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendToExternal", arg0, arg1) - ret0, _ := ret[0].(common.Hash) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SendToExternal indicates an expected call of SendToExternal. -func (mr *MockSignerMockRecorder) SendToExternal(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendToExternal", reflect.TypeOf((*MockSigner)(nil).SendToExternal), arg0, arg1) -} diff --git a/signer/privatekey_signer.go b/signer/privatekey_signer.go deleted file mode 100644 index 4e532c5a..00000000 --- a/signer/privatekey_signer.go +++ /dev/null @@ -1,71 +0,0 @@ -package signer - -import ( - "context" - "crypto/ecdsa" - "errors" - "math/big" - "os" - "path/filepath" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -// Deprecated: Use SignerV2 instead -type PrivateKeySigner struct { - txOpts *bind.TransactOpts -} - -var _ Signer = (*PrivateKeySigner)(nil) - -func NewPrivateKeySigner(privateKey *ecdsa.PrivateKey, chainID *big.Int) (Signer, error) { - // TODO (madhur): chainId should not be hardcoded - txOpts, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID) - if err != nil { - return nil, err - } - return &PrivateKeySigner{ - txOpts: txOpts, - }, nil -} - -func NewPrivateKeyFromKeystoreSigner(path string, password string, chainID *big.Int) (Signer, error) { - privateKey, err := getECDSAPrivateKey(path, password) - if err != nil { - return nil, err - } - - // TODO (madhur): chainId should not be hardcoded - txOpts, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID) - if err != nil { - return nil, err - } - return &PrivateKeySigner{ - txOpts: txOpts, - }, nil -} - -func (p *PrivateKeySigner) GetTxOpts() *bind.TransactOpts { - return p.txOpts -} - -func (p *PrivateKeySigner) SendToExternal(ctx context.Context, tx *types.Transaction) (common.Hash, error) { - return common.Hash{}, errors.New("this signer does not support external signing") -} - -func getECDSAPrivateKey(keyStoreFile string, password string) (*ecdsa.PrivateKey, error) { - keyStoreContents, err := os.ReadFile(filepath.Clean(keyStoreFile)) - if err != nil { - return nil, err - } - - sk, err := keystore.DecryptKey(keyStoreContents, password) - if err != nil { - return nil, err - } - - return sk.PrivateKey, nil -} diff --git a/signer/privatekey_signer_test.go b/signer/privatekey_signer_test.go deleted file mode 100644 index 6f77cf28..00000000 --- a/signer/privatekey_signer_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package signer - -import ( - "crypto/ecdsa" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/stretchr/testify/assert" -) - -func TestPrivateKeySigner(t *testing.T) { - privateKey, err := crypto.GenerateKey() - assert.NoError(t, err) - - tests := map[string]struct { - privateKey *ecdsa.PrivateKey - chainID *big.Int - success bool - }{ - "Successful initialization": { - privateKey: privateKey, - chainID: big.NewInt(5), - success: true, - }, - "Failure with Invalid network": { - privateKey: privateKey, - success: false, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - _, err := NewPrivateKeySigner(test.privateKey, test.chainID) - if test.success { - assert.NoError(t, err) - return - } else { - assert.Error(t, err) - } - }) - } -} - -func TestPrivateKeyFromKeystoreSigner(t *testing.T) { - tests := map[string]struct { - path string - password string - chainID *big.Int - success bool - }{ - "Successful initialization": { - path: "./mockdata/dummy.key.json", - password: "test12345", - chainID: big.NewInt(5), - success: true, - }, - "Failure with Invalid network": { - path: "./mockdata/dummy.key.json", - password: "test12345", - success: false, - }, - "Failure with Invalid password": { - path: "./mockdata/dummy.key.json", - password: "wrong_password", - chainID: big.NewInt(5), - success: false, - }, - "Failure with unknown path": { - path: "./mockdata/wrongfile.key.json", - password: "test12345", - chainID: big.NewInt(5), - success: false, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - _, err := NewPrivateKeyFromKeystoreSigner(test.path, test.password, test.chainID) - if test.success { - assert.NoError(t, err) - return - } else { - assert.Error(t, err) - } - }) - } -} diff --git a/signer/signer.go b/signer/signer.go deleted file mode 100644 index 1c8573b3..00000000 --- a/signer/signer.go +++ /dev/null @@ -1,22 +0,0 @@ -package signer - -import ( - "context" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -// Signer is an interface that defines the methods that a signer must implement. -// There are two kinds of signer. -// 1. A signer that can implement a Signer function and return the signed transaction. -// They need to implement GetSigner() function and leave SendToExternal() unimplemented. -// -// 2. A signer (remote signer) that we will send to an external rpc which takes care of signing and broadcasting the -// signed transaction. They need to implement SendToExternal() function and leave GetSigner() unimplemented. -// Deprecated: Use SignerV2 instead -type Signer interface { - GetTxOpts() *bind.TransactOpts - SendToExternal(ctx context.Context, tx *types.Transaction) (common.Hash, error) -} From 7c3be6176b67b9f1885d8ab4ccae36cfaa82e72c Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Sat, 7 Dec 2024 14:20:06 -0800 Subject: [PATCH 2/5] refactor to resolve import cycle --- signer/bls/cerberus/cerberus.go | 4 ++-- signer/bls/local/local.go | 14 +++++++------- signer/bls/signer.go | 29 ++++++++++++++++++++++++++++- signer/bls/{ => types}/errors.go | 3 ++- signer/bls/{ => types}/types.go | 20 ++++++++++++++++++-- 5 files changed, 57 insertions(+), 13 deletions(-) rename signer/bls/{ => types}/errors.go (59%) rename signer/bls/{ => types}/types.go (51%) diff --git a/signer/bls/cerberus/cerberus.go b/signer/bls/cerberus/cerberus.go index 7c49bc3c..b852de59 100644 --- a/signer/bls/cerberus/cerberus.go +++ b/signer/bls/cerberus/cerberus.go @@ -58,7 +58,7 @@ func New(cfg Config) (Signer, error) { }, nil } -func (s *Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { +func (s Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { if len(msg) != 32 { return nil, bls.ErrInvalidMessageLength } @@ -78,7 +78,7 @@ func (s *Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { return resp.Signature, nil } -func (s *Signer) GetOperatorId() (string, error) { +func (s Signer) GetOperatorId() (string, error) { pkBytes, err := hex.DecodeString(s.pubKeyHex) if err != nil { return "", fmt.Errorf("failed to decode BLS public key: %w", err) diff --git a/signer/bls/local/local.go b/signer/bls/local/local.go index c389fa58..74272b29 100644 --- a/signer/bls/local/local.go +++ b/signer/bls/local/local.go @@ -4,7 +4,7 @@ import ( "context" sdkBls "github.com/Layr-Labs/eigensdk-go/crypto/bls" - "github.com/Layr-Labs/eigensdk-go/signer/bls" + "github.com/Layr-Labs/eigensdk-go/signer/bls/types" ) type Config struct { @@ -16,19 +16,19 @@ type Signer struct { key *sdkBls.KeyPair } -func New(cfg Config) *Signer { +func New(cfg Config) (*Signer, error) { keyPair, err := sdkBls.ReadPrivateKeyFromFile(cfg.Path, cfg.Password) if err != nil { - return nil + return nil, err } return &Signer{ key: keyPair, - } + }, nil } -func (s *Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { +func (s Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { if len(msg) != 32 { - return nil, bls.ErrInvalidMessageLength + return nil, types.ErrInvalidMessageLength } var data [32]byte @@ -37,6 +37,6 @@ func (s *Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { return s.key.SignMessage(data).Serialize(), nil } -func (s *Signer) GetOperatorId() (string, error) { +func (s Signer) GetOperatorId() (string, error) { return s.key.PubKey.GetOperatorID(), nil } diff --git a/signer/bls/signer.go b/signer/bls/signer.go index a9d80d0a..0b0a78c8 100644 --- a/signer/bls/signer.go +++ b/signer/bls/signer.go @@ -1,6 +1,12 @@ package bls -import "context" +import ( + "context" + + "github.com/Layr-Labs/eigensdk-go/signer/bls/cerberus" + "github.com/Layr-Labs/eigensdk-go/signer/bls/local" + "github.com/Layr-Labs/eigensdk-go/signer/bls/types" +) type Signer interface { // Sign signs the message using the BLS signature scheme @@ -10,3 +16,24 @@ type Signer interface { // This is hash of the G1 public key of the signer GetOperatorId() (string, error) } + +// NewSigner creates a new signer based on the config +func NewSigner(cfg types.SignerConfig) (Signer, error) { + switch cfg.SignerType { + case types.Local: + return local.New(local.Config{ + Path: cfg.Path, + Password: cfg.Password, + }) + case types.Cerberus: + return cerberus.New(cerberus.Config{ + URL: cfg.CerberusUrl, + PublicKeyHex: cfg.PublicKeyHex, + Password: cfg.CerberusPassword, + EnableTLS: cfg.EnableTLS, + TLSCertFilePath: cfg.TLSCertFilePath, + }) + default: + return nil, types.ErrInvalidSignerType + } +} diff --git a/signer/bls/errors.go b/signer/bls/types/errors.go similarity index 59% rename from signer/bls/errors.go rename to signer/bls/types/errors.go index 1e249d55..e53631ae 100644 --- a/signer/bls/errors.go +++ b/signer/bls/types/errors.go @@ -1,7 +1,8 @@ -package bls +package types import "errors" var ( ErrInvalidMessageLength = errors.New("invalid message length. must be 32 bytes") + ErrInvalidSignerType = errors.New("invalid signer type") ) diff --git a/signer/bls/types.go b/signer/bls/types/types.go similarity index 51% rename from signer/bls/types.go rename to signer/bls/types/types.go index ce62d2d1..8f486405 100644 --- a/signer/bls/types.go +++ b/signer/bls/types/types.go @@ -1,7 +1,19 @@ -package bls +package types + +type SignerType string + +const ( + // Local signer type + Local SignerType = "local" + // Cerberus signer type + Cerberus SignerType = "cerberus" +) type SignerConfig struct { - // Local keystore params + // Type of the signer + SignerType SignerType + + // Params for local signer // Path to the key file Path string // Password to decrypt the key file @@ -14,4 +26,8 @@ type SignerConfig struct { PublicKeyHex string // CerberusPassword is the password to encrypt the key if cerberus using local keystore CerberusPassword string + // EnableTLS enables TLS for the cerberus signer + EnableTLS bool + // TLSCertFilePath is the path to the TLS cert file + TLSCertFilePath string } From 0f669dbe48dcb5780c38360208a80b8b0e724030 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Sat, 7 Dec 2024 14:22:36 -0800 Subject: [PATCH 3/5] doc --- signer/bls/signer.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/signer/bls/signer.go b/signer/bls/signer.go index 0b0a78c8..7bf2c14c 100644 --- a/signer/bls/signer.go +++ b/signer/bls/signer.go @@ -17,7 +17,15 @@ type Signer interface { GetOperatorId() (string, error) } -// NewSigner creates a new signer based on the config +// NewSigner creates a new Signer instance based on the provided configuration. +// It supports different types of signers, such as Local and Cerberus. +// +// Parameters: +// - cfg: A SignerConfig struct that contains the configuration for the signer. +// +// Returns: +// - Signer: An instance of the Signer interface. +// - error: An error if the signer type is invalid or if there is an issue creating the signer. func NewSigner(cfg types.SignerConfig) (Signer, error) { switch cfg.SignerType { case types.Local: From 577e26ef0df0d2a90687a3153804c769169c9c29 Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Sat, 7 Dec 2024 14:39:31 -0800 Subject: [PATCH 4/5] fix: imports --- signer/bls/cerberus/cerberus.go | 4 ++-- signer/bls/types/types.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/signer/bls/cerberus/cerberus.go b/signer/bls/cerberus/cerberus.go index b852de59..39239e2a 100644 --- a/signer/bls/cerberus/cerberus.go +++ b/signer/bls/cerberus/cerberus.go @@ -11,7 +11,7 @@ import ( "google.golang.org/grpc/credentials" sdkBls "github.com/Layr-Labs/eigensdk-go/crypto/bls" - "github.com/Layr-Labs/eigensdk-go/signer/bls" + "github.com/Layr-Labs/eigensdk-go/signer/bls/types" v1 "github.com/Layr-Labs/cerberus-api/pkg/api/v1" ) @@ -60,7 +60,7 @@ func New(cfg Config) (Signer, error) { func (s Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { if len(msg) != 32 { - return nil, bls.ErrInvalidMessageLength + return nil, types.ErrInvalidMessageLength } var data [32]byte diff --git a/signer/bls/types/types.go b/signer/bls/types/types.go index 8f486405..1148c642 100644 --- a/signer/bls/types/types.go +++ b/signer/bls/types/types.go @@ -12,7 +12,7 @@ const ( type SignerConfig struct { // Type of the signer SignerType SignerType - + // Params for local signer // Path to the key file Path string From c5ffb53d14b0345214fcf6019337eadbbcf1661b Mon Sep 17 00:00:00 2001 From: Madhur Shrimal Date: Wed, 11 Dec 2024 13:34:46 -0800 Subject: [PATCH 5/5] add a public key method --- signer/bls/cerberus/cerberus.go | 4 ++++ signer/bls/local/local.go | 5 +++++ signer/bls/signer.go | 2 ++ 3 files changed, 11 insertions(+) diff --git a/signer/bls/cerberus/cerberus.go b/signer/bls/cerberus/cerberus.go index 39239e2a..0b318516 100644 --- a/signer/bls/cerberus/cerberus.go +++ b/signer/bls/cerberus/cerberus.go @@ -87,3 +87,7 @@ func (s Signer) GetOperatorId() (string, error) { publicKey := pubkey.Deserialize(pkBytes) return publicKey.GetOperatorID(), nil } + +func (s Signer) GetPublicKeyHex() string { + return s.pubKeyHex +} diff --git a/signer/bls/local/local.go b/signer/bls/local/local.go index 74272b29..1c942057 100644 --- a/signer/bls/local/local.go +++ b/signer/bls/local/local.go @@ -2,6 +2,7 @@ package local import ( "context" + "encoding/hex" sdkBls "github.com/Layr-Labs/eigensdk-go/crypto/bls" "github.com/Layr-Labs/eigensdk-go/signer/bls/types" @@ -40,3 +41,7 @@ func (s Signer) Sign(ctx context.Context, msg []byte) ([]byte, error) { func (s Signer) GetOperatorId() (string, error) { return s.key.PubKey.GetOperatorID(), nil } + +func (s Signer) GetPublicKeyHex() string { + return hex.EncodeToString(s.key.PubKey.Serialize()) +} diff --git a/signer/bls/signer.go b/signer/bls/signer.go index 7bf2c14c..cc6025ef 100644 --- a/signer/bls/signer.go +++ b/signer/bls/signer.go @@ -15,6 +15,8 @@ type Signer interface { // GetOperatorId returns the operator ID of the signer. // This is hash of the G1 public key of the signer GetOperatorId() (string, error) + + GetPublicKeyHex() string } // NewSigner creates a new Signer instance based on the provided configuration.