mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-03 07:26:45 +00:00
Expose auth validator functionality for wrapper (#416)
* expose auth validator functionality for wrapper * Add REST validation after keys set, package account types for future syncing * Add transient error checking for initial creddemtial validation * fix command types * Addressed nits from glorious person * Amalgamate body within error when not between 2xx status, added btcmarket specific auth error check * nit fix for glorious person * Format fix * removed unused code * check transient first then validate if its an exchange specific authentication error, all others will be disregarded * Addressed glorious nits * Addressed glorious nits * Moved account processing to updateaccountinfo func and added in fetch account info * Add GRPC Account streaming (NOTE: could not complete until sync item added) * RM exchange check * Address xtda nits * RM comment code * Fix linter issues * used most recent protoc version * lbank linter issues fixed * Addressed nits and changed len check to range in for loops * Fixed timeout issue * thrasher nits addressed * add string holdings
This commit is contained in:
@@ -59,17 +59,6 @@ func dryrunParamInteraction(param string) {
|
||||
}
|
||||
}
|
||||
|
||||
// CheckExchangeExists returns true whether or not an exchange has already
|
||||
// been loaded
|
||||
func CheckExchangeExists(exchName string) bool {
|
||||
for x := range Bot.Exchanges {
|
||||
if strings.EqualFold(Bot.Exchanges[x].GetName(), exchName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetExchangeByName returns an exchange given an exchange name
|
||||
func GetExchangeByName(exchName string) exchange.IBotExchange {
|
||||
for x := range Bot.Exchanges {
|
||||
@@ -86,7 +75,8 @@ func ReloadExchange(name string) error {
|
||||
return ErrNoExchangesLoaded
|
||||
}
|
||||
|
||||
if !CheckExchangeExists(name) {
|
||||
e := GetExchangeByName(name)
|
||||
if e == nil {
|
||||
return ErrExchangeNotFound
|
||||
}
|
||||
|
||||
@@ -95,7 +85,6 @@ func ReloadExchange(name string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
e := GetExchangeByName(name)
|
||||
e.Setup(exchCfg)
|
||||
log.Debugf(log.ExchangeSys, "%s exchange reloaded successfully.\n", name)
|
||||
return nil
|
||||
@@ -107,7 +96,7 @@ func UnloadExchange(name string) error {
|
||||
return ErrNoExchangesLoaded
|
||||
}
|
||||
|
||||
if !CheckExchangeExists(name) {
|
||||
if GetExchangeByName(name) == nil {
|
||||
return ErrExchangeNotFound
|
||||
}
|
||||
|
||||
@@ -139,7 +128,7 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error {
|
||||
var exch exchange.IBotExchange
|
||||
|
||||
if len(Bot.Exchanges) > 0 {
|
||||
if CheckExchangeExists(name) {
|
||||
if GetExchangeByName(name) != nil {
|
||||
return ErrExchangeAlreadyLoaded
|
||||
}
|
||||
}
|
||||
@@ -288,55 +277,65 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error {
|
||||
|
||||
Bot.Exchanges = append(Bot.Exchanges, exch)
|
||||
|
||||
base := exch.GetBase()
|
||||
if base.API.AuthenticatedSupport ||
|
||||
base.API.AuthenticatedWebsocketSupport {
|
||||
err = exch.ValidateCredentials()
|
||||
if err != nil {
|
||||
log.Warnf(log.ExchangeSys,
|
||||
"%s: Cannot validate credentials, authenticated support has been disabled, Error: %s\n",
|
||||
base.Name,
|
||||
err)
|
||||
base.API.AuthenticatedSupport = false
|
||||
base.API.AuthenticatedWebsocketSupport = false
|
||||
exchCfg.API.AuthenticatedSupport = false
|
||||
exchCfg.API.AuthenticatedWebsocketSupport = false
|
||||
}
|
||||
}
|
||||
|
||||
if useWG {
|
||||
exch.Start(wg)
|
||||
} else {
|
||||
wg := sync.WaitGroup{}
|
||||
exch.Start(&wg)
|
||||
wg.Wait()
|
||||
tempWG := sync.WaitGroup{}
|
||||
exch.Start(&tempWG)
|
||||
tempWG.Wait()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupExchanges sets up the exchanges used by the Bot
|
||||
func SetupExchanges() {
|
||||
var wg sync.WaitGroup
|
||||
exchanges := Bot.Config.GetAllExchangeConfigs()
|
||||
for x := range exchanges {
|
||||
exch := exchanges[x]
|
||||
if CheckExchangeExists(exch.Name) {
|
||||
e := GetExchangeByName(exch.Name)
|
||||
if e == nil {
|
||||
log.Errorln(log.ExchangeSys, ErrExchangeNotFound)
|
||||
continue
|
||||
}
|
||||
|
||||
err := ReloadExchange(exch.Name)
|
||||
configs := Bot.Config.GetAllExchangeConfigs()
|
||||
for x := range configs {
|
||||
if e := GetExchangeByName(configs[x].Name); e != nil {
|
||||
err := ReloadExchange(configs[x].Name)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "ReloadExchange %s failed: %s\n", exch.Name, err)
|
||||
log.Errorf(log.ExchangeSys, "ReloadExchange %s failed: %s\n", configs[x].Name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !e.IsEnabled() {
|
||||
UnloadExchange(exch.Name)
|
||||
UnloadExchange(configs[x].Name)
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
if !exch.Enabled && !Bot.Settings.EnableAllExchanges {
|
||||
log.Debugf(log.ExchangeSys, "%s: Exchange support: Disabled\n", exch.Name)
|
||||
if !configs[x].Enabled && !Bot.Settings.EnableAllExchanges {
|
||||
log.Debugf(log.ExchangeSys, "%s: Exchange support: Disabled\n", configs[x].Name)
|
||||
continue
|
||||
}
|
||||
err := LoadExchange(exch.Name, true, &wg)
|
||||
err := LoadExchange(configs[x].Name, true, &wg)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "LoadExchange %s failed: %s\n", exch.Name, err)
|
||||
log.Errorf(log.ExchangeSys, "LoadExchange %s failed: %s\n", configs[x].Name, err)
|
||||
continue
|
||||
}
|
||||
log.Debugf(log.ExchangeSys,
|
||||
"%s: Exchange support: Enabled (Authenticated API support: %s - Verbose mode: %s).\n",
|
||||
exch.Name,
|
||||
common.IsEnabled(exch.API.AuthenticatedSupport),
|
||||
common.IsEnabled(exch.Verbose),
|
||||
configs[x].Name,
|
||||
common.IsEnabled(configs[x].API.AuthenticatedSupport),
|
||||
common.IsEnabled(configs[x].Verbose),
|
||||
)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
@@ -21,7 +21,7 @@ func SetupTest(t *testing.T) {
|
||||
testSetup = true
|
||||
}
|
||||
|
||||
if CheckExchangeExists(testExchange) {
|
||||
if GetExchangeByName(testExchange) != nil {
|
||||
return
|
||||
}
|
||||
err := LoadExchange(testExchange, false, nil)
|
||||
@@ -31,7 +31,7 @@ func SetupTest(t *testing.T) {
|
||||
}
|
||||
|
||||
func CleanupTest(t *testing.T) {
|
||||
if !CheckExchangeExists(testExchange) {
|
||||
if GetExchangeByName(testExchange) == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -45,11 +45,11 @@ func CleanupTest(t *testing.T) {
|
||||
func TestCheckExchangeExists(t *testing.T) {
|
||||
SetupTest(t)
|
||||
|
||||
if !CheckExchangeExists(testExchange) {
|
||||
if GetExchangeByName(testExchange) == nil {
|
||||
t.Errorf("TestGetExchangeExists: Unable to find exchange")
|
||||
}
|
||||
|
||||
if CheckExchangeExists("Asdsad") {
|
||||
if GetExchangeByName("Asdsad") != nil {
|
||||
t.Errorf("TestGetExchangeExists: Non-existent exchange found")
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/dispatch"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/stats"
|
||||
@@ -447,18 +448,21 @@ func GetSpecificTicker(p currency.Pair, exchangeName string, assetType asset.Ite
|
||||
// GetCollatedExchangeAccountInfoByCoin collates individual exchange account
|
||||
// information and turns into into a map string of
|
||||
// exchange.AccountCurrencyInfo
|
||||
func GetCollatedExchangeAccountInfoByCoin(exchAccounts []exchange.AccountInfo) map[currency.Code]exchange.AccountCurrencyInfo {
|
||||
result := make(map[currency.Code]exchange.AccountCurrencyInfo)
|
||||
for _, accounts := range exchAccounts {
|
||||
for _, account := range accounts.Accounts {
|
||||
for _, accountCurrencyInfo := range account.Currencies {
|
||||
currencyName := accountCurrencyInfo.CurrencyName
|
||||
avail := accountCurrencyInfo.TotalValue
|
||||
onHold := accountCurrencyInfo.Hold
|
||||
|
||||
func GetCollatedExchangeAccountInfoByCoin(accounts []account.Holdings) map[currency.Code]account.Balance {
|
||||
result := make(map[currency.Code]account.Balance)
|
||||
for x := range accounts {
|
||||
for y := range accounts[x].Accounts {
|
||||
for z := range accounts[x].Accounts[y].Currencies {
|
||||
currencyName := accounts[x].Accounts[y].Currencies[z].CurrencyName
|
||||
avail := accounts[x].Accounts[y].Currencies[z].TotalValue
|
||||
onHold := accounts[x].Accounts[y].Currencies[z].Hold
|
||||
info, ok := result[currencyName]
|
||||
if !ok {
|
||||
accountInfo := exchange.AccountCurrencyInfo{CurrencyName: currencyName, Hold: onHold, TotalValue: avail}
|
||||
accountInfo := account.Balance{
|
||||
CurrencyName: currencyName,
|
||||
Hold: onHold,
|
||||
TotalValue: avail,
|
||||
}
|
||||
result[currencyName] = accountInfo
|
||||
} else {
|
||||
info.Hold += onHold
|
||||
@@ -471,16 +475,6 @@ func GetCollatedExchangeAccountInfoByCoin(exchAccounts []exchange.AccountInfo) m
|
||||
return result
|
||||
}
|
||||
|
||||
// GetAccountCurrencyInfoByExchangeName returns info for an exchange
|
||||
func GetAccountCurrencyInfoByExchangeName(accounts []exchange.AccountInfo, exchangeName string) (exchange.AccountInfo, error) {
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
if accounts[i].Exchange == exchangeName {
|
||||
return accounts[i], nil
|
||||
}
|
||||
}
|
||||
return exchange.AccountInfo{}, ErrExchangeNotFound
|
||||
}
|
||||
|
||||
// GetExchangeHighestPriceByCurrencyPair returns the exchange with the highest
|
||||
// price for a given currency pair and asset type
|
||||
func GetExchangeHighestPriceByCurrencyPair(p currency.Pair, assetType asset.Item) (string, error) {
|
||||
@@ -504,23 +498,23 @@ func GetExchangeLowestPriceByCurrencyPair(p currency.Pair, assetType asset.Item)
|
||||
}
|
||||
|
||||
// SeedExchangeAccountInfo seeds account info
|
||||
func SeedExchangeAccountInfo(data []exchange.AccountInfo) {
|
||||
if len(data) == 0 {
|
||||
func SeedExchangeAccountInfo(accounts []account.Holdings) {
|
||||
if len(accounts) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
port := portfolio.GetPortfolio()
|
||||
|
||||
for _, exchangeData := range data {
|
||||
exchangeName := exchangeData.Exchange
|
||||
var currencies []exchange.AccountCurrencyInfo
|
||||
for _, account := range exchangeData.Accounts {
|
||||
for _, info := range account.Currencies {
|
||||
for x := range accounts {
|
||||
exchangeName := accounts[x].Exchange
|
||||
var currencies []account.Balance
|
||||
for y := range accounts[x].Accounts {
|
||||
for z := range accounts[x].Accounts[y].Currencies {
|
||||
var update bool
|
||||
for i := range currencies {
|
||||
if info.CurrencyName == currencies[i].CurrencyName {
|
||||
currencies[i].Hold += info.Hold
|
||||
currencies[i].TotalValue += info.TotalValue
|
||||
if accounts[x].Accounts[y].Currencies[z].CurrencyName == currencies[i].CurrencyName {
|
||||
currencies[i].Hold += accounts[x].Accounts[y].Currencies[z].Hold
|
||||
currencies[i].TotalValue += accounts[x].Accounts[y].Currencies[z].TotalValue
|
||||
update = true
|
||||
}
|
||||
}
|
||||
@@ -529,17 +523,17 @@ func SeedExchangeAccountInfo(data []exchange.AccountInfo) {
|
||||
continue
|
||||
}
|
||||
|
||||
currencies = append(currencies, exchange.AccountCurrencyInfo{
|
||||
CurrencyName: info.CurrencyName,
|
||||
TotalValue: info.TotalValue,
|
||||
Hold: info.Hold,
|
||||
currencies = append(currencies, account.Balance{
|
||||
CurrencyName: accounts[x].Accounts[y].Currencies[z].CurrencyName,
|
||||
TotalValue: accounts[x].Accounts[y].Currencies[z].TotalValue,
|
||||
Hold: accounts[x].Accounts[y].Currencies[z].Hold,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, total := range currencies {
|
||||
currencyName := total.CurrencyName
|
||||
total := total.TotalValue
|
||||
for x := range currencies {
|
||||
currencyName := currencies[x].CurrencyName
|
||||
total := currencies[x].TotalValue
|
||||
|
||||
if !port.ExchangeAddressExists(exchangeName, currencyName) {
|
||||
if total <= 0 {
|
||||
@@ -768,7 +762,7 @@ func GetAllEnabledExchangeAccountInfo() AllEnabledExchangeAccounts {
|
||||
}
|
||||
continue
|
||||
}
|
||||
individualExchange, err := individualBot.GetAccountInfo()
|
||||
individualExchange, err := individualBot.FetchAccountInfo()
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "Error encountered retrieving exchange account info for %s. Error %s\n",
|
||||
individualBot.GetName(), err)
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/stats"
|
||||
@@ -453,13 +453,13 @@ func TestGetSpecificTicker(t *testing.T) {
|
||||
func TestGetCollatedExchangeAccountInfoByCoin(t *testing.T) {
|
||||
SetupTestHelpers(t)
|
||||
|
||||
var exchangeInfo []exchange.AccountInfo
|
||||
var info exchange.AccountInfo
|
||||
var exchangeInfo []account.Holdings
|
||||
|
||||
info.Exchange = "Bitfinex"
|
||||
info.Accounts = append(info.Accounts,
|
||||
exchange.Account{
|
||||
Currencies: []exchange.AccountCurrencyInfo{
|
||||
var bitfinexHoldings account.Holdings
|
||||
bitfinexHoldings.Exchange = "Bitfinex"
|
||||
bitfinexHoldings.Accounts = append(bitfinexHoldings.Accounts,
|
||||
account.SubAccount{
|
||||
Currencies: []account.Balance{
|
||||
{
|
||||
CurrencyName: currency.BTC,
|
||||
TotalValue: 100,
|
||||
@@ -468,21 +468,27 @@ func TestGetCollatedExchangeAccountInfoByCoin(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
exchangeInfo = append(exchangeInfo, info)
|
||||
exchangeInfo = append(exchangeInfo, bitfinexHoldings)
|
||||
|
||||
info.Exchange = "Bitstamp"
|
||||
info.Accounts = append(info.Accounts,
|
||||
exchange.Account{
|
||||
Currencies: []exchange.AccountCurrencyInfo{
|
||||
var bitstampHoldings account.Holdings
|
||||
bitstampHoldings.Exchange = "Bitstamp"
|
||||
bitstampHoldings.Accounts = append(bitstampHoldings.Accounts,
|
||||
account.SubAccount{
|
||||
Currencies: []account.Balance{
|
||||
{
|
||||
CurrencyName: currency.LTC,
|
||||
TotalValue: 100,
|
||||
Hold: 0,
|
||||
},
|
||||
{
|
||||
CurrencyName: currency.BTC,
|
||||
TotalValue: 100,
|
||||
Hold: 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
exchangeInfo = append(exchangeInfo, info)
|
||||
exchangeInfo = append(exchangeInfo, bitstampHoldings)
|
||||
|
||||
result := GetCollatedExchangeAccountInfoByCoin(exchangeInfo)
|
||||
if len(result) == 0 {
|
||||
@@ -504,40 +510,6 @@ func TestGetCollatedExchangeAccountInfoByCoin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountCurrencyInfoByExchangeName(t *testing.T) {
|
||||
SetupTestHelpers(t)
|
||||
|
||||
var exchangeInfo []exchange.AccountInfo
|
||||
var info exchange.AccountInfo
|
||||
info.Exchange = "Bitfinex"
|
||||
info.Accounts = append(info.Accounts,
|
||||
exchange.Account{
|
||||
Currencies: []exchange.AccountCurrencyInfo{
|
||||
{
|
||||
CurrencyName: currency.BTC,
|
||||
TotalValue: 100,
|
||||
Hold: 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
exchangeInfo = append(exchangeInfo, info)
|
||||
|
||||
result, err := GetAccountCurrencyInfoByExchangeName(exchangeInfo, "Bitfinex")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if result.Exchange != "Bitfinex" {
|
||||
t.Fatal("Unexepcted result")
|
||||
}
|
||||
|
||||
_, err = GetAccountCurrencyInfoByExchangeName(exchangeInfo, "ASDF")
|
||||
if err != ErrExchangeNotFound {
|
||||
t.Fatal("Unexepcted result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetExchangeHighestPriceByCurrencyPair(t *testing.T) {
|
||||
SetupTestHelpers(t)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package engine
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
||||
)
|
||||
@@ -42,5 +42,5 @@ type EnabledExchangeCurrencies struct {
|
||||
|
||||
// AllEnabledExchangeAccounts holds all enabled accounts info
|
||||
type AllEnabledExchangeAccounts struct {
|
||||
Data []exchange.AccountInfo `json:"data"`
|
||||
Data []account.Holdings `json:"data"`
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/database/models/postgres"
|
||||
"github.com/thrasher-corp/gocryptotrader/database/models/sqlite3"
|
||||
"github.com/thrasher-corp/gocryptotrader/database/repository/audit"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
||||
@@ -448,7 +449,7 @@ func (s *RPCServer) GetAccountInfo(ctx context.Context, r *gctrpc.GetAccountInfo
|
||||
return nil, errors.New("exchange is not loaded/doesn't exist")
|
||||
}
|
||||
|
||||
resp, err := exch.GetAccountInfo()
|
||||
resp, err := exch.FetchAccountInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -470,6 +471,87 @@ func (s *RPCServer) GetAccountInfo(ctx context.Context, r *gctrpc.GetAccountInfo
|
||||
return &gctrpc.GetAccountInfoResponse{Exchange: r.Exchange, Accounts: accounts}, nil
|
||||
}
|
||||
|
||||
// GetAccountInfoStream streams an account balance for a specific exchange
|
||||
func (s *RPCServer) GetAccountInfoStream(r *gctrpc.GetAccountInfoRequest, stream gctrpc.GoCryptoTrader_GetAccountInfoStreamServer) error {
|
||||
if r.Exchange == "" {
|
||||
return errors.New(errExchangeNameUnset)
|
||||
}
|
||||
|
||||
exch := GetExchangeByName(r.Exchange)
|
||||
if exch == nil {
|
||||
return errors.New("exchange is not loaded/doesn't exist")
|
||||
}
|
||||
|
||||
initAcc, err := exch.FetchAccountInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var accounts []*gctrpc.Account
|
||||
for x := range initAcc.Accounts {
|
||||
var subAccounts []*gctrpc.AccountCurrencyInfo
|
||||
for y := range initAcc.Accounts[x].Currencies {
|
||||
subAccounts = append(subAccounts, &gctrpc.AccountCurrencyInfo{
|
||||
Currency: initAcc.Accounts[x].Currencies[y].CurrencyName.String(),
|
||||
TotalValue: initAcc.Accounts[x].Currencies[y].TotalValue,
|
||||
Hold: initAcc.Accounts[x].Currencies[y].Hold,
|
||||
})
|
||||
}
|
||||
accounts = append(accounts, &gctrpc.Account{
|
||||
Id: initAcc.Accounts[x].ID,
|
||||
Currencies: subAccounts,
|
||||
})
|
||||
}
|
||||
|
||||
err = stream.Send(&gctrpc.GetAccountInfoResponse{
|
||||
Exchange: initAcc.Exchange,
|
||||
Accounts: accounts,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pipe, err := account.SubscribeToExchangeAccount(r.Exchange)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer pipe.Release()
|
||||
|
||||
for {
|
||||
data, ok := <-pipe.C
|
||||
if !ok {
|
||||
return errors.New(errDispatchSystem)
|
||||
}
|
||||
|
||||
acc := (*data.(*interface{})).(account.Holdings)
|
||||
|
||||
var accounts []*gctrpc.Account
|
||||
for x := range acc.Accounts {
|
||||
var subAccounts []*gctrpc.AccountCurrencyInfo
|
||||
for y := range acc.Accounts[x].Currencies {
|
||||
subAccounts = append(subAccounts, &gctrpc.AccountCurrencyInfo{
|
||||
Currency: acc.Accounts[x].Currencies[y].CurrencyName.String(),
|
||||
TotalValue: acc.Accounts[x].Currencies[y].TotalValue,
|
||||
Hold: acc.Accounts[x].Currencies[y].Hold,
|
||||
})
|
||||
}
|
||||
accounts = append(accounts, &gctrpc.Account{
|
||||
Id: acc.Accounts[x].ID,
|
||||
Currencies: subAccounts,
|
||||
})
|
||||
}
|
||||
|
||||
err := stream.Send(&gctrpc.GetAccountInfoResponse{
|
||||
Exchange: acc.Exchange,
|
||||
Accounts: accounts,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig returns the bots config
|
||||
func (s *RPCServer) GetConfig(ctx context.Context, r *gctrpc.GetConfigRequest) (*gctrpc.GetConfigResponse, error) {
|
||||
return &gctrpc.GetConfigResponse{}, common.ErrNotYetImplemented
|
||||
|
||||
Reference in New Issue
Block a user