mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
Package config
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
15
main.go
@@ -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.")
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user