github.com/cgcardona/r-subnet-evm@v0.1.5/cmd/simulator/key/key.go (about)

     1  // (c) 2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package key
     5  
     6  import (
     7  	"context"
     8  	"crypto/ecdsa"
     9  	"fmt"
    10  	"os"
    11  	"path/filepath"
    12  
    13  	"github.com/ethereum/go-ethereum/common"
    14  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    15  )
    16  
    17  type Key struct {
    18  	PrivKey *ecdsa.PrivateKey
    19  	Address common.Address
    20  }
    21  
    22  func createKey(pk *ecdsa.PrivateKey) *Key {
    23  	return &Key{pk, ethcrypto.PubkeyToAddress(pk.PublicKey)}
    24  }
    25  
    26  // Load attempts to open a [Key] stored at [file].
    27  func Load(file string) (*Key, error) {
    28  	pk, err := ethcrypto.LoadECDSA(file)
    29  	if err != nil {
    30  		return nil, fmt.Errorf("problem loading private key from %s: %w", file, err)
    31  	}
    32  	return createKey(pk), nil
    33  }
    34  
    35  // LoadAll loads all keys in [dir].
    36  func LoadAll(ctx context.Context, dir string) ([]*Key, error) {
    37  	if _, err := os.Stat(dir); os.IsNotExist(err) {
    38  		if err := os.MkdirAll(dir, 0755); err != nil {
    39  			return nil, fmt.Errorf("unable to create %s: %w", dir, err)
    40  		}
    41  
    42  		return nil, nil
    43  	}
    44  
    45  	var files []string
    46  
    47  	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
    48  		if path == dir {
    49  			return nil
    50  		}
    51  
    52  		files = append(files, path)
    53  		return nil
    54  	})
    55  	if err != nil {
    56  		return nil, fmt.Errorf("could not walk %s: %w", dir, err)
    57  	}
    58  
    59  	ks := make([]*Key, len(files))
    60  	for i, file := range files {
    61  		k, err := Load(file)
    62  		if err != nil {
    63  			return nil, fmt.Errorf("could not load key at %s: %w", file, err)
    64  		}
    65  
    66  		ks[i] = k
    67  	}
    68  	return ks, nil
    69  }
    70  
    71  // Save persists a [Key] to [dir] (where the filename is the hex-encoded
    72  // address).
    73  func (k *Key) Save(dir string) error {
    74  	fp := filepath.Join(dir, k.Address.Hex())
    75  	return ethcrypto.SaveECDSA(fp, k.PrivKey)
    76  }
    77  
    78  // Generate creates a new [Key] and returns it.
    79  func Generate() (*Key, error) {
    80  	pk, err := ethcrypto.GenerateKey()
    81  	if err != nil {
    82  		return nil, fmt.Errorf("%w: cannot generate key", err)
    83  	}
    84  	return createKey(pk), nil
    85  }