planetmint-go/lib/config.go
Julian Strobl 00a56fed43
refactor(lib): make config more readable
- export variables from struct
- lock/defer lock

Signed-off-by: Julian Strobl <jmastr@mailbox.org>
2024-11-19 09:22:20 +01:00

191 lines
3.9 KiB
Go

package lib
import (
"errors"
"os"
"sync"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/planetmint/planetmint-go/lib/params"
)
var (
// ErrInvalidConfig is returned when configuration validation fails
ErrInvalidConfig = errors.New("invalid configuration")
// Global singleton instances
instance *Config
mu sync.RWMutex
once sync.Once
sdkConfig *sdk.Config
)
// Config defines the top-level configuration for the Planetmint library.
// All fields are exported to allow external access while maintaining
// thread-safe modifications through methods.
type Config struct {
ChainID string
ClientCtx client.Context
EncodingConfig params.EncodingConfig
FeeDenom string
RPCEndpoint string
RootDir string
SerialPort string
TxGas uint64
}
// NewConfig creates a new Config instance with default values.
func NewConfig() *Config {
return &Config{
ChainID: "planetmint-testnet-1",
ClientCtx: client.Context{},
EncodingConfig: params.EncodingConfig{},
FeeDenom: "plmnt",
RPCEndpoint: "http://127.0.0.1:26657",
RootDir: "~/.planetmint-go/",
TxGas: 200000,
}
}
// GetConfig returns the singleton Config instance, initializing it if necessary.
func GetConfig() *Config {
once.Do(func() {
instance = NewConfig()
sdkConfig = sdk.GetConfig()
// Initialize default configuration
instance.SetBech32PrefixForAccount("plmnt")
encodingConfig := MakeEncodingConfig()
instance.SetEncodingConfig(encodingConfig)
})
return instance
}
// Validate checks if the configuration is valid.
func (c *Config) Validate() error {
mu.RLock()
defer mu.RUnlock()
if c.ChainID == "" {
return errors.New("chain ID cannot be empty")
}
if c.RPCEndpoint == "" {
return errors.New("RPC endpoint cannot be empty")
}
if c.TxGas == 0 {
return errors.New("transaction gas cannot be zero")
}
return nil
}
// Builder methods
func (c *Config) SetBech32PrefixForAccount(prefix string) *Config {
mu.Lock()
defer mu.Unlock()
sdkConfig.SetBech32PrefixForAccount(prefix, "pub")
return c
}
func (c *Config) SetEncodingConfig(config params.EncodingConfig) *Config {
mu.Lock()
defer mu.Unlock()
c.EncodingConfig = config
return c
}
func (c *Config) SetChainID(chainID string) *Config {
mu.Lock()
defer mu.Unlock()
c.ChainID = chainID
return c
}
func (c *Config) SetClientCtx(ctx client.Context) *Config {
mu.Lock()
defer mu.Unlock()
c.ClientCtx = ctx
return c
}
func (c *Config) SetFeeDenom(denom string) *Config {
mu.Lock()
defer mu.Unlock()
c.FeeDenom = denom
return c
}
func (c *Config) SetRoot(root string) *Config {
mu.Lock()
defer mu.Unlock()
c.RootDir = root
return c
}
func (c *Config) SetRPCEndpoint(endpoint string) *Config {
mu.Lock()
defer mu.Unlock()
c.RPCEndpoint = endpoint
return c
}
func (c *Config) SetTxGas(gas uint64) *Config {
mu.Lock()
defer mu.Unlock()
c.TxGas = gas
return c
}
func (c *Config) SetSerialPort(port string) *Config {
mu.Lock()
defer mu.Unlock()
c.SerialPort = port
return c
}
// Getter methods
func (c *Config) GetSerialPort() string {
mu.RLock()
defer mu.RUnlock()
return c.SerialPort
}
// Keyring operations
// GetLibKeyring returns a new keyring instance configured with the current settings.
func (c *Config) GetLibKeyring() (keyring.Keyring, error) {
mu.RLock()
defer mu.RUnlock()
return keyring.New(
"lib",
keyring.BackendTest,
c.RootDir,
os.Stdin,
c.EncodingConfig.Marshaler,
[]keyring.Option{}...,
)
}
// GetDefaultValidatorRecord returns the first validator record from the keyring.
func (c *Config) GetDefaultValidatorRecord() (*keyring.Record, error) {
keyring, err := c.GetLibKeyring()
if err != nil {
return nil, err
}
records, err := keyring.List()
if err != nil {
return nil, err
}
if len(records) == 0 {
return nil, errors.New("no keyring records found")
}
return records[0], nil
}