diff --git a/config.go b/config.go index 43e12506..9c123e83 100644 --- a/config.go +++ b/config.go @@ -58,6 +58,7 @@ type SMSGlobal struct { Enabled bool } } + type ConfigPost struct { Data Config `json:"Data"` } @@ -66,6 +67,7 @@ type Config struct { Name string EncryptConfig int Cryptocurrencies string + Portfolio Portfolio `json:"PortfolioAddresses"` SMS SMSGlobal `json:"SMSGlobal"` Webserver Webserver `json:"Webserver"` Exchanges []Exchanges diff --git a/config_example.dat b/config_example.dat index dc614013..3e826765 100644 --- a/config_example.dat +++ b/config_example.dat @@ -1,8 +1,31 @@ { "Name": "Skynet", "EncryptConfig": 0, - "DisplayCurrency":"USD", "Cryptocurrencies": "BTC,XBT,LTC,XRP,XDG,DOGE,STR,NMC,STR,XDG,XRP,XVN", + "PortfolioAddresses": { + "Addresses": [ + { + "Address": "1JCe8z4jJVNXSjohjM4i9Hh813dLCNx2Sy", + "CoinType": "BTC", + "Balance": 124178.0002442 + }, + { + "Address": "3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v", + "CoinType": "BTC", + "Balance": 103439.83659727 + }, + { + "Address": "LgY8ahfHRhvjVQC1zJnBhFMG5pCTMuKRqh", + "CoinType": "LTC", + "Balance": 3.00000005e+06 + }, + { + "Address": "0xb794f5ea0ba39494ce839613fffba74279579268", + "CoinType": "ETH", + "Balance": 5.774999820458524e+06 + } + ] + }, "SMSGlobal": { "Enabled": false, "Username": "Username", @@ -20,7 +43,7 @@ "AdminUsername": "admin", "AdminPassword": "Password", "ListenAddress": ":9050" - }, + }, "Exchanges": [ { "Name": "ANX", @@ -31,6 +54,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTCUSD,BTCHKD,BTCEUR,BTCCAD,BTCAUD,BTCSGD,BTCJPY,BTCGBP,BTCNZD,LTCBTC,DOGEBTC,STRBTC,XRPBTC", "EnabledPairs": "BTCUSD,BTCHKD,BTCEUR,BTCCAD,BTCAUD,BTCSGD,BTCJPY,BTCGBP,BTCNZD,LTCBTC,DOGEBTC,STRBTC,XRPBTC", "BaseCurrencies": "USD,HKD,EUR,CAD,AUD,SGD,JPY,GBP,NZD" @@ -44,7 +68,8 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC", + "ClientID": "", + "AvailablePairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC,ETCBTC,ETCUSD,BFXUSD,BFXBTC,RRTUSD,RRTBTC,ZECUSD,ZECBTC,XMRUSD,XMRBTC,DSHUSD,DSHBTC", "EnabledPairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC", "BaseCurrencies": "USD" }, @@ -72,7 +97,7 @@ "APIKey": "Key", "APISecret": "Secret", "ClientID": "ClientID", - "AvailablePairs": "BTCAUD,LTCAUD,LTCBTC", + "AvailablePairs": "LTCBTC,LTCAUD,BTCAUD,BTCMYR", "EnabledPairs": "BTCAUD,LTCAUD,LTCBTC", "BaseCurrencies": "AUD" }, @@ -85,6 +110,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTCCNY,LTCCNY,LTCBTC", "EnabledPairs": "BTCCNY,LTCCNY,LTCBTC", "BaseCurrencies": "CNY" @@ -98,6 +124,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTCUSD,BTCRUR,BTCEUR,LTCBTC,LTCUSD,LTCRUR,LTCEUR,NMCBTC,NMCUSD,NVCBTC,NVCUSD,USDRUR,EURUSD,EURRUR,PPCBTC,PPCUSD", "EnabledPairs": "BTCUSD,BTCRUR,BTCEUR,LTCBTC,LTCUSD,LTCRUR,LTCEUR,NMCBTC,NMCUSD,NVCBTC,NVCUSD,USDRUR,EURUSD,EURRUR,PPCBTC,PPCUSD", "BaseCurrencies": "USD,RUB,EUR" @@ -111,6 +138,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "LTC,BTC", "EnabledPairs": "LTC,BTC", "BaseCurrencies": "AUD" @@ -125,7 +153,7 @@ "APIKey": "Key", "APISecret": "Secret", "ClientID": "ClientID", - "AvailablePairs": "BTCUSD,ETHUSD,BTCGBP,BTCEUR,BTCCAD,ETHBTC", + "AvailablePairs": "BTCGBP,BTCEUR,ETHUSD,ETHBTC,LTCUSD,LTCBTC,BTCUSD", "EnabledPairs": "BTCUSD,BTCGBP,BTCEUR", "BaseCurrencies": "USD,GBP,EUR" }, @@ -138,7 +166,8 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTCUSD", + "ClientID": "", + "AvailablePairs": "BTCUSD,ETHBTC,ETHUSD", "EnabledPairs": "BTCUSD", "BaseCurrencies": "USD" }, @@ -151,6 +180,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTCCNY,LTCCNY", "EnabledPairs": "BTCCNY,LTCCNY", "BaseCurrencies": "CNY" @@ -178,6 +208,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "XBTEUR,XBTUSD,XBTCAD,XBTGBP,XBTJPY,LTCEUR,LTCUSD,LTCCAD,ETHXBT,ETHEUR,ETHUSD,ETHCAD,ETHGBP,ETHJPY,XBTLTC,XBTNMC,XBTXDG,XBTXLM,XBTXRP", "EnabledPairs": "XBTEUR,XBTUSD,XBTCAD,XBTGBP,XBTJPY,LTCEUR,LTCUSD,LTCCAD,ETHXBT,ETHEUR,ETHUSD,ETHCAD,ETHGBP,ETHJPY,XBTLTC,XBTNMC,XBTXDG,XBTXLM,XBTXRP", "BaseCurrencies": "EUR,USD,CAD,GBP,JPY" @@ -191,6 +222,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTCUSD,BTCCNY", "EnabledPairs": "BTCUSD,BTCCNY", "BaseCurrencies": "USD,CNY,SEK" @@ -218,6 +250,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTCCNY,LTCCNY", "EnabledPairs": "BTCCNY,LTCCNY", "BaseCurrencies": "CNY" @@ -231,6 +264,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTCUSD,LTCUSD", "EnabledPairs": "BTCUSD,LTCUSD", "BaseCurrencies": "USD" @@ -244,6 +278,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", + "ClientID": "", "AvailablePairs": "BTC_XUSD,BTC_FCT,BTC_MMNXT,BTC_NMC,BTC_BITUSD,BTC_RDD,BTC_XMR,BTC_XST,BTC_DSH,BTC_MAID,BTC_DGB,BTC_NEOS,BTC_BLK,BTC_NAUT,BTC_NBT,BTC_XCP,BTC_STR,BTC_BTCD,BTC_GRC,BTC_HUC,BTC_BBR,BTC_XDN,BTC_INDEX,BTC_IOC,BTC_SWARM,BTC_EMC2,BTC_MCN,BTC_NOXT,BTC_MINT,BTC_PTS,BTC_SC,BTC_GEO,BTC_XRP,BTC_FLO,BTC_BITS,BTC_HYP,BTC_XCR,BTC_LTBC,BTC_SYS,BTC_GMC,BTC_ETH,BTC_SYNC,BTC_GAP,BTC_BCN,BTC_C2,BTC_PINK,BTC_FIBRE,BTC_POT,BTC_QTL,BTC_SDC,BTC_XC,BTC_DASH,BTC_SILK,BTC_CLAM,BTC_NAV,BTC_PIGGY,BTC_BCY,BTC_MIL,BTC_XCN,BTC_YACC,BTC_BTS,BTC_QBK,BTC_SJCX,BTC_LQD,BTC_BURST,BTC_RIC,BTC_VRC,BTC_LTC,BTC_XPB,BTC_GRS,BTC_XCH,BTC_ARCH,BTC_QORA,BTC_HZ,BTC_NSR,BTC_XPM,BTC_BITCNY,BTC_EXE,BTC_XMG,BTC_BTC,BTC_BTM,BTC_NOBL,BTC_NXT,BTC_DOGE,BTC_CURE,BTC_MNTA,BTC_ADN,BTC_EXP,BTC_VTC,BTC_FLDC,BTC_MRS,BTC_MYR,BTC_OMNI,BTC_VNL,BTC_USDT,BTC_NOTE,BTC_WDC,BTC_BELA,BTC_VIA,BTC_CGA,BTC_DIEM,BTC_IFC,BTC_XDP,BTC_BLOCK,BTC_MMC,BTC_1CR,BTC_UNITY,BTC_XBC,BTC_GEMZ,BTC_FLT,BTC_PPC,BTC_XEM,BTC_RBY,BTC_CNMT,BTC_ABY,XMR_XDN,XMR_IFC,XMR_DIEM,XMR_BBR,XMR_DSH,XMR_BCN,XMR_LTC,XMR_MAID,XMR_DASH,XMR_BTCD,XMR_HYP,XMR_BLK,XMR_QORA,XMR_MNTA,XMR_NXT,USDT_BTC,USDT_ETH,USDT_XRP,USDT_DASH,USDT_LTC,USDT_NXT,USDT_XMR,USDT_STR", "EnabledPairs": "BTC_LTC,BTC_ETH,BTC_DOGE,BTC_DASH,BTC_XRP", "BaseCurrencies": "USD" diff --git a/main.go b/main.go index 6b8898ff..5773ba11 100644 --- a/main.go +++ b/main.go @@ -35,7 +35,6 @@ type Bot struct { exchange Exchange exchanges []IBotExchange tickers []Ticker - portfolio Portfolio tickerChan chan Ticker shutdown chan bool } @@ -122,6 +121,8 @@ func main() { log.Fatalf("Fatal error retrieving config currency AvailablePairs. Error: ", err) } + go StartPortfolioWatcher() + if bot.config.Webserver.Enabled { err := CheckWebserverValues() if err != nil { diff --git a/portfolio.go b/portfolio.go index 5930efdb..3247318b 100644 --- a/portfolio.go +++ b/portfolio.go @@ -3,6 +3,8 @@ package main import ( "errors" "fmt" + "log" + "time" ) const ( @@ -99,7 +101,7 @@ func GetBlockrAddressMulti(addresses []string, coinType string) (BlockrAddressBa } func GetAddressBalance(address string) (float64, bool) { - for _, x := range bot.portfolio.Addresses { + for _, x := range bot.config.Portfolio.Addresses { if x.Address == address { return x.Balance, true } @@ -108,7 +110,7 @@ func GetAddressBalance(address string) (float64, bool) { } func AddressExists(address string) bool { - for _, x := range bot.portfolio.Addresses { + for _, x := range bot.config.Portfolio.Addresses { if x.Address == address { return true } @@ -124,7 +126,7 @@ func UpdatePortfolio(addresses []string, coinType string) bool { } for _, x := range result.Data { if !AddressExists(x.Address) { - bot.portfolio.Addresses = append(bot.portfolio.Addresses, PortfolioAddress{Address: x.Address, CoinType: coinType, Balance: x.Balance / WEI_PER_ETHER}) + bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, PortfolioAddress{Address: x.Address, CoinType: coinType, Balance: x.Balance / WEI_PER_ETHER}) } } return true @@ -136,7 +138,7 @@ func UpdatePortfolio(addresses []string, coinType string) bool { } for _, x := range result.Data { if !AddressExists(x.Address) { - bot.portfolio.Addresses = append(bot.portfolio.Addresses, PortfolioAddress{Address: x.Address, CoinType: coinType, Balance: x.Balance}) + bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, PortfolioAddress{Address: x.Address, CoinType: coinType, Balance: x.Balance}) } } } else { @@ -145,7 +147,7 @@ func UpdatePortfolio(addresses []string, coinType string) bool { return false } if !AddressExists(result.Data.Address) { - bot.portfolio.Addresses = append(bot.portfolio.Addresses, PortfolioAddress{Address: result.Data.Address, CoinType: coinType, Balance: result.Data.Balance}) + bot.config.Portfolio.Addresses = append(bot.config.Portfolio.Addresses, PortfolioAddress{Address: result.Data.Address, CoinType: coinType, Balance: result.Data.Balance}) } } return true @@ -153,7 +155,7 @@ func UpdatePortfolio(addresses []string, coinType string) bool { func GetPortfolioSummary(coinFilter string) map[string]float64 { result := make(map[string]float64) - for _, x := range bot.portfolio.Addresses { + for _, x := range bot.config.Portfolio.Addresses { if coinFilter != "" && coinFilter != x.CoinType { continue } @@ -166,3 +168,26 @@ func GetPortfolioSummary(coinFilter string) map[string]float64 { } return result } + +func GetPortfolioGroupedCoin() map[string][]string { + result := make(map[string][]string) + for _, x := range bot.config.Portfolio.Addresses { + result[x.CoinType] = append(result[x.CoinType], x.Address) + } + return result +} + +func StartPortfolioWatcher() { + addrCount := len(bot.config.Portfolio.Addresses) + log.Printf("PortfolioWatcher started: Have %d address(es) in portfolio.\n", addrCount) + for { + data := GetPortfolioGroupedCoin() + for key, value := range data { + success := UpdatePortfolio(value, key) + if success { + log.Printf("PortfolioWatcher: Successfully updated address balance for %s address(es) %s\n", key, value) + } + } + time.Sleep(time.Minute * 10) + } +}