Package config

This commit is contained in:
Adrian Gallagher
2017-03-16 14:36:42 +11:00
parent b6c9d64f75
commit 3edf81f48b
24 changed files with 163 additions and 220 deletions

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -103,7 +104,7 @@ func (a *ANX) SetDefaults() {
}
//Setup is run on startup to setup exchange with config values
func (a *ANX) Setup(exch Exchanges) {
func (a *ANX) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
a.SetEnabled(false)
} else {

View File

@@ -11,6 +11,7 @@ import (
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -197,7 +198,7 @@ func (b *Bitfinex) GetName() string {
return b.Name
}
func (b *Bitfinex) Setup(exch Exchanges) {
func (b *Bitfinex) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
b.SetEnabled(false)
} else {
@@ -252,13 +253,13 @@ func (b *Bitfinex) Run() {
exchangeProducts = common.SplitStrings(common.StringToUpper(common.JoinStrings(exchangeProducts, ",")), ",")
diff := common.StringSliceDifference(b.AvailablePairs, exchangeProducts)
if len(diff) > 0 {
exch, err := GetExchangeConfig(b.Name)
exch, err := bot.config.GetExchangeConfig(b.Name)
if err != nil {
log.Println(err)
} else {
log.Printf("%s Updating available pairs. Difference: %s.\n", b.Name, diff)
exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",")
UpdateExchangeConfig(exch)
bot.config.UpdateExchangeConfig(exch)
}
}
}

View File

@@ -11,6 +11,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -181,7 +182,7 @@ func (b *Bitstamp) GetName() string {
return b.Name
}
func (b *Bitstamp) Setup(exch Exchanges) {
func (b *Bitstamp) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
b.SetEnabled(false)
} else {

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -184,7 +185,7 @@ func (b *BTCC) SetDefaults() {
}
//Setup is run on startup to setup exchange with config values
func (b *BTCC) Setup(exch Exchanges) {
func (b *BTCC) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
b.SetEnabled(false)
} else {

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -101,7 +102,7 @@ func (b *BTCE) IsEnabled() bool {
return b.Enabled
}
func (b *BTCE) Setup(exch Exchanges) {
func (b *BTCE) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
b.SetEnabled(false)
} else {

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -110,7 +111,7 @@ func (b *BTCMarkets) IsEnabled() bool {
return b.Enabled
}
func (b *BTCMarkets) Setup(exch Exchanges) {
func (b *BTCMarkets) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
b.SetEnabled(false)
} else {

View File

@@ -334,3 +334,19 @@ func UnixTimestampStrToTime(timeStr string) (time.Time, error) {
return time.Unix(i, 0), nil
}
func ReadFile(path string) ([]byte, error) {
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return file, nil
}
func WriteFile(file string, data []byte) error {
err := ioutil.WriteFile(file, data, 0644)
if err != nil {
return err
}
return nil
}

View File

@@ -1,10 +1,9 @@
package main
package config
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
@@ -43,14 +42,14 @@ var (
RenamingConfigFile = "Renaming config file %s to %s."
)
type Webserver struct {
type WebserverConfig struct {
Enabled bool
AdminUsername string
AdminPassword string
ListenAddress string
}
type SMSGlobal struct {
type SMSGlobalConfig struct {
Enabled bool
Username string
Password string
@@ -69,13 +68,13 @@ type Config struct {
Name string
EncryptConfig int
Cryptocurrencies string
Portfolio Portfolio `json:"PortfolioAddresses"`
SMS SMSGlobal `json:"SMSGlobal"`
Webserver Webserver `json:"Webserver"`
Exchanges []Exchanges
Portfolio PortfolioConfig `json:"PortfolioAddresses"`
SMS SMSGlobalConfig `json:"SMSGlobal"`
Webserver WebserverConfig `json:"Webserver"`
Exchanges []ExchangeConfig `json:"Exchanges"`
}
type Exchanges struct {
type ExchangeConfig struct {
Name string
Enabled bool
Verbose bool
@@ -90,43 +89,53 @@ type Exchanges struct {
BaseCurrencies string
}
func GetEnabledExchanges() int {
type PortfolioAddressConfig struct {
Address string
CoinType string
Balance float64
}
type PortfolioConfig struct {
Addresses []PortfolioAddressConfig
}
func (c *Config) GetConfigEnabledExchanges() int {
counter := 0
for i := range bot.config.Exchanges {
if bot.config.Exchanges[i].Enabled {
for i := range c.Exchanges {
if c.Exchanges[i].Enabled {
counter++
}
}
return counter
}
func GetExchangeConfig(name string) (Exchanges, error) {
for i, _ := range bot.config.Exchanges {
if bot.config.Exchanges[i].Name == name {
return bot.config.Exchanges[i], nil
func (c *Config) GetExchangeConfig(name string) (ExchangeConfig, error) {
for i, _ := range c.Exchanges {
if c.Exchanges[i].Name == name {
return c.Exchanges[i], nil
}
}
return Exchanges{}, fmt.Errorf(ErrExchangeNotFound, name)
return ExchangeConfig{}, fmt.Errorf(ErrExchangeNotFound, name)
}
func UpdateExchangeConfig(e Exchanges) error {
for i, _ := range bot.config.Exchanges {
if bot.config.Exchanges[i].Name == e.Name {
bot.config.Exchanges[i] = e
func (c *Config) UpdateExchangeConfig(e ExchangeConfig) error {
for i, _ := range c.Exchanges {
if c.Exchanges[i].Name == e.Name {
c.Exchanges[i] = e
return nil
}
}
return fmt.Errorf(ErrExchangeNotFound, e.Name)
}
func CheckSMSGlobalConfigValues() error {
if bot.config.SMS.Username == "" || bot.config.SMS.Username == "Username" || bot.config.SMS.Password == "" || bot.config.SMS.Password == "Password" {
func (c *Config) CheckSMSGlobalConfigValues() error {
if c.SMS.Username == "" || c.SMS.Username == "Username" || c.SMS.Password == "" || c.SMS.Password == "Password" {
return errors.New(WarningSMSGlobalDefaultOrEmptyValues)
}
contacts := 0
for i := range bot.config.SMS.Contacts {
if bot.config.SMS.Contacts[i].Enabled {
if bot.config.SMS.Contacts[i].Name == "" || bot.config.SMS.Contacts[i].Number == "" || (bot.config.SMS.Contacts[i].Name == "Bob" && bot.config.SMS.Contacts[i].Number == "12345") {
for i := range c.SMS.Contacts {
if c.SMS.Contacts[i].Enabled {
if c.SMS.Contacts[i].Name == "" || c.SMS.Contacts[i].Number == "" || (c.SMS.Contacts[i].Name == "Bob" && c.SMS.Contacts[i].Number == "12345") {
log.Printf(WarningSSMSGlobalSMSContactDefaultOrEmptyValues, i)
continue
}
@@ -139,13 +148,13 @@ func CheckSMSGlobalConfigValues() error {
return nil
}
func CheckExchangeConfigValues() error {
if bot.config.Cryptocurrencies == "" {
func (c *Config) CheckExchangeConfigValues() error {
if c.Cryptocurrencies == "" {
return errors.New(ErrCryptocurrenciesEmpty)
}
exchanges := 0
for i, exch := range bot.config.Exchanges {
for i, exch := range c.Exchanges {
if exch.Enabled {
if exch.Name == "" {
return fmt.Errorf(ErrExchangeNameEmpty, i)
@@ -161,12 +170,12 @@ func CheckExchangeConfigValues() error {
}
if exch.AuthenticatedAPISupport { // non-fatal error
if exch.APIKey == "" || exch.APISecret == "" || exch.APIKey == "Key" || exch.APISecret == "Secret" {
bot.config.Exchanges[i].AuthenticatedAPISupport = false
c.Exchanges[i].AuthenticatedAPISupport = false
log.Printf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
continue
} else if exch.Name == "ITBIT" || exch.Name == "Bitstamp" || exch.Name == "Coinbase" {
if exch.ClientID == "" || exch.ClientID == "ClientID" {
bot.config.Exchanges[i].AuthenticatedAPISupport = false
c.Exchanges[i].AuthenticatedAPISupport = false
log.Printf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
continue
}
@@ -181,16 +190,16 @@ func CheckExchangeConfigValues() error {
return nil
}
func CheckWebserverValues() error {
if bot.config.Webserver.AdminUsername == "" || bot.config.Webserver.AdminPassword == "" {
func (c *Config) CheckWebserverConfigValues() error {
if c.Webserver.AdminUsername == "" || c.Webserver.AdminPassword == "" {
return errors.New(WarningWebserverCredentialValuesEmpty)
}
if !common.StringContains(bot.config.Webserver.ListenAddress, ":") {
if !common.StringContains(c.Webserver.ListenAddress, ":") {
return errors.New(WarningWebserverListenAddressInvalid)
}
portStr := common.SplitStrings(bot.config.Webserver.ListenAddress, ":")[1]
portStr := common.SplitStrings(c.Webserver.ListenAddress, ":")[1]
port, err := strconv.Atoi(portStr)
if err != nil {
return errors.New(WarningWebserverListenAddressInvalid)
@@ -202,8 +211,8 @@ func CheckWebserverValues() error {
return nil
}
func ReadConfig() error {
_, err := ioutil.ReadFile(OLD_CONFIG_FILE)
func (c *Config) ReadConfig() error {
_, err := common.ReadFile(OLD_CONFIG_FILE)
if err == nil {
err = os.Rename(OLD_CONFIG_FILE, CONFIG_FILE)
if err != nil {
@@ -212,25 +221,25 @@ func ReadConfig() error {
log.Printf(RenamingConfigFile+"\n", OLD_CONFIG_FILE, CONFIG_FILE)
}
file, err := ioutil.ReadFile(CONFIG_FILE)
file, err := common.ReadFile(CONFIG_FILE)
if err != nil {
return err
}
if !ConfirmECS(file) {
err = ConfirmConfigJSON(file, &bot.config)
err = ConfirmConfigJSON(file, &c)
if err != nil {
return err
}
if bot.config.EncryptConfig == CONFIG_FILE_ENCRYPTION_DISABLED {
if c.EncryptConfig == CONFIG_FILE_ENCRYPTION_DISABLED {
return nil
}
if bot.config.EncryptConfig == CONFIG_FILE_ENCRYPTION_PROMPT {
if PromptForConfigEncryption() {
bot.config.EncryptConfig = CONFIG_FILE_ENCRYPTION_ENABLED
SaveConfig()
if c.EncryptConfig == CONFIG_FILE_ENCRYPTION_PROMPT {
if c.PromptForConfigEncryption() {
c.EncryptConfig = CONFIG_FILE_ENCRYPTION_ENABLED
return c.SaveConfig()
}
}
} else {
@@ -244,7 +253,7 @@ func ReadConfig() error {
return err
}
err = ConfirmConfigJSON(data, &bot.config)
err = ConfirmConfigJSON(data, &c)
if err != nil {
return err
}
@@ -252,10 +261,10 @@ func ReadConfig() error {
return nil
}
func SaveConfig() error {
payload, err := json.MarshalIndent(bot.config, "", " ")
func (c *Config) SaveConfig() error {
payload, err := json.MarshalIndent(c, "", " ")
if bot.config.EncryptConfig == CONFIG_FILE_ENCRYPTION_ENABLED {
if c.EncryptConfig == CONFIG_FILE_ENCRYPTION_ENABLED {
key, err := PromptForConfigKey()
if err != nil {
return err
@@ -267,20 +276,20 @@ func SaveConfig() error {
}
}
err = ioutil.WriteFile(CONFIG_FILE, payload, 0644)
err = common.WriteFile(CONFIG_FILE, payload)
if err != nil {
return err
}
return nil
}
func LoadConfig() error {
err := ReadConfig()
func (c *Config) LoadConfig() error {
err := c.ReadConfig()
if err != nil {
return fmt.Errorf(ErrFailureOpeningConfig, CONFIG_FILE, err)
}
err = CheckExchangeConfigValues()
err = c.CheckExchangeConfigValues()
if err != nil {
return fmt.Errorf(ErrCheckingConfigValues, err)
}

View File

@@ -1,4 +1,4 @@
package main
package config
import (
"bytes"
@@ -14,10 +14,12 @@ import (
)
const (
ENCRYPTION_CONFIRMATION_STRING = "THORS-HAMMER"
CONFIG_ENCRYPTION_CONFIRMATION_STRING = "THORS-HAMMER"
ErrConfigDataLessThenRequiredAESBlockSize = "The config file data is too small for the AES required block size."
)
func PromptForConfigEncryption() bool {
func (c *Config) PromptForConfigEncryption() bool {
log.Println("Would you like to encrypt your config file (y/n)?")
input := ""
@@ -27,8 +29,8 @@ func PromptForConfigEncryption() bool {
}
if !common.YesOrNo(input) {
bot.config.EncryptConfig = CONFIG_FILE_ENCRYPTION_DISABLED
SaveConfig()
c.EncryptConfig = CONFIG_FILE_ENCRYPTION_DISABLED
c.SaveConfig()
return false
}
return true
@@ -73,7 +75,7 @@ func EncryptConfigFile(configData, key []byte) ([]byte, error) {
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], configData)
appendedFile := []byte(ENCRYPTION_CONFIRMATION_STRING)
appendedFile := []byte(CONFIG_ENCRYPTION_CONFIRMATION_STRING)
appendedFile = append(appendedFile, ciphertext...)
return appendedFile, nil
}
@@ -86,7 +88,7 @@ func DecryptConfigFile(configData, key []byte) ([]byte, error) {
}
if len(configData) < aes.BlockSize {
return nil, errors.New("The config file data is too small for the AES required block size.")
return nil, errors.New(ErrConfigDataLessThenRequiredAESBlockSize)
}
iv := configData[:aes.BlockSize]
@@ -103,10 +105,10 @@ func ConfirmConfigJSON(file []byte, result interface{}) error {
}
func ConfirmECS(file []byte) bool {
subslice := []byte(ENCRYPTION_CONFIRMATION_STRING)
subslice := []byte(CONFIG_ENCRYPTION_CONFIRMATION_STRING)
return bytes.Contains(file, subslice)
}
func RemoveECS(file []byte) []byte {
return bytes.Trim(file, ENCRYPTION_CONFIRMATION_STRING)
return bytes.Trim(file, CONFIG_ENCRYPTION_CONFIRMATION_STRING)
}

View File

@@ -3,6 +3,8 @@ package main
import (
"encoding/json"
"net/http"
"github.com/thrasher-/gocryptotrader/config"
)
func GetAllSettings(w http.ResponseWriter, r *http.Request) {
@@ -16,7 +18,7 @@ func GetAllSettings(w http.ResponseWriter, r *http.Request) {
func SaveAllSettings(w http.ResponseWriter, r *http.Request) {
//Get the data from the request
decoder := json.NewDecoder(r.Body)
var responseData ConfigPost
var responseData config.ConfigPost
jsonerr := decoder.Decode(&responseData)
if jsonerr != nil {
panic(jsonerr)
@@ -33,11 +35,11 @@ func SaveAllSettings(w http.ResponseWriter, r *http.Request) {
}
}
//Reload the configuration
err := SaveConfig()
err := bot.config.SaveConfig()
if err != nil {
panic(err)
}
err = LoadConfig()
err = bot.config.LoadConfig()
if err != nil {
panic(err)
}

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -145,7 +146,7 @@ func (g *GDAX) IsEnabled() bool {
return g.Enabled
}
func (g *GDAX) Setup(exch Exchanges) {
func (g *GDAX) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
g.SetEnabled(false)
} else {
@@ -200,13 +201,13 @@ func (g *GDAX) Run() {
}
diff := common.StringSliceDifference(g.AvailablePairs, currencies)
if len(diff) > 0 {
exch, err := GetExchangeConfig(g.Name)
exch, err := bot.config.GetExchangeConfig(g.Name)
if err != nil {
log.Println(err)
} else {
log.Printf("%s Updating available pairs. Difference: %s.\n", g.Name, diff)
exch.AvailablePairs = common.JoinStrings(currencies, ",")
UpdateExchangeConfig(exch)
bot.config.UpdateExchangeConfig(exch)
}
}
}

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -126,7 +127,7 @@ func (g *Gemini) IsEnabled() bool {
return g.Enabled
}
func (g *Gemini) Setup(exch Exchanges) {
func (g *Gemini) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
g.SetEnabled(false)
} else {
@@ -168,13 +169,13 @@ func (g *Gemini) Run() {
exchangeProducts = common.SplitStrings(common.StringToUpper(common.JoinStrings(exchangeProducts, ",")), ",")
diff := common.StringSliceDifference(g.AvailablePairs, exchangeProducts)
if len(diff) > 0 {
exch, err := GetExchangeConfig(g.Name)
exch, err := bot.config.GetExchangeConfig(g.Name)
if err != nil {
log.Println(err)
} else {
log.Printf("%s Updating available pairs. Difference: %s.\n", g.Name, diff)
exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",")
UpdateExchangeConfig(exch)
bot.config.UpdateExchangeConfig(exch)
}
}
}

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -65,7 +66,7 @@ func (h *HUOBI) IsEnabled() bool {
return h.Enabled
}
func (h *HUOBI) Setup(exch Exchanges) {
func (h *HUOBI) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
h.SetEnabled(false)
} else {

View File

@@ -1,8 +1,12 @@
package main
import (
"github.com/thrasher-/gocryptotrader/config"
)
//IBotExchange : Enforces standard functions for all exchanges supported in gocryptotrader
type IBotExchange interface {
Setup(exch Exchanges)
Setup(exch config.ExchangeConfig)
Start()
SetDefaults()
GetName() string

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -72,7 +73,7 @@ func (i *ItBit) IsEnabled() bool {
return i.Enabled
}
func (i *ItBit) Setup(exch Exchanges) {
func (i *ItBit) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
i.SetEnabled(false)
} else {

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -76,7 +77,7 @@ func (k *Kraken) IsEnabled() bool {
return k.Enabled
}
func (k *Kraken) Setup(exch Exchanges) {
func (k *Kraken) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
k.SetEnabled(false)
} else {
@@ -129,13 +130,13 @@ func (k *Kraken) Run() {
}
diff := common.StringSliceDifference(k.AvailablePairs, exchangeProducts)
if len(diff) > 0 {
exch, err := GetExchangeConfig(k.Name)
exch, err := bot.config.GetExchangeConfig(k.Name)
if err != nil {
log.Println(err)
} else {
log.Printf("%s Updating available pairs. Difference: %s.\n", k.Name, diff)
exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",")
UpdateExchangeConfig(exch)
bot.config.UpdateExchangeConfig(exch)
}
}
}

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -83,7 +84,7 @@ func (l *LakeBTC) IsEnabled() bool {
return l.Enabled
}
func (l *LakeBTC) Setup(exch Exchanges) {
func (l *LakeBTC) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
l.SetEnabled(false)
} else {

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -99,7 +100,7 @@ func (l *Liqui) IsEnabled() bool {
return l.Enabled
}
func (l *Liqui) Setup(exch Exchanges) {
func (l *Liqui) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
l.SetEnabled(false)
} else {
@@ -142,13 +143,13 @@ func (l *Liqui) Run() {
exchangeProducts := l.GetAvailablePairs(true)
diff := common.StringSliceDifference(l.AvailablePairs, exchangeProducts)
if len(diff) > 0 {
exch, err := GetExchangeConfig(l.Name)
exch, err := bot.config.GetExchangeConfig(l.Name)
if err != nil {
log.Println(err)
} else {
log.Printf("%s Updating available pairs. Difference: %s.\n", l.Name, diff)
exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",")
UpdateExchangeConfig(exch)
bot.config.UpdateExchangeConfig(exch)
}
}
}

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -60,7 +61,7 @@ func (l *LocalBitcoins) IsEnabled() bool {
return l.Enabled
}
func (l *LocalBitcoins) Setup(exch Exchanges) {
func (l *LocalBitcoins) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
l.SetEnabled(false)
} else {

15
main.go
View File

@@ -10,6 +10,7 @@ import (
"syscall"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
type Exchange struct {
@@ -33,7 +34,7 @@ type Exchange struct {
}
type Bot struct {
config Config
config config.Config
exchange Exchange
exchanges []IBotExchange
tickers []Ticker
@@ -63,9 +64,9 @@ func setupBotExchanges() {
func main() {
HandleInterrupt()
log.Printf("Loading config file %s..\n", CONFIG_FILE)
log.Printf("Loading config file %s..\n", config.CONFIG_FILE)
err := LoadConfig()
err := bot.config.LoadConfig()
if err != nil {
log.Fatal(err)
}
@@ -74,7 +75,7 @@ func main() {
AdjustGoMaxProcs()
if bot.config.SMS.Enabled {
err = CheckSMSGlobalConfigValues()
err = bot.config.CheckSMSGlobalConfigValues()
if err != nil {
log.Println(err) // non fatal event
bot.config.SMS.Enabled = false
@@ -85,7 +86,7 @@ func main() {
log.Println("SMS support disabled.")
}
log.Printf("Available Exchanges: %d. Enabled Exchanges: %d.\n", len(bot.config.Exchanges), GetEnabledExchanges())
log.Printf("Available Exchanges: %d. Enabled Exchanges: %d.\n", len(bot.config.Exchanges), bot.config.GetConfigEnabledExchanges())
log.Println("Bot Exchange support:")
bot.exchanges = []IBotExchange{
@@ -126,7 +127,7 @@ func main() {
go StartPortfolioWatcher()
if bot.config.Webserver.Enabled {
err := CheckWebserverValues()
err := bot.config.CheckWebserverConfigValues()
if err != nil {
log.Println(err) // non fatal event
//bot.config.Webserver.Enabled = false
@@ -177,7 +178,7 @@ func HandleInterrupt() {
func Shutdown() {
log.Println("Bot shutting down..")
err := SaveConfig()
err := bot.config.SaveConfig()
if err != nil {
log.Println("Unable to save config.")

View File

@@ -10,6 +10,7 @@ import (
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -222,7 +223,7 @@ func (o *OKCoin) IsEnabled() bool {
return o.Enabled
}
func (o *OKCoin) Setup(exch Exchanges) {
func (o *OKCoin) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
o.SetEnabled(false)
} else {

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -91,7 +92,7 @@ func (p *Poloniex) IsEnabled() bool {
return p.Enabled
}
func (p *Poloniex) Setup(exch Exchanges) {
func (p *Poloniex) Setup(exch config.ExchangeConfig) {
if !exch.Enabled {
p.SetEnabled(false)
} else {

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
const (
@@ -134,9 +135,10 @@ func UpdatePortfolio(addresses []string, coinType string) bool {
if err != nil {
return false
}
for _, x := range result.Data {
if !AddressExists(x.Address) {
bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, PortfolioAddress{Address: x.Address, CoinType: coinType, Balance: x.Balance / common.WEI_PER_ETHER})
bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, config.PortfolioAddressConfig{Address: x.Address, CoinType: coinType, Balance: x.Balance / common.WEI_PER_ETHER})
} else {
UpdateAddressBalance(x.Address, x.Balance)
}
@@ -150,7 +152,7 @@ func UpdatePortfolio(addresses []string, coinType string) bool {
}
for _, x := range result.Data {
if !AddressExists(x.Address) {
bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, PortfolioAddress{Address: x.Address, CoinType: coinType, Balance: x.Balance})
bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, config.PortfolioAddressConfig{Address: x.Address, CoinType: coinType, Balance: x.Balance})
} else {
UpdateAddressBalance(x.Address, x.Balance)
}
@@ -161,7 +163,7 @@ func UpdatePortfolio(addresses []string, coinType string) bool {
return false
}
if !AddressExists(result.Data.Address) {
bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, PortfolioAddress{Address: result.Data.Address, CoinType: coinType, Balance: result.Data.Balance})
bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, config.PortfolioAddressConfig{Address: result.Data.Address, CoinType: coinType, Balance: result.Data.Balance})
} else {
UpdateAddressBalance(result.Data.Address, result.Data.Balance)
}

View File

@@ -1,21 +1,11 @@
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
)
const (
ENCRYPTION_CONFIRMATION_STRING = "THORS-HAMMER"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
func EncryptOrDecrypt(encrypt bool) string {
@@ -38,26 +28,26 @@ func main() {
log.Println("GoCryptoTrader: config-helper tool.")
if key == "" {
result, err := PromptForConfigKey()
result, err := config.PromptForConfigKey()
if err != nil {
log.Fatal("Unable to obtain encryption/decryption key.")
}
key = string(result)
}
file, err := ReadFile(inFile)
file, err := common.ReadFile(inFile)
if err != nil {
log.Fatalf("Unable to read input file %s. Error: %s.", inFile, err)
}
if ConfirmECS(file) && encrypt {
if config.ConfirmECS(file) && encrypt {
log.Println("File is already encrypted. Decrypting..")
encrypt = false
}
if !ConfirmECS(file) && !encrypt {
if !config.ConfirmECS(file) && !encrypt {
var result interface{}
err := ConfirmConfigJSON(file, result)
err := config.ConfirmConfigJSON(file, result)
if err != nil {
log.Fatal("File isn't in JSON format")
}
@@ -67,119 +57,20 @@ func main() {
var data []byte
if encrypt {
data, err = EncryptConfigFile(file, []byte(key))
data, err = config.EncryptConfigFile(file, []byte(key))
if err != nil {
log.Fatalf("Unable to encrypt config data. Error: %s.", err)
}
} else {
data, err = DecryptConfigFile(file, []byte(key))
data, err = config.DecryptConfigFile(file, []byte(key))
if err != nil {
log.Fatalf("Unable to decrypt config data. Error: %s.", err)
}
}
err = WriteFile(outFile, data)
err = common.WriteFile(outFile, data)
if err != nil {
log.Fatalf("Unable to write output file %s. Error: %s", outFile, err)
}
log.Printf("Successfully %s input file %s and wrote output to %s.\n", EncryptOrDecrypt(encrypt), inFile, outFile)
}
func ReadFile(path string) ([]byte, error) {
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return file, nil
}
func WriteFile(file string, data []byte) error {
err := ioutil.WriteFile(file, data, 0644)
if err != nil {
return err
}
return nil
}
func PromptForConfigKey() ([]byte, error) {
var cryptoKey []byte
for len(cryptoKey) != 32 {
log.Println("Enter password (32 characters):")
_, err := fmt.Scanln(&cryptoKey)
if err != nil {
return nil, err
}
if len(cryptoKey) > 32 || len(cryptoKey) < 32 {
continue
}
}
nonce := make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return cryptoKey, nil
}
func EncryptConfigFile(configData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
ciphertext := make([]byte, aes.BlockSize+len(configData))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], configData)
appendedFile := []byte(ENCRYPTION_CONFIRMATION_STRING)
appendedFile = append(appendedFile, ciphertext...)
return appendedFile, nil
}
func DecryptConfigFile(configData, key []byte) ([]byte, error) {
configData = RemoveECS(configData)
blockDecrypt, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(configData) < aes.BlockSize {
return nil, errors.New("The config file data is too small for the AES required block size.")
}
iv := configData[:aes.BlockSize]
configData = configData[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(blockDecrypt, iv)
stream.XORKeyStream(configData, configData)
result := configData
return result, nil
}
func ConfirmConfigJSON(file []byte, result interface{}) error {
err := json.Unmarshal(file, &result)
if err != nil {
return err
}
return nil
}
func ConfirmECS(file []byte) bool {
subslice := []byte(ENCRYPTION_CONFIRMATION_STRING)
return bytes.Contains(file, subslice)
}
func RemoveECS(file []byte) []byte {
return bytes.Trim(file, ENCRYPTION_CONFIRMATION_STRING)
}