Deposit address wrapper Update (#232)

* Add get deposit address and fix authentication issue for ZB exchange

*  Add get deposit address for Yobit exchange

* Add get deposit address for Poloniex exchange

* Add get deposit address for LocalBitcoins exchange

* Remove support for deposit address on Liqui exchange

*  Add get deposit address for LakeBTC exchange

* Add notes as to the reason of non implementation

* Add get deposit address for Kraken exchange

* Add get deposit address for HitBTC exchange

*  Add get deposit address for GateIO exchange

* Add get deposit address for Exmo exchange

*  Remove support for deposit address on Coinut exchange

* Add test case for BTC Markets function still not supported yet.

*  Add get deposit address for Bittrex exchange

* Add get deposit address for Bitstamp exchange

* Add get deposit address for Bitmex exchange
Rm unused swagger.json file in Bitmex exchange

* Add get deposit address for Bithumb exchange

* Add get deposit address for Binance exchange
Fix bug in Authenticated requests, concatenates sig string on end of query

* Remove support for deposit address on ANX exchange

* Updated account type to segregate multiple accounts on an exchange.

* Fix requested changes

* Add get deposit address for Bitfinex exchange
Add parameter for getting deposit address to wrapper

* Add get deposit address for ANX exchange

* Fix misspelling in Poloniex

* Drop working field and initialisation of zero value for Account Type

* Change switch to symbol package currency code
This commit is contained in:
Ryan O'Hara-Reid
2019-01-17 11:44:23 +11:00
committed by Adrian Gallagher
parent 88303b81ab
commit 84a67359c9
75 changed files with 1234 additions and 6559 deletions

View File

@@ -16,19 +16,26 @@ import (
// Alphapoint exchange
func (a *Alphapoint) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = a.GetName()
response.Exchange = a.GetName()
account, err := a.GetAccountInformation()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for i := 0; i < len(account.Currencies); i++ {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = account.Currencies[i].Name
exchangeCurrency.TotalValue = float64(account.Currencies[i].Balance)
exchangeCurrency.Hold = float64(account.Currencies[i].Hold)
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -164,7 +171,7 @@ func (a *Alphapoint) GetOrderInfo(orderID int64) (float64, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (a *Alphapoint) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
func (a *Alphapoint) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
addreses, err := a.GetDepositAddresses()
if err != nil {
return "", err

View File

@@ -385,7 +385,6 @@ func (a *ANX) GetDepositAddressByCurrency(currency, name string, new bool) (stri
}
err := a.SendAuthenticatedHTTPRequest(path, request, &response)
if err != nil {
return "", err
}

View File

@@ -395,3 +395,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := a.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := a.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -199,8 +199,10 @@ func (a *ANX) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.ExchangeName = a.GetName()
info.Currencies = balance
info.Exchange = a.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: balance,
})
return info, nil
}
@@ -305,8 +307,8 @@ func (a *ANX) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (a *ANX) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (a *ANX) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return a.GetDepositAddressByCurrency(cryptocurrency.String(), "", false)
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -2,6 +2,7 @@ package binance
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/url"
@@ -603,17 +604,36 @@ func (b *Binance) SendAuthHTTPRequest(method, path string, params url.Values, re
signature := params.Encode()
hmacSigned := common.GetHMAC(common.HashSHA256, []byte(signature), []byte(b.APISecret))
hmacSignedStr := common.HexEncodeToString(hmacSigned)
params.Set("signature", hmacSignedStr)
headers := make(map[string]string)
headers["X-MBX-APIKEY"] = b.APIKey
if b.Verbose {
log.Debugf("sent path: \n%s\n", path)
log.Debugf("sent path: %s", path)
}
path = common.EncodeURLValues(path, params)
return b.SendPayload(method, path, headers, bytes.NewBufferString(""), result, true, b.Verbose)
path = common.EncodeURLValues(path, params)
path += fmt.Sprintf("&signature=%s", hmacSignedStr)
interim := json.RawMessage{}
errCap := struct {
Success bool `json:"success"`
Message string `json:"msg"`
}{}
err := b.SendPayload(method, path, headers, bytes.NewBuffer(nil), &interim, true, b.Verbose)
if err != nil {
return err
}
if err := common.JSONDecode(interim, &errCap); err == nil {
if !errCap.Success && errCap.Message != "" {
return errors.New(errCap.Message)
}
}
return common.JSONDecode(interim, result)
}
// CheckLimit checks value against a variable list
@@ -742,15 +762,19 @@ func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string
}
//GetDepositAddressForCurrency retrieves the wallet address for a given currency
func (b *Binance) GetDepositAddressForCurrency(currency string) error {
func (b *Binance) GetDepositAddressForCurrency(currency string) (string, error) {
path := fmt.Sprintf("%s%s", b.APIUrl, depositAddress)
var resp interface{}
resp := struct {
Address string `json:"address"`
Success bool `json:"success"`
AddressTag string `json:"addressTag"`
}{}
params := url.Values{}
params.Set("asset", currency)
params.Set("status", "true")
if err := b.SendAuthHTTPRequest("GET", path, params, &resp); err != nil {
return err
}
return nil
return resp.Address,
b.SendAuthHTTPRequest("GET", path, params, &resp)
}

View File

@@ -4,10 +4,9 @@ import (
"testing"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
"github.com/thrasher-/gocryptotrader/config"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
)
@@ -425,7 +424,7 @@ func TestGetAccountInfo(t *testing.T) {
_, err := b.GetAccountInfo()
if err != nil {
t.Error("test failed - GetAccountInfo() error:", err)
t.Error("test failed - GetAccountInfo() error", err)
}
}
@@ -491,3 +490,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -157,8 +157,11 @@ func (b *Binance) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.ExchangeName = b.GetName()
info.Currencies = currencyBalance
info.Exchange = b.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: currencyBalance,
})
return info, nil
}
@@ -264,8 +267,8 @@ func (b *Binance) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Binance) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (b *Binance) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return b.GetDepositAddressForCurrency(cryptocurrency.String())
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -1087,3 +1087,31 @@ func (b *Bitfinex) ConvertSymbolToWithdrawalType(currency string) string {
return common.StringToLower(currency)
}
}
// ConvertSymbolToDepositMethod returns a converted currency deposit method
func (b *Bitfinex) ConvertSymbolToDepositMethod(currency string) (method string, err error) {
switch currency {
case symbol.BTC:
method = "bitcoin"
case symbol.LTC:
method = "litecoin"
case symbol.ETH:
method = "ethereum"
case symbol.ETC:
method = "ethereumc"
case symbol.USDT:
method = "tetheruso"
case symbol.ZEC:
method = "zcash"
case symbol.XMR:
method = "monero"
case symbol.BCH:
method = "bcash"
case symbol.MIOTA:
method = "iota"
default:
err = fmt.Errorf("currency %s not supported in method list",
currency)
}
return
}

View File

@@ -241,14 +241,14 @@ func TestGetSymbolsDetails(t *testing.T) {
}
func TestGetAccountInfo(t *testing.T) {
if b.APIKey == "" || b.APISecret == "" {
if !areTestAPIKeysSet() {
t.SkipNow()
}
t.Parallel()
_, err := b.GetAccountInfo()
if err == nil {
t.Error("Test Failed - GetAccountInfo error")
if err != nil {
t.Error("Test Failed - GetAccountInfo error", err)
}
}
@@ -903,3 +903,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Withdraw failed to be placed: %v", err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := b.GetDepositAddress(symbol.BTC, "deposit")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := b.GetDepositAddress(symbol.BTC, "deposit")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -118,46 +118,32 @@ func (b *Bitfinex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (order
// Bitfinex exchange
func (b *Bitfinex) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = b.GetName()
response.Exchange = b.GetName()
accountBalance, err := b.GetAccountBalance()
if err != nil {
return response, err
}
if !b.Enabled {
return response, nil
var Accounts = []exchange.Account{
{ID: "deposit"},
{ID: "exchange"},
{ID: "trading"},
}
type bfxCoins struct {
OnHold float64
Available float64
}
accounts := make(map[string]bfxCoins)
for i := range accountBalance {
onHold := accountBalance[i].Amount - accountBalance[i].Available
coins := bfxCoins{
OnHold: onHold,
Available: accountBalance[i].Available,
}
result, ok := accounts[accountBalance[i].Currency]
if !ok {
accounts[accountBalance[i].Currency] = coins
} else {
result.Available += accountBalance[i].Available
result.OnHold += onHold
accounts[accountBalance[i].Currency] = result
for _, bal := range accountBalance {
for i := range Accounts {
if Accounts[i].ID == bal.Type {
Accounts[i].Currencies = append(Accounts[i].Currencies,
exchange.AccountCurrencyInfo{
CurrencyName: bal.Currency,
TotalValue: bal.Amount,
Hold: bal.Amount - bal.Available,
})
}
}
}
for x, y := range accounts {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = common.StringToUpper(x)
exchangeCurrency.TotalValue = y.Available + y.OnHold
exchangeCurrency.Hold = y.OnHold
response.Currencies = append(response.Currencies, exchangeCurrency)
}
response.Accounts = Accounts
return response, nil
}
@@ -229,8 +215,18 @@ func (b *Bitfinex) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Bitfinex) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (b *Bitfinex) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
method, err := b.ConvertSymbolToDepositMethod(cryptocurrency.String())
if err != nil {
return "", err
}
resp, err := b.NewDeposit(method, accountID, 0)
if err != nil {
return "", err
}
return resp.Address, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted

View File

@@ -124,7 +124,7 @@ func (b *Bitflyer) UpdateOrderbook(p pair.CurrencyPair, assetType string) (order
// Bitflyer exchange
func (b *Bitflyer) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = b.GetName()
response.Exchange = b.GetName()
// accountBalance, err := b.GetAccountBalance()
// if err != nil {
// return response, err
@@ -184,7 +184,7 @@ func (b *Bitflyer) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Bitflyer) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
func (b *Bitflyer) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrNotYetImplemented
}

View File

@@ -321,8 +321,18 @@ func (b *Bithumb) GetWalletAddress(currency string) (WalletAddressRes, error) {
params := url.Values{}
params.Set("currency", common.StringToUpper(currency))
return response,
b.SendAuthenticatedHTTPRequest(privateWalletAdd, params, &response)
err := b.SendAuthenticatedHTTPRequest(privateWalletAdd, params, &response)
if err != nil {
return response, err
}
if response.Data.WalletAddress == "" {
return response,
fmt.Errorf("deposit address needs to be created via the Bithumb website before retreival for currency %s",
currency)
}
return response, nil
}
// GetLastTransaction returns customer last transaction

View File

@@ -7,7 +7,7 @@ import (
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
"github.com/thrasher-/gocryptotrader/exchanges"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
)
// Please supply your own keys here for due diligence testing
@@ -482,3 +482,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if testAPIKey != "" && testAPISecret != "" {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -146,8 +146,11 @@ func (b *Bithumb) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.Currencies = exchangeBalances
info.ExchangeName = b.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: exchangeBalances,
})
info.Exchange = b.GetName()
return info, nil
}
@@ -248,8 +251,13 @@ func (b *Bithumb) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Bithumb) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (b *Bithumb) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
addr, err := b.GetWalletAddress(cryptocurrency.String())
if err != nil {
return "", err
}
return addr.Data.WalletAddress, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -5,11 +5,13 @@ import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/symbol"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
@@ -700,9 +702,15 @@ func (b *Bitmex) ConfirmWithdrawal(token string) (TransactionInfo, error) {
func (b *Bitmex) GetCryptoDepositAddress(currency string) (string, error) {
var address string
if !strings.EqualFold(currency, symbol.XBT) {
return "",
fmt.Errorf("cryptocurrency %s deposits are not supported by exchange only bitcoin",
currency)
}
return address, b.SendAuthenticatedHTTPRequest("GET",
bitmexEndpointUserDepositAddress,
UserCurrencyParams{Currency: currency},
UserCurrencyParams{Currency: "XBt"},
&address)
}

View File

@@ -6,11 +6,10 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
"github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/config"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
)
// Please supply your own keys here for due diligence testing
@@ -638,3 +637,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -142,8 +142,11 @@ func (b *Bitmex) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.ExchangeName = b.GetName()
info.Currencies = balances
info.Exchange = b.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: balances,
})
return info, nil
}
@@ -250,8 +253,8 @@ func (b *Bitmex) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Bitmex) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (b *Bitmex) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return b.GetCryptoDepositAddress(cryptocurrency.String())
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,7 @@
package bitstamp
import (
"encoding/json"
"errors"
"fmt"
"net/url"
@@ -43,6 +44,7 @@ const (
bitstampAPIBitcoinDeposit = "bitcoin_deposit_address"
bitstampAPILitecoinDeposit = "ltc_address"
bitstampAPIEthereumDeposit = "eth_address"
bitstampAPIBitcoinCashDeposit = "bch_address"
bitstampAPIUnconfirmedBitcoin = "unconfirmed_btc"
bitstampAPITransferToMain = "transfer-to-main"
bitstampAPITransferFromMain = "transfer-from-main"
@@ -565,29 +567,34 @@ func (b *Bitstamp) OpenInternationalBankWithdrawal(amount float64, currency,
}
// GetCryptoDepositAddress returns a depositing address by crypto
// crypto - example "btc", "ltc", "eth", or "xrp"
// crypto - example "btc", "ltc", "eth", "xrp" or "bch"
func (b *Bitstamp) GetCryptoDepositAddress(crypto string) (string, error) {
type response struct {
Address string `json:"address"`
}
resp := response{}
var resp string
switch common.StringToLower(crypto) {
case "btc":
return resp.Address,
b.SendAuthenticatedHTTPRequest(bitstampAPIBitcoinDeposit, false, nil, &resp.Address)
case "ltc":
return resp.Address,
switch crypto {
case symbol.BTC:
return resp,
b.SendAuthenticatedHTTPRequest(bitstampAPIBitcoinDeposit, false, nil, &resp)
case symbol.LTC:
return resp,
b.SendAuthenticatedHTTPRequest(bitstampAPILitecoinDeposit, true, nil, &resp)
case "eth":
return resp.Address,
b.SendAuthenticatedHTTPRequest(bitstampAPIEthereumDeposit, true, nil, &resp)
case "xrp":
return resp.Address,
b.SendAuthenticatedHTTPRequest(bitstampAPIXrpDeposit, true, nil, &resp)
}
return resp.Address, errors.New("incorrect cryptocurrency string")
case symbol.ETH:
return resp,
b.SendAuthenticatedHTTPRequest(bitstampAPIEthereumDeposit, true, nil, &resp)
case symbol.XRP:
return resp,
b.SendAuthenticatedHTTPRequest(bitstampAPIXrpDeposit, true, nil, &resp)
case symbol.BCH:
return resp,
b.SendAuthenticatedHTTPRequest(bitstampAPIBitcoinCashDeposit, true, nil, &resp)
default:
return resp, fmt.Errorf("unsupported cryptocurrency string %s", crypto)
}
}
// GetUnconfirmedBitcoinDeposits returns unconfirmed transactions
@@ -628,7 +635,7 @@ func (b *Bitstamp) SendHTTPRequest(path string, result interface{}) error {
}
// SendAuthenticatedHTTPRequest sends an authenticated request
func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url.Values, result interface{}) (err error) {
func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url.Values, result interface{}) error {
if !b.AuthenticatedAPISupport {
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
}
@@ -663,5 +670,23 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url
encodedValues := values.Encode()
readerValues := strings.NewReader(encodedValues)
return b.SendPayload("POST", path, headers, readerValues, result, true, b.Verbose)
interim := json.RawMessage{}
errCap := struct {
Error string `json:"error"`
}{}
err := b.SendPayload("POST", path, headers, readerValues, &interim, true, b.Verbose)
if err != nil {
return err
}
if err := common.JSONDecode(interim, &errCap); err == nil {
if errCap.Error != "" {
return errors.New(errCap.Error)
}
}
return common.JSONDecode(interim, result)
}

View File

@@ -5,11 +5,10 @@ import (
"testing"
"time"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
"github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/config"
)
// Please add your private keys and customerID for better tests
@@ -567,3 +566,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Withdraw failed to be placed: %v", err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() && customerID != "" {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress error", err)
}
} else {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress error cannot be nil")
}
}
}

View File

@@ -120,35 +120,42 @@ func (b *Bitstamp) UpdateOrderbook(p pair.CurrencyPair, assetType string) (order
// Bitstamp exchange
func (b *Bitstamp) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = b.GetName()
response.Exchange = b.GetName()
accountBalance, err := b.GetBalance()
if err != nil {
return response, err
}
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
var currencies []exchange.AccountCurrencyInfo
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "BTC",
TotalValue: accountBalance.BTCAvailable,
Hold: accountBalance.BTCReserved,
})
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "XRP",
TotalValue: accountBalance.XRPAvailable,
Hold: accountBalance.XRPReserved,
})
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "USD",
TotalValue: accountBalance.USDAvailable,
Hold: accountBalance.USDReserved,
})
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "EUR",
TotalValue: accountBalance.EURAvailable,
Hold: accountBalance.EURReserved,
})
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -219,8 +226,8 @@ func (b *Bitstamp) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Bitstamp) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (b *Bitstamp) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return b.GetCryptoDepositAddress(cryptocurrency.String())
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -168,15 +168,6 @@ func TestGetAccountBalanceByCurrency(t *testing.T) {
}
}
func TestGetDepositAddress(t *testing.T) {
t.Parallel()
_, err := b.GetDepositAddress("btc")
if err == nil {
t.Error("Test Failed - Bittrex - GetDepositAddress() error")
}
}
func TestGetOrder(t *testing.T) {
t.Parallel()
@@ -481,3 +472,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -65,19 +65,25 @@ func (b *Bittrex) Run() {
// Bittrex exchange
func (b *Bittrex) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = b.GetName()
response.Exchange = b.GetName()
accountBalance, err := b.GetAccountBalances()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for i := 0; i < len(accountBalance.Result); i++ {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = accountBalance.Result[i].Currency
exchangeCurrency.TotalValue = accountBalance.Result[i].Balance
exchangeCurrency.Hold = accountBalance.Result[i].Balance - accountBalance.Result[i].Available
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -237,8 +243,13 @@ func (b *Bittrex) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Bittrex) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (b *Bittrex) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
depositAddr, err := b.GetCryptoDepositAddress(cryptocurrency.String())
if err != nil {
return "", err
}
return depositAddr.Result.Address, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -180,8 +180,8 @@ func (b *BTCC) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *BTCC) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (b *BTCC) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrFunctionNotSupported
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -32,7 +32,7 @@ func TestSetup(t *testing.T) {
t.Error("Test Failed - BTC Markets Setup() init error")
}
if apiKey != "" && apiSecret != "" {
if areTestAPIKeysSet() {
bConfig.APIKey = apiKey
bConfig.APISecret = apiSecret
bConfig.AuthenticatedAPISupport = true
@@ -450,3 +450,10 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
_, err := b.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}

View File

@@ -122,21 +122,27 @@ func (b *BTCMarkets) UpdateOrderbook(p pair.CurrencyPair, assetType string) (ord
// BTCMarkets exchange
func (b *BTCMarkets) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = b.GetName()
response.Exchange = b.GetName()
accountBalance, err := b.GetAccountBalance()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for i := 0; i < len(accountBalance); i++ {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = accountBalance[i].Currency
exchangeCurrency.TotalValue = accountBalance[i].Balance
exchangeCurrency.Hold = accountBalance[i].PendingFunds
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -256,7 +262,7 @@ func (b *BTCMarkets) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *BTCMarkets) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
func (b *BTCMarkets) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrFunctionNotSupported
}

View File

@@ -577,3 +577,10 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Withdraw failed to be placed: %v", err)
}
}
func TestGetDepositAddress(t *testing.T) {
_, err := c.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
}

View File

@@ -51,19 +51,26 @@ func (c *CoinbasePro) Run() {
// coinbasepro exchange
func (c *CoinbasePro) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = c.GetName()
response.Exchange = c.GetName()
accountBalance, err := c.GetAccounts()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for i := 0; i < len(accountBalance); i++ {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = accountBalance[i].Currency
exchangeCurrency.TotalValue = accountBalance[i].Available
exchangeCurrency.Hold = accountBalance[i].Hold
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -194,8 +201,8 @@ func (c *CoinbasePro) GetOrderInfo(orderID int64) (exchange.OrderDetail, error)
}
// GetDepositAddress returns a deposit address for a specified currency
func (c *CoinbasePro) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (c *CoinbasePro) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrFunctionNotSupported
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -360,3 +360,10 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
_, err := c.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() function unsupported cannot be nil")
}
}

View File

@@ -131,8 +131,11 @@ func (c *COINUT) GetAccountInfo() (exchange.AccountInfo, error) {
TotalValue: bal.ZEC,
})
info.ExchangeName = c.GetName()
info.Currencies = balances
info.Exchange = c.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: balances,
})
return info, nil
}
@@ -345,8 +348,8 @@ func (c *COINUT) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (c *COINUT) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (c *COINUT) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrFunctionNotSupported
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -188,8 +188,14 @@ const (
// AccountInfo is a Generic type to hold each exchange's holdings in
// all enabled currencies
type AccountInfo struct {
ExchangeName string
Currencies []AccountCurrencyInfo
Exchange string
Accounts []Account
}
// Account defines a singular account type with asocciated currencies
type Account struct {
ID string
Currencies []AccountCurrencyInfo
}
// AccountCurrencyInfo is a sub type to store currency name and value
@@ -308,7 +314,7 @@ type IBotExchange interface {
CancelOrder(order OrderCancellation) error
CancelAllOrders(orders OrderCancellation) (CancelAllOrdersResponse, error)
GetOrderInfo(orderID int64) (OrderDetail, error)
GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error)
GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error)
WithdrawCryptocurrencyFunds(wtihdrawRequest WithdrawRequest) (string, error)
WithdrawFiatFunds(wtihdrawRequest WithdrawRequest) (string, error)

View File

@@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/url"
"reflect"
"strconv"
"strings"
"time"
@@ -272,10 +271,26 @@ func (e *EXMO) GetRequiredAmount(pair string, amount float64) (RequiredAmount, e
// GetCryptoDepositAddress returns a list of addresses for cryptocurrency deposits
func (e *EXMO) GetCryptoDepositAddress() (map[string]string, error) {
result := make(map[string]string)
var result interface{}
err := e.SendAuthenticatedHTTPRequest("POST", exmoDepositAddress, url.Values{}, &result)
log.Debug(reflect.TypeOf(result).String())
return result, err
if err != nil {
return nil, err
}
switch result.(type) {
case map[string]interface{}:
mapString := make(map[string]string)
for key, value := range result.(map[string]interface{}) {
strValue := fmt.Sprintf("%v", value)
mapString[key] = strValue
}
return mapString, nil
default:
return nil, errors.New("no addresses found, generate required addresses via site")
}
}
// WithdrawCryptocurrency withdraws a cryptocurrency from the exchange to the desired address

View File

@@ -93,18 +93,6 @@ func TestGetRequiredAmount(t *testing.T) {
}
}
func TestGetCryptoDepositAddress(t *testing.T) {
t.Parallel()
if APIKey == "" || APISecret == "" {
t.Skip()
}
TestSetup(t)
_, err := e.GetCryptoDepositAddress()
if err == nil {
t.Errorf("Test failed. Err: %s", err)
}
}
func setFeeBuilder() exchange.FeeBuilder {
return exchange.FeeBuilder{
Amount: 1,
@@ -400,3 +388,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := e.GetDepositAddress(symbol.LTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := e.GetDepositAddress(symbol.LTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -140,12 +140,13 @@ func (e *EXMO) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook
// Exmo exchange
func (e *EXMO) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = e.GetName()
response.Exchange = e.GetName()
result, err := e.GetUserInfo()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for x, y := range result.Balances {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = common.StringToUpper(x)
@@ -157,8 +158,13 @@ func (e *EXMO) GetAccountInfo() (exchange.AccountInfo, error) {
exchangeCurrency.Hold = reserved
}
}
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -249,8 +255,18 @@ func (e *EXMO) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (e *EXMO) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (e *EXMO) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
fullAddr, err := e.GetCryptoDepositAddress()
if err != nil {
return "", err
}
addr, ok := fullAddr[cryptocurrency.String()]
if !ok {
return "", fmt.Errorf("currency %s could not be found, please generate via the exmo website", cryptocurrency.String())
}
return addr, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -30,12 +30,15 @@ const (
gateioCancelAllOrders = "private/cancelAllOrders"
gateioWithdraw = "private/withdraw"
gateioOpenOrders = "private/openOrders"
gateioDepositAddress = "private/depositAddress"
gateioTicker = "ticker"
gateioTickers = "tickers"
gateioOrderbook = "orderBook"
gateioAuthRate = 100
gateioUnauthRate = 100
gateioGenerateAddress = "New address is being generated for you, please wait a moment and refresh this page. "
)
// Gateio is the overarching type across this package
@@ -534,3 +537,28 @@ func (g *Gateio) WithdrawCrypto(currency, address string, amount float64) (strin
return "", nil
}
// GetCryptoDepositAddress returns a deposit address for a cryptocurrency
func (g *Gateio) GetCryptoDepositAddress(currency string) (string, error) {
type response struct {
Result bool `json:"result,string"`
Code int `json:"code"`
Message string `json:"message"`
Address string `json:"addr"`
}
var result response
params := fmt.Sprintf("currency=%s",
currency)
err := g.SendAuthenticatedHTTPRequest("POST", gateioDepositAddress, params, &result)
if err != nil {
return "", err
}
if !result.Result {
return "", fmt.Errorf("code:%d message:%s", result.Code, result.Message)
}
return result.Address, nil
}

View File

@@ -164,7 +164,7 @@ func TestGetFee(t *testing.T) {
TestSetup(t)
var feeBuilder = setFeeBuilder()
if apiKey != "" && apiSecret != "" {
if areTestAPIKeysSet() {
// CryptocurrencyTradeFee Basic
if resp, err := g.GetFee(feeBuilder); resp != float64(0.002) || err != nil {
t.Error(err)
@@ -421,3 +421,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := g.GetDepositAddress(symbol.ETC, "")
if err != nil {
t.Error("Test Fail - GetDepositAddress error", err)
}
} else {
_, err := g.GetDepositAddress(symbol.ETC, "")
if err == nil {
t.Error("Test Fail - GetDepositAddress error cannot be nil")
}
}
}

View File

@@ -1,9 +1,11 @@
package gateio
import (
"errors"
"fmt"
"strconv"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -161,8 +163,11 @@ func (g *Gateio) GetAccountInfo() (exchange.AccountInfo, error) {
}
}
info.Currencies = balances
info.ExchangeName = g.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: balances,
})
info.Exchange = g.GetName()
return info, nil
}
@@ -262,8 +267,24 @@ func (g *Gateio) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (g *Gateio) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (g *Gateio) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
addr, err := g.GetCryptoDepositAddress(cryptocurrency.String())
if err != nil {
return "", err
}
// Waits for new generated address if not created yet, its variable per
// currency
if addr == gateioGenerateAddress {
time.Sleep(10 * time.Second)
addr, err = g.GetCryptoDepositAddress(cryptocurrency.String())
if addr == gateioGenerateAddress {
return "", errors.New("address not generated in time")
}
return addr, nil
}
return addr, err
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -502,3 +502,10 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
_, err := Session[1].GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress error cannot be nil")
}
}

View File

@@ -46,18 +46,25 @@ func (g *Gemini) Run() {
// Gemini exchange
func (g *Gemini) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = g.GetName()
response.Exchange = g.GetName()
accountBalance, err := g.GetBalances()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for i := 0; i < len(accountBalance); i++ {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = accountBalance[i].Currency
exchangeCurrency.TotalValue = accountBalance[i].Amount
exchangeCurrency.Hold = accountBalance[i].Available
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -186,8 +193,12 @@ func (g *Gemini) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (g *Gemini) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (g *Gemini) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
addr, err := g.GetCryptoDepositAddress("", cryptocurrency.String())
if err != nil {
return "", err
}
return addr.Address, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -364,10 +364,13 @@ func (h *HitBTC) GetBalances() (map[string]Balance, error) {
// GetDepositAddresses returns a deposit address for a specific currency
func (h *HitBTC) GetDepositAddresses(currency string) (DepositCryptoAddresses, error) {
resp := DepositCryptoAddresses{}
err := h.SendAuthenticatedHTTPRequest("GET", apiV2CryptoAddress+"/"+currency, url.Values{}, &resp)
var resp DepositCryptoAddresses
return resp, err
return resp,
h.SendAuthenticatedHTTPRequest("GET",
apiV2CryptoAddress+"/"+currency,
url.Values{},
&resp)
}
// GenerateNewAddress generates a new deposit address for a currency

View File

@@ -13,7 +13,6 @@ import (
var h HitBTC
// Please supply your own APIKEYS here for due diligence testing
const (
apiKey = ""
apiSecret = ""
@@ -86,7 +85,7 @@ func TestGetFee(t *testing.T) {
TestSetup(t)
var feeBuilder = setFeeBuilder()
if apiKey != "" && apiSecret != "" {
if areTestAPIKeysSet() {
// CryptocurrencyTradeFee Basic
if resp, err := h.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
t.Error(err)
@@ -332,3 +331,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := h.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := h.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -126,19 +126,25 @@ func (h *HitBTC) UpdateOrderbook(currencyPair pair.CurrencyPair, assetType strin
// HitBTC exchange
func (h *HitBTC) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = h.GetName()
response.Exchange = h.GetName()
accountBalance, err := h.GetBalances()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for _, item := range accountBalance {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = item.Currency
exchangeCurrency.TotalValue = item.Available
exchangeCurrency.Hold = item.Reserved
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -215,8 +221,13 @@ func (h *HitBTC) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (h *HitBTC) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (h *HitBTC) GetDepositAddress(currency pair.CurrencyItem, accountID string) (string, error) {
resp, err := h.GetDepositAddresses(currency.String())
if err != nil {
return "", err
}
return resp.Address, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -574,3 +574,10 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
_, err := h.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}

View File

@@ -149,76 +149,83 @@ func (h *HUOBI) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderboo
return orderbook.GetOrderbook(h.Name, p, assetType)
}
var mtx sync.Mutex
// GetAccountID returns the account ID for trades NOTE interim implementation
// does not account for multiple account IDs
func (h *HUOBI) GetAccountID() (string, error) {
mtx.Lock()
defer mtx.Unlock()
if h.AccountID == "" {
acc, err := h.GetAccounts()
if err != nil {
return "", err
}
if len(acc) > 0 {
return strconv.FormatInt(acc[0].ID, 10), nil
}
return "", errors.New("no user ID fetched")
// GetAccountID returns the account ID for trades
func (h *HUOBI) GetAccountID() ([]Account, error) {
acc, err := h.GetAccounts()
if err != nil {
return nil, err
}
return h.AccountID, nil
if len(acc) < 1 {
return nil, errors.New("no account returned")
}
return acc, nil
}
//GetAccountInfo retrieves balances for all enabled currencies for the
// HUOBI exchange - to-do
func (h *HUOBI) GetAccountInfo() (exchange.AccountInfo, error) {
var info exchange.AccountInfo
info.ExchangeName = h.GetName()
info.Exchange = h.GetName()
accID, err := h.GetAccountID()
accounts, err := h.GetAccountID()
if err != nil {
return info, err
}
acc, err := h.GetAccountBalance(accID)
if err != nil {
return info, err
}
for _, account := range accounts {
var acc exchange.Account
type hold struct {
Avail float64
Hold float64
}
acc.ID = strconv.FormatInt(account.ID, 10)
var currencyData = make(map[string]*hold)
for _, data := range acc {
_, ok := currencyData[data.Currency]
if !ok {
currencyData[data.Currency] = &hold{}
balances, err := h.GetAccountBalance(acc.ID)
if err != nil {
return info, err
}
if data.Type == "trade" {
currencyData[data.Currency].Avail = data.Balance
} else {
currencyData[data.Currency].Hold = data.Balance
var currencyDetails []exchange.AccountCurrencyInfo
for _, balance := range balances {
var frozen bool
if balance.Type == "frozen" {
frozen = true
}
var updated bool
for i := range currencyDetails {
if currencyDetails[i].CurrencyName == balance.Currency {
if frozen {
currencyDetails[i].Hold = balance.Balance
} else {
currencyDetails[i].TotalValue = balance.Balance
}
updated = true
}
}
if updated {
continue
}
if frozen {
currencyDetails = append(currencyDetails,
exchange.AccountCurrencyInfo{
CurrencyName: balance.Currency,
Hold: balance.Balance,
})
} else {
currencyDetails = append(currencyDetails,
exchange.AccountCurrencyInfo{
CurrencyName: balance.Currency,
TotalValue: balance.Balance,
})
}
}
acc.Currencies = currencyDetails
info.Accounts = append(info.Accounts, acc)
}
var balances []exchange.AccountCurrencyInfo
for key, data := range currencyData {
balances = append(balances, exchange.AccountCurrencyInfo{
CurrencyName: key,
TotalValue: data.Avail + data.Hold,
Hold: data.Hold,
})
}
info.Currencies = balances
return info, nil
}
@@ -330,8 +337,8 @@ func (h *HUOBI) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (h *HUOBI) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (h *HUOBI) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrFunctionNotSupported
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -51,6 +51,7 @@ const (
huobihadaxMarginAccountBalance = "margin/accounts/balance"
huobihadaxWithdrawCreate = "dw/withdraw/api/create"
huobihadaxWithdrawCancel = "dw/withdraw-virtual/%s/cancel"
huobiHadaxDepositAddress = "query/deposit-withdraw"
huobihadaxAuthRate = 100
huobihadaxUnauthRate = 100
@@ -58,7 +59,6 @@ const (
// HUOBIHADAX is the overarching type across this package
type HUOBIHADAX struct {
AccountID string
exchange.Base
}
@@ -886,3 +886,33 @@ func calculateTradingFee(purchasePrice, amount float64) float64 {
feePercent := 0.002
return feePercent * purchasePrice * amount
}
// GetDepositWithdrawalHistory returns deposit or withdrawal data
func (h *HUOBIHADAX) GetDepositWithdrawalHistory(associatedID string, currency string, isDeposit bool, size int64) ([]History, error) {
var resp = struct {
Response
Data []History `json:"data"`
}{}
vals := url.Values{}
if isDeposit {
vals.Set("type", "deposit")
} else {
vals.Set("type", "withdraw")
}
vals.Set("from", associatedID)
vals.Set("size", strconv.FormatInt(size, 10))
vals.Set("currency", common.StringToLower(currency))
err := h.SendAuthenticatedHTTPRequest("GET",
huobiHadaxDepositAddress,
vals,
&resp)
if resp.ErrorMessage != "" {
return resp.Data, errors.New(resp.ErrorMessage)
}
return resp.Data, err
}

View File

@@ -558,3 +558,10 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
_, err := h.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}

View File

@@ -88,10 +88,10 @@ type Symbol struct {
// Account stores the account data
type Account struct {
ID int64 `json:"id"`
Type string `json:"type"`
State string `json:"working"`
UserID int64 `json:"user-id"`
ID int64 `json:"id"`
Type string `json:"type"`
SubType string `json:"subtype"`
State string `json:"state"`
}
// AccountBalance stores the user all account balance
@@ -234,3 +234,17 @@ var (
TimeIntervalMohth = TimeInterval("1mon")
TimeIntervalYear = TimeInterval("1year")
)
// History defines currency deposit or withdrawal data
type History struct {
ID int64 `json:"id"`
Type string `json:"type"`
Currency string `json:"currency"`
TxHash string `json:"tx-hash"`
Amount float64 `json:"amount"`
Address string `json:"address"`
Fee float64 `json:"fee"`
State string `json:"state"`
CreatedAt int64 `json:"created-at"`
UpdatedAt int64 `json:"Updated-at"`
}

View File

@@ -114,76 +114,83 @@ func (h *HUOBIHADAX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (ord
return orderbook.GetOrderbook(h.Name, p, assetType)
}
var mtx sync.Mutex
// GetAccountID returns the account ID for trades NOTE interim implementation
// does not account for multiple account IDs
func (h *HUOBIHADAX) GetAccountID() (string, error) {
mtx.Lock()
defer mtx.Unlock()
if h.AccountID == "" {
acc, err := h.GetAccounts()
if err != nil {
return "", err
}
if len(acc) > 0 {
return strconv.FormatInt(acc[0].ID, 10), nil
}
return "", errors.New("no account ID fetched")
// GetAccountID returns the account info
func (h *HUOBIHADAX) GetAccountID() ([]Account, error) {
acc, err := h.GetAccounts()
if err != nil {
return nil, err
}
return h.AccountID, nil
if len(acc) < 1 {
return nil, errors.New("no account returned")
}
return acc, nil
}
// GetAccountInfo retrieves balances for all enabled currencies for the
// HUOBIHADAX exchange
func (h *HUOBIHADAX) GetAccountInfo() (exchange.AccountInfo, error) {
var info exchange.AccountInfo
info.ExchangeName = h.GetName()
info.Exchange = h.GetName()
accID, err := h.GetAccountID()
accounts, err := h.GetAccountID()
if err != nil {
return info, err
}
acc, err := h.GetAccountBalance(accID)
if err != nil {
return info, err
}
for _, account := range accounts {
var acc exchange.Account
type hold struct {
Avail float64
Hold float64
}
acc.ID = strconv.FormatInt(account.ID, 10)
var currencyData = make(map[string]*hold)
for _, data := range acc {
_, ok := currencyData[data.Currency]
if !ok {
currencyData[data.Currency] = &hold{}
balances, err := h.GetAccountBalance(acc.ID)
if err != nil {
return info, err
}
if data.Type == "trade" {
currencyData[data.Currency].Avail = data.Balance
} else {
currencyData[data.Currency].Hold = data.Balance
var currencyDetails []exchange.AccountCurrencyInfo
for _, balance := range balances {
var frozen bool
if balance.Type == "frozen" {
frozen = true
}
var updated bool
for i := range currencyDetails {
if currencyDetails[i].CurrencyName == balance.Currency {
if frozen {
currencyDetails[i].Hold = balance.Balance
} else {
currencyDetails[i].TotalValue = balance.Balance
}
updated = true
}
}
if updated {
continue
}
if frozen {
currencyDetails = append(currencyDetails,
exchange.AccountCurrencyInfo{
CurrencyName: balance.Currency,
Hold: balance.Balance,
})
} else {
currencyDetails = append(currencyDetails,
exchange.AccountCurrencyInfo{
CurrencyName: balance.Currency,
TotalValue: balance.Balance,
})
}
}
acc.Currencies = currencyDetails
info.Accounts = append(info.Accounts, acc)
}
var balances []exchange.AccountCurrencyInfo
for key, data := range currencyData {
balances = append(balances, exchange.AccountCurrencyInfo{
CurrencyName: key,
TotalValue: data.Avail + data.Hold,
Hold: data.Hold,
})
}
info.Currencies = balances
return info, nil
}
@@ -295,8 +302,8 @@ func (h *HUOBIHADAX) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (h *HUOBIHADAX) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (h *HUOBIHADAX) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrFunctionNotSupported
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -406,3 +406,10 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
_, err := i.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}

View File

@@ -111,7 +111,7 @@ func (i *ItBit) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderboo
// GetAccountInfo retrieves balances for all enabled currencies
func (i *ItBit) GetAccountInfo() (exchange.AccountInfo, error) {
var info exchange.AccountInfo
info.ExchangeName = i.GetName()
info.Exchange = i.GetName()
wallets, err := i.GetWallets(url.Values{})
if err != nil {
@@ -146,6 +146,10 @@ func (i *ItBit) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: fullBalance,
})
return info, nil
}
@@ -237,7 +241,10 @@ func (i *ItBit) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (i *ItBit) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
// NOTE: This has not been implemented due to the fact you need to generate a
// a specific wallet ID and they restrict the amount of deposit address you can
// request limiting them to 2.
func (i *ItBit) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrNotYetImplemented
}

View File

@@ -1,6 +1,7 @@
package kraken
import (
"errors"
"fmt"
"net/url"
"strconv"
@@ -16,32 +17,33 @@ import (
)
const (
krakenAPIURL = "https://api.kraken.com"
krakenAPIVersion = "0"
krakenServerTime = "Time"
krakenAssets = "Assets"
krakenAssetPairs = "AssetPairs"
krakenTicker = "Ticker"
krakenOHLC = "OHLC"
krakenDepth = "Depth"
krakenTrades = "Trades"
krakenSpread = "Spread"
krakenBalance = "Balance"
krakenTradeBalance = "TradeBalance"
krakenOpenOrders = "OpenOrders"
krakenClosedOrders = "ClosedOrders"
krakenQueryOrders = "QueryOrders"
krakenTradeHistory = "TradesHistory"
krakenQueryTrades = "QueryTrades"
krakenOpenPositions = "OpenPositions"
krakenLedgers = "Ledgers"
krakenQueryLedgers = "QueryLedgers"
krakenTradeVolume = "TradeVolume"
krakenOrderCancel = "CancelOrder"
krakenOrderPlace = "AddOrder"
krakenWithdrawInfo = "WithdrawInfo"
krakenWithdraw = "Withdraw"
krakenDepositMethods = "DepositMethods"
krakenAPIURL = "https://api.kraken.com"
krakenAPIVersion = "0"
krakenServerTime = "Time"
krakenAssets = "Assets"
krakenAssetPairs = "AssetPairs"
krakenTicker = "Ticker"
krakenOHLC = "OHLC"
krakenDepth = "Depth"
krakenTrades = "Trades"
krakenSpread = "Spread"
krakenBalance = "Balance"
krakenTradeBalance = "TradeBalance"
krakenOpenOrders = "OpenOrders"
krakenClosedOrders = "ClosedOrders"
krakenQueryOrders = "QueryOrders"
krakenTradeHistory = "TradesHistory"
krakenQueryTrades = "QueryTrades"
krakenOpenPositions = "OpenPositions"
krakenLedgers = "Ledgers"
krakenQueryLedgers = "QueryLedgers"
krakenTradeVolume = "TradeVolume"
krakenOrderCancel = "CancelOrder"
krakenOrderPlace = "AddOrder"
krakenWithdrawInfo = "WithdrawInfo"
krakenWithdraw = "Withdraw"
krakenDepositMethods = "DepositMethods"
krakenDepositAddresses = "DepositAddresses"
krakenAuthRate = 0
krakenUnauthRate = 0
@@ -495,9 +497,10 @@ func (k *Kraken) GetDepositMethods(currency string) ([]DepositMethods, error) {
Result []DepositMethods `json:"result"`
}
params := url.Values{}
params.Set("asset ", currency)
params.Set("asset", currency)
if err := k.SendAuthenticatedHTTPRequest(krakenDepositMethods, params, &response); err != nil {
err := k.SendAuthenticatedHTTPRequest(krakenDepositMethods, params, &response)
if err != nil {
return response.Result, err
}
@@ -998,3 +1001,26 @@ func getCryptocurrencyDepositFee(currency string) float64 {
func calculateTradingFee(currency string, feePair map[string]TradeVolumeFee, purchasePrice, amount float64) float64 {
return (feePair[currency].Fee / 100) * purchasePrice * amount
}
// GetCryptoDepositAddress returns a deposit address for a cryptocurrency
func (k *Kraken) GetCryptoDepositAddress(method, code string) (string, error) {
var resp = struct {
Error []string `json:"error"`
Result []DepositAddress `json:"result"`
}{}
values := url.Values{}
values.Set("asset", code)
values.Set("method", method)
err := k.SendAuthenticatedHTTPRequest(krakenDepositAddresses, values, &resp)
if err != nil {
return "", err
}
for _, a := range resp.Result {
return a.Address, nil
}
return "", errors.New("no addresses returned")
}

View File

@@ -241,7 +241,7 @@ func TestGetFee(t *testing.T) {
TestSetup(t)
var feeBuilder = setFeeBuilder()
if apiKey != "" && apiSecret != "" {
if areTestAPIKeysSet() {
// CryptocurrencyTradeFee Basic
if resp, err := k.GetFee(feeBuilder); resp != float64(0.0026) || err != nil {
t.Error(err)
@@ -519,3 +519,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Withdraw failed to be placed: %v", err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := k.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := k.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error can not be nil")
}
}
}

View File

@@ -299,10 +299,10 @@ type WithdrawInformation struct {
// DepositMethods Used to check deposit fees
type DepositMethods struct {
Method string `json:"method"`
Limit float64 `json:"limit,string"`
Fee float64 `json:"fee,string"`
AddressSetupFee float64 `json:"address-setup-fee,string"`
Method string `json:"method"`
Limit interface{} `json:"limit"` // If no limit amount, this comes back as boolean
Fee float64 `json:"fee,string"`
AddressSetupFee float64 `json:"address-setup-fee,string"`
}
// OrderDescription represents an orders description
@@ -365,3 +365,10 @@ var WithdrawalFees = map[string]float64{
symbol.XTZ: 0.05,
symbol.ZEC: 0.0001,
}
// DepositAddress defines a deposit address
type DepositAddress struct {
Address string `json:"address"`
ExpireTime int64 `json:"expiretm,string"`
New bool `json:"new"`
}

View File

@@ -1,6 +1,7 @@
package kraken
import (
"errors"
"strings"
"sync"
@@ -142,7 +143,7 @@ func (k *Kraken) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbo
// Kraken exchange - to-do
func (k *Kraken) GetAccountInfo() (exchange.AccountInfo, error) {
var info exchange.AccountInfo
info.ExchangeName = k.GetName()
info.Exchange = k.GetName()
bal, err := k.GetBalance()
if err != nil {
@@ -157,7 +158,10 @@ func (k *Kraken) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.Currencies = balances
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: balances,
})
return info, nil
}
@@ -236,8 +240,22 @@ func (k *Kraken) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (k *Kraken) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (k *Kraken) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
methods, err := k.GetDepositMethods(cryptocurrency.String())
if err != nil {
return "", err
}
var method string
for _, m := range methods {
method = m.Method
}
if method == "" {
return "", errors.New("method not found")
}
return k.GetCryptoDepositAddress(method, cryptocurrency.String())
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal

View File

@@ -394,3 +394,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := l.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := l.GetDepositAddress(symbol.DASH, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"github.com/thrasher-/gocryptotrader/common"
@@ -106,12 +107,13 @@ func (l *LakeBTC) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderb
// LakeBTC exchange
func (l *LakeBTC) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = l.GetName()
response.Exchange = l.GetName()
accountInfo, err := l.GetAccountInformation()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for x, y := range accountInfo.Balance {
for z, w := range accountInfo.Locked {
if z == x {
@@ -119,10 +121,15 @@ func (l *LakeBTC) GetAccountInfo() (exchange.AccountInfo, error) {
exchangeCurrency.CurrencyName = common.StringToUpper(x)
exchangeCurrency.TotalValue, _ = strconv.ParseFloat(y, 64)
exchangeCurrency.Hold, _ = strconv.ParseFloat(w, 64)
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
}
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -201,8 +208,18 @@ func (l *LakeBTC) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (l *LakeBTC) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (l *LakeBTC) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
if !strings.EqualFold(cryptocurrency.String(), symbol.BTC) {
return "", fmt.Errorf("unsupported currency %s deposit address can only be BTC, manual deposit is required for other currencies",
cryptocurrency.String())
}
info, err := l.GetAccountInformation()
if err != nil {
return "", err
}
return info.Profile.BTCDepositAddress, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -117,20 +117,25 @@ func (l *Liqui) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderboo
// Liqui exchange
func (l *Liqui) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = l.GetName()
response.Exchange = l.GetName()
accountBalance, err := l.GetAccountInformation()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for x, y := range accountBalance.Funds {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = common.StringToUpper(x)
exchangeCurrency.TotalValue = y
exchangeCurrency.Hold = 0
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -214,8 +219,8 @@ func (l *Liqui) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (l *Liqui) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (l *Liqui) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrFunctionNotSupported
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -355,3 +355,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if apiKey != "" || apiSecret != "" {
_, err := l.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := l.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
}
}
}

View File

@@ -5,8 +5,11 @@ import (
"fmt"
"math"
"strconv"
"strings"
"sync"
"github.com/thrasher-/gocryptotrader/currency/symbol"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
@@ -113,7 +116,7 @@ func (l *LocalBitcoins) UpdateOrderbook(p pair.CurrencyPair, assetType string) (
// LocalBitcoins exchange
func (l *LocalBitcoins) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = l.GetName()
response.Exchange = l.GetName()
accountBalance, err := l.GetWalletBalance()
if err != nil {
return response, err
@@ -122,7 +125,9 @@ func (l *LocalBitcoins) GetAccountInfo() (exchange.AccountInfo, error) {
exchangeCurrency.CurrencyName = "BTC"
exchangeCurrency.TotalValue = accountBalance.Total.Balance
response.Currencies = append(response.Currencies, exchangeCurrency)
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: []exchange.AccountCurrencyInfo{exchangeCurrency},
})
return response, nil
}
@@ -246,8 +251,13 @@ func (l *LocalBitcoins) GetOrderInfo(orderID int64) (exchange.OrderDetail, error
}
// GetDepositAddress returns a deposit address for a specified currency
func (l *LocalBitcoins) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (l *LocalBitcoins) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
if !strings.EqualFold(symbol.BTC, cryptocurrency.String()) {
return "", fmt.Errorf("Localbitcoins do not have support for currency %s just bitcoin",
cryptocurrency.String())
}
return l.GetWalletAddress()
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -145,36 +145,42 @@ func (o *OKCoin) UpdateOrderbook(currency pair.CurrencyPair, assetType string) (
// OKCoin exchange
func (o *OKCoin) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = o.GetName()
response.Exchange = o.GetName()
assets, err := o.GetUserInfo()
if err != nil {
return response, err
}
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
var currencies []exchange.AccountCurrencyInfo
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "BTC",
TotalValue: assets.Info.Funds.Free.BTC,
Hold: assets.Info.Funds.Freezed.BTC,
})
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "LTC",
TotalValue: assets.Info.Funds.Free.LTC,
Hold: assets.Info.Funds.Freezed.LTC,
})
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "USD",
TotalValue: assets.Info.Funds.Free.USD,
Hold: assets.Info.Funds.Freezed.USD,
})
response.Currencies = append(response.Currencies, exchange.AccountCurrencyInfo{
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: "CNY",
TotalValue: assets.Info.Funds.Free.CNY,
Hold: assets.Info.Funds.Freezed.CNY,
})
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -285,7 +291,8 @@ func (o *OKCoin) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (o *OKCoin) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
func (o *OKCoin) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
// NOTE needs API version update to access
return "", common.ErrNotYetImplemented
}

View File

@@ -167,8 +167,11 @@ func (o *OKEX) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.ExchangeName = o.GetName()
info.Currencies = balances
info.Exchange = o.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: balances,
})
return info, nil
}
@@ -283,7 +286,8 @@ func (o *OKEX) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (o *OKEX) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
func (o *OKEX) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
// NOTE needs API version update to access
return "", common.ErrNotYetImplemented
}

View File

@@ -107,7 +107,7 @@ func TestGetFee(t *testing.T) {
TestSetup(t)
var feeBuilder = setFeeBuilder()
if apiKey != "" && apiSecret != "" {
if areTestAPIKeysSet() {
// CryptocurrencyTradeFee Basic
if resp, err := p.GetFee(feeBuilder); resp != float64(0.002) || err != nil {
t.Error(err)
@@ -350,3 +350,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() {
_, err := p.GetDepositAddress(symbol.DASH, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress()", err)
}
} else {
_, err := p.GetDepositAddress(symbol.DASH, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress()")
}
}
}

View File

@@ -126,18 +126,24 @@ func (p *Poloniex) UpdateOrderbook(currencyPair pair.CurrencyPair, assetType str
// Poloniex exchange
func (p *Poloniex) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = p.GetName()
response.Exchange = p.GetName()
accountBalance, err := p.GetBalances()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for x, y := range accountBalance.Currency {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = x
exchangeCurrency.TotalValue = y
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -235,8 +241,19 @@ func (p *Poloniex) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (p *Poloniex) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (p *Poloniex) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
a, err := p.GetDepositAddresses()
if err != nil {
return "", err
}
address, ok := a.Addresses[cryptocurrency.Upper().String()]
if !ok {
return "", fmt.Errorf("Cannot find deposit address for %s",
cryptocurrency)
}
return address, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -127,20 +127,25 @@ func (w *WEX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.
// WEX exchange
func (w *WEX) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = w.GetName()
response.Exchange = w.GetName()
accountBalance, err := w.GetAccountInformation()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for x, y := range accountBalance.Funds {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = common.StringToUpper(x)
exchangeCurrency.TotalValue = y
exchangeCurrency.Hold = 0
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -232,7 +237,7 @@ func (w *WEX) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (w *WEX) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
func (w *WEX) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrNotYetImplemented
}

View File

@@ -258,8 +258,8 @@ func (y *Yobit) GetCryptoDepositAddress(coin string) (DepositAddress, error) {
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
if result.Success != 1 {
return result, fmt.Errorf("%s", result.Error)
}
return result, nil
}

View File

@@ -125,14 +125,6 @@ func TestWithdrawCoinsToAddress(t *testing.T) {
}
}
func TestGetDepositAddress(t *testing.T) {
t.Parallel()
_, err := y.GetDepositAddress("btc")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
}
func TestCreateYobicode(t *testing.T) {
t.Parallel()
_, err := y.CreateCoupon("bla", 0)
@@ -469,3 +461,17 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if apiKey != "" || apiSecret != "" {
_, err := y.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error", err)
}
} else {
_, err := y.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error")
}
}
}

View File

@@ -118,10 +118,13 @@ type TradeHistory struct {
// DepositAddress stores a curency deposit address
type DepositAddress struct {
Address string `json:"address"`
ProcessedAmount float64 `json:"processed_amount"`
ServerTime int64 `json:"server_time"`
Error string `json:"error"`
Success int `json:"success"`
Return struct {
Address string `json:"address"`
ProcessedAmount float64 `json:"processed_amount"`
ServerTime int64 `json:"server_time"`
} `json:"return"`
Error string `json:"error"`
}
// WithdrawCoinsToAddress stores information for a withdrawcoins request

View File

@@ -104,12 +104,13 @@ func (y *Yobit) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderboo
// Yobit exchange
func (y *Yobit) GetAccountInfo() (exchange.AccountInfo, error) {
var response exchange.AccountInfo
response.ExchangeName = y.GetName()
response.Exchange = y.GetName()
accountBalance, err := y.GetAccountInformation()
if err != nil {
return response, err
}
var currencies []exchange.AccountCurrencyInfo
for x, y := range accountBalance.FundsInclOrders {
var exchangeCurrency exchange.AccountCurrencyInfo
exchangeCurrency.CurrencyName = common.StringToUpper(x)
@@ -121,9 +122,13 @@ func (y *Yobit) GetAccountInfo() (exchange.AccountInfo, error) {
}
}
response.Currencies = append(response.Currencies, exchangeCurrency)
currencies = append(currencies, exchangeCurrency)
}
response.Accounts = append(response.Accounts, exchange.Account{
Currencies: currencies,
})
return response, nil
}
@@ -214,8 +219,13 @@ func (y *Yobit) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (y *Yobit) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (y *Yobit) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
a, err := y.GetCryptoDepositAddress(cryptocurrency.String())
if err != nil {
return "", err
}
return a.Return.Address, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -11,6 +11,7 @@ import (
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
@@ -32,6 +33,7 @@ const (
zbDepth = "depth"
zbUnfinishedOrdersIgnoreTradeType = "getUnfinishedOrdersIgnoreTradeType"
zbWithdraw = "withdraw"
zbDepositAddress = "getUserAddress"
zbAuthRate = 100
zbUnauthRate = 100
@@ -122,7 +124,7 @@ func (z *ZB) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) {
vals.Set("price", strconv.FormatFloat(arg.Price, 'f', -1, 64))
vals.Set("tradeType", string(arg.Type))
err := z.SendAuthenticatedHTTPRequest("GET", zbOrder, vals, &result)
err := z.SendAuthenticatedHTTPRequest("GET", vals, &result)
if err != nil {
return 0, err
}
@@ -150,7 +152,7 @@ func (z *ZB) CancelExistingOrder(orderID int64, symbol string) error {
vals.Set("currency", symbol)
var result response
err := z.SendAuthenticatedHTTPRequest("GET", zbCancelOrder, vals, &result)
err := z.SendAuthenticatedHTTPRequest("GET", vals, &result)
if err != nil {
return err
}
@@ -170,7 +172,7 @@ func (z *ZB) GetAccountInformation() (AccountsResponse, error) {
vals.Set("accesskey", z.APIKey)
vals.Set("method", "getAccountInfo")
err := z.SendAuthenticatedHTTPRequest("GET", zbAccountInfo, vals, &result)
err := z.SendAuthenticatedHTTPRequest("GET", vals, &result)
if err != nil {
return result, err
}
@@ -187,7 +189,7 @@ func (z *ZB) GetUnfinishedOrdersIgnoreTradeType(currency, pageindex, pagesize st
vals.Set("pageIndex", pageindex)
vals.Set("pageSize", pagesize)
err := z.SendAuthenticatedHTTPRequest("GET", zbUnfinishedOrdersIgnoreTradeType, vals, &result)
err := z.SendAuthenticatedHTTPRequest("GET", vals, &result)
if err != nil {
return result, err
}
@@ -329,32 +331,45 @@ func (z *ZB) GetSpotKline(arg KlinesRequestParams) (KLineResponse, error) {
return res, nil
}
// GetCryptoAddress fetches and returns the deposit address
// NOTE - PLEASE BE AWARE THAT YOU NEED TO GENERATE A DEPOSIT ADDRESS VIA
// LOGGING IN AND NOT BY USING THIS ENDPOINT OTHERWISE THIS WILL GIVE YOU A
// GENERAL ERROR RESPONSE.
func (z *ZB) GetCryptoAddress(currency pair.CurrencyItem) (UserAddress, error) {
var resp UserAddress
vals := url.Values{}
vals.Set("method", zbDepositAddress)
vals.Set("currency", currency.Lower().String())
return resp,
z.SendAuthenticatedHTTPRequest("GET", vals, &resp)
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (z *ZB) SendHTTPRequest(path string, result interface{}) error {
return z.SendPayload("GET", path, nil, nil, result, false, z.Verbose)
}
// SendAuthenticatedHTTPRequest sends authenticated requests to the zb API
func (z *ZB) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, result interface{}) error {
func (z *ZB) SendAuthenticatedHTTPRequest(httpMethod string, params url.Values, result interface{}) error {
if !z.AuthenticatedAPISupport {
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, z.Name)
}
mapParams2Sign := url.Values{}
mapParams2Sign.Set("accesskey", z.APIKey)
mapParams2Sign.Set("method", values.Get("method"))
params.Set("accesskey", z.APIKey)
values.Set("sign",
common.HexEncodeToString(common.GetHMAC(common.HashMD5,
[]byte(values.Encode()),
[]byte(common.Sha1ToHex(z.APISecret)))))
hmac := common.GetHMAC(common.HashMD5,
[]byte(params.Encode()),
[]byte(common.Sha1ToHex(z.APISecret)))
values.Set("reqTime", fmt.Sprintf("%d", time.Now().UnixNano()/1e6))
params.Set("reqTime", fmt.Sprintf("%d", common.UnixMillis(time.Now())))
params.Set("sign", fmt.Sprintf("%x", hmac))
url := fmt.Sprintf("%s/%s?%s",
z.APIUrlSecondaryDefault,
endpoint,
values.Encode())
z.APIUrlSecondary,
params.Get("method"),
params.Encode())
var intermediary json.RawMessage
@@ -363,7 +378,7 @@ func (z *ZB) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Va
Message string `json:"message"`
}{}
err := z.SendPayload(method,
err := z.SendPayload(httpMethod,
url,
nil,
strings.NewReader(""),
@@ -461,7 +476,7 @@ func (z *ZB) Withdraw(currency, address, safepassword string, amount, fees float
vals.Set("safePwd", safepassword)
var resp response
err := z.SendAuthenticatedHTTPRequest("GET", zbWithdraw, vals, &resp)
err := z.SendAuthenticatedHTTPRequest("GET", vals, &resp)
if err != nil {
return "", err
}

View File

@@ -401,3 +401,18 @@ func TestWithdrawInternationalBank(t *testing.T) {
t.Errorf("Expected '%v', recieved: '%v'", common.ErrFunctionNotSupported, err)
}
}
func TestGetDepositAddress(t *testing.T) {
if apiKey != "" || apiSecret != "" {
_, err := z.GetDepositAddress(symbol.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress() error PLEASE MAKE SURE YOU CREATE DEPOSIT ADDRESSES VIA ZB.COM",
err)
}
} else {
_, err := z.GetDepositAddress(symbol.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error")
}
}
}

View File

@@ -130,6 +130,18 @@ type KLineResponse struct {
Data []*KLineResponseData `json:"data"` // KLine数据
}
// UserAddress defines Users Address for depositing funds
type UserAddress struct {
Code int64 `json:"code"`
Message struct {
Description string `json:"des"`
IsSuccessful bool `json:"isSuc"`
Data struct {
Key string `json:"key"`
} `json:"datas"`
} `json:"message"`
}
// TimeInterval represents interval enum.
type TimeInterval string

View File

@@ -143,8 +143,11 @@ func (z *ZB) GetAccountInfo() (exchange.AccountInfo, error) {
})
}
info.ExchangeName = z.GetName()
info.Currencies = balances
info.Exchange = z.GetName()
info.Accounts = append(info.Accounts, exchange.Account{
Currencies: balances,
})
return info, nil
}
@@ -243,8 +246,13 @@ func (z *ZB) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
// GetDepositAddress returns a deposit address for a specified currency
func (z *ZB) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
return "", common.ErrNotYetImplemented
func (z *ZB) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
address, err := z.GetCryptoAddress(cryptocurrency)
if err != nil {
return "", err
}
return address.Message.Data.Key, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is

View File

@@ -262,22 +262,24 @@ func GetSpecificTicker(currency, exchangeName, assetType string) (ticker.Price,
// GetCollatedExchangeAccountInfoByCoin collates individual exchange account
// information and turns into into a map string of
// exchange.AccountCurrencyInfo
func GetCollatedExchangeAccountInfoByCoin(accounts []exchange.AccountInfo) map[string]exchange.AccountCurrencyInfo {
func GetCollatedExchangeAccountInfoByCoin(exchAccounts []exchange.AccountInfo) map[string]exchange.AccountCurrencyInfo {
result := make(map[string]exchange.AccountCurrencyInfo)
for i := 0; i < len(accounts); i++ {
for j := 0; j < len(accounts[i].Currencies); j++ {
currencyName := accounts[i].Currencies[j].CurrencyName
avail := accounts[i].Currencies[j].TotalValue
onHold := accounts[i].Currencies[j].Hold
for _, accounts := range exchAccounts {
for _, account := range accounts.Accounts {
for _, accountCurrencyInfo := range account.Currencies {
currencyName := accountCurrencyInfo.CurrencyName
avail := accountCurrencyInfo.TotalValue
onHold := accountCurrencyInfo.Hold
info, ok := result[currencyName]
if !ok {
accountInfo := exchange.AccountCurrencyInfo{CurrencyName: currencyName, Hold: onHold, TotalValue: avail}
result[currencyName] = accountInfo
} else {
info.Hold += onHold
info.TotalValue += avail
result[currencyName] = info
info, ok := result[currencyName]
if !ok {
accountInfo := exchange.AccountCurrencyInfo{CurrencyName: currencyName, Hold: onHold, TotalValue: avail}
result[currencyName] = accountInfo
} else {
info.Hold += onHold
info.TotalValue += avail
result[currencyName] = info
}
}
}
}
@@ -287,7 +289,7 @@ func GetCollatedExchangeAccountInfoByCoin(accounts []exchange.AccountInfo) map[s
// 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].ExchangeName == exchangeName {
if accounts[i].Exchange == exchangeName {
return accounts[i], nil
}
}
@@ -324,39 +326,81 @@ func SeedExchangeAccountInfo(data []exchange.AccountInfo) {
port := portfolio.GetPortfolio()
for i := 0; i < len(data); i++ {
exchangeName := data[i].ExchangeName
for j := 0; j < len(data[i].Currencies); j++ {
currencyName := data[i].Currencies[j].CurrencyName
onHold := data[i].Currencies[j].Hold
avail := data[i].Currencies[j].TotalValue
total := onHold + avail
for _, exchangeData := range data {
exchangeName := exchangeData.Exchange
var currencies []exchange.AccountCurrencyInfo
for _, account := range exchangeData.Accounts {
for _, info := range account.Currencies {
var update bool
for i := range currencies {
if info.CurrencyName == currencies[i].CurrencyName {
currencies[i].Hold += info.Hold
currencies[i].TotalValue += info.TotalValue
update = true
}
}
if update {
continue
}
currencies = append(currencies, exchange.AccountCurrencyInfo{
CurrencyName: info.CurrencyName,
TotalValue: info.TotalValue,
Hold: info.Hold,
})
}
}
for _, total := range currencies {
currencyName := total.CurrencyName
total := total.TotalValue
if !port.ExchangeAddressExists(exchangeName, currencyName) {
if total <= 0 {
continue
}
log.Debugf("Portfolio: Adding new exchange address: %s, %s, %f, %s\n",
exchangeName, currencyName, total, portfolio.PortfolioAddressExchange)
exchangeName,
currencyName,
total,
portfolio.PortfolioAddressExchange)
port.Addresses = append(
port.Addresses,
portfolio.Address{Address: exchangeName, CoinType: currencyName,
Balance: total, Description: portfolio.PortfolioAddressExchange},
)
portfolio.Address{Address: exchangeName,
CoinType: currencyName,
Balance: total,
Description: portfolio.PortfolioAddressExchange})
} else {
if total <= 0 {
log.Debugf("Portfolio: Removing %s %s entry.\n", exchangeName,
log.Debugf("Portfolio: Removing %s %s entry.\n",
exchangeName,
currencyName)
port.RemoveExchangeAddress(exchangeName, currencyName)
} else {
balance, ok := port.GetAddressBalance(exchangeName, currencyName, portfolio.PortfolioAddressExchange)
balance, ok := port.GetAddressBalance(exchangeName,
currencyName,
portfolio.PortfolioAddressExchange)
if !ok {
continue
}
if balance != total {
log.Debugf("Portfolio: Updating %s %s entry with balance %f.\n",
exchangeName, currencyName, total)
port.UpdateExchangeAddressBalance(exchangeName, currencyName, total)
exchangeName,
currencyName,
total)
port.UpdateExchangeAddressBalance(exchangeName,
currencyName,
total)
}
}
}

View File

@@ -282,13 +282,32 @@ func TestGetCollatedExchangeAccountInfoByCoin(t *testing.T) {
exchangeInfo := []exchange.AccountInfo{}
var info exchange.AccountInfo
info.ExchangeName = "Bitfinex"
info.Currencies = append(info.Currencies,
exchange.AccountCurrencyInfo{CurrencyName: "BTC", TotalValue: 100, Hold: 0})
info.Exchange = "Bitfinex"
info.Accounts = append(info.Accounts,
exchange.Account{
Currencies: []exchange.AccountCurrencyInfo{
{
CurrencyName: "BTC",
TotalValue: 100,
Hold: 0,
},
},
})
exchangeInfo = append(exchangeInfo, info)
info.ExchangeName = "Bitstamp"
info.Currencies = append(info.Currencies, exchange.AccountCurrencyInfo{CurrencyName: "LTC", TotalValue: 100, Hold: 0})
info.Exchange = "Bitstamp"
info.Accounts = append(info.Accounts,
exchange.Account{
Currencies: []exchange.AccountCurrencyInfo{
{
CurrencyName: "LTC",
TotalValue: 100,
Hold: 0,
},
},
})
exchangeInfo = append(exchangeInfo, info)
result := GetCollatedExchangeAccountInfoByCoin(exchangeInfo)
@@ -316,9 +335,18 @@ func TestGetAccountCurrencyInfoByExchangeName(t *testing.T) {
exchangeInfo := []exchange.AccountInfo{}
var info exchange.AccountInfo
info.ExchangeName = "Bitfinex"
info.Currencies = append(info.Currencies,
exchange.AccountCurrencyInfo{CurrencyName: "BTC", TotalValue: 100, Hold: 0})
info.Exchange = "Bitfinex"
info.Accounts = append(info.Accounts,
exchange.Account{
Currencies: []exchange.AccountCurrencyInfo{
{
CurrencyName: "BTC",
TotalValue: 100,
Hold: 0,
},
},
})
exchangeInfo = append(exchangeInfo, info)
result, err := GetAccountCurrencyInfoByExchangeName(exchangeInfo, "Bitfinex")
@@ -326,7 +354,7 @@ func TestGetAccountCurrencyInfoByExchangeName(t *testing.T) {
t.Fatal(err)
}
if result.ExchangeName != "Bitfinex" {
if result.Exchange != "Bitfinex" {
t.Fatal("Unexepcted result")
}

View File

@@ -148,7 +148,7 @@ func ({{.Variable}} *{{.CapitalName}}) GetOrderInfo(orderID int64) (exchange.Ord
}
// GetDepositAddress returns a deposit address for a specified currency
func ({{.Variable}} *{{.CapitalName}}) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) {
func ({{.Variable}} *{{.CapitalName}}) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
return "", common.ErrNotYetImplemented
}