From 3ad9c3dfbe8f878a745ac05a50bfb06c903af61d Mon Sep 17 00:00:00 2001 From: Adrian Gallagher Date: Wed, 6 Sep 2017 15:36:06 +1000 Subject: [PATCH] Use cryptoID instead of blockr (currently down) --- portfolio/portfolio.go | 126 +++++++++--------------------------- portfolio/portfolio_test.go | 103 +++++++++++------------------ 2 files changed, 71 insertions(+), 158 deletions(-) diff --git a/portfolio/portfolio.go b/portfolio/portfolio.go index ddff2170..81f6eae4 100644 --- a/portfolio/portfolio.go +++ b/portfolio/portfolio.go @@ -10,9 +10,7 @@ import ( ) const ( - blockrAPIURL = "blockr.io/api" - blockrAPIVersion = "1" - blockrAddressBalance = "address/balance" + cryptoIDAPIURL = "https://chainz.cryptoid.info" etherchainAPIURL = "https://etherchain.org/api" etherchainAccountMultiple = "account/multiple" @@ -38,32 +36,6 @@ type Address struct { Description string } -// BlockrAddress holds JSON incoming and outgoing data for BLOCKR with address -// information -type BlockrAddress struct { - Address string `json:"address"` - Balance float64 `json:"balance"` - BalanceMultisig float64 `json:"balance_multisig"` -} - -// BlockrAddressBalanceSingle holds JSON incoming and outgoing data for BLOCKR -// with address balance information -type BlockrAddressBalanceSingle struct { - Status string `json:"status"` - Data BlockrAddress `json:"data"` - Code int `json:"code"` - Message string `json:"message"` -} - -// BlockrAddressBalanceMulti holds JSON incoming and outgoing data for BLOCKR -// with address balance information for multiple wallets -type BlockrAddressBalanceMulti struct { - Status string `json:"status"` - Data []BlockrAddress `json:"data"` - Code int `json:"code"` - Message string `json:"message"` -} - // EtherchainBalanceResponse holds JSON incoming and outgoing data for // Etherchain type EtherchainBalanceResponse struct { @@ -118,56 +90,21 @@ func GetEthereumBalance(address []string) (EtherchainBalanceResponse, error) { return result, nil } -// GetBlockrBalanceSingle queries Blockr for an address balance for either a -// LTC or a BTC single address -func GetBlockrBalanceSingle(address string, coinType string) (BlockrAddressBalanceSingle, error) { - valid, _ := common.IsValidCryptoAddress(address, coinType) - if !valid { - return BlockrAddressBalanceSingle{}, fmt.Errorf( - "Not a %s address", common.StringToUpper(coinType), - ) +// GetCryptoIDAddress queries CryptoID for an address balance for a +// specified cryptocurrency +func GetCryptoIDAddress(address string, coinType string) (float64, error) { + ok, err := common.IsValidCryptoAddress(address, coinType) + if !ok || err != nil { + return 0, errors.New("invalid address") } - url := fmt.Sprintf( - "https://%s.%s/v%s/%s/%s", common.StringToLower(coinType), blockrAPIURL, - blockrAPIVersion, blockrAddressBalance, address, - ) - result := BlockrAddressBalanceSingle{} - err := common.SendHTTPGetRequest(url, true, &result) + var result interface{} + url := fmt.Sprintf("%s/%s/api.dws?q=getbalance&a=%s", cryptoIDAPIURL, common.StringToLower(coinType), address) + err = common.SendHTTPGetRequest(url, true, &result) if err != nil { - return result, err + return 0, err } - if result.Status != "success" { - return result, errors.New(result.Message) - } - return result, nil -} - -// GetBlockrAddressMulti queries Blockr for an address balance for either a LTC -// or a BTC multiple addresses -func GetBlockrAddressMulti(addresses []string, coinType string) (BlockrAddressBalanceMulti, error) { - for _, add := range addresses { - valid, _ := common.IsValidCryptoAddress(add, coinType) - if !valid { - return BlockrAddressBalanceMulti{}, fmt.Errorf( - "Not a %s address", common.StringToUpper(coinType), - ) - } - } - addressesStr := common.JoinStrings(addresses, ",") - url := fmt.Sprintf( - "https://%s.%s/v%s/%s/%s", common.StringToLower(coinType), blockrAPIURL, - blockrAPIVersion, blockrAddressBalance, addressesStr, - ) - result := BlockrAddressBalanceMulti{} - err := common.SendHTTPGetRequest(url, true, &result) - if err != nil { - return result, err - } - if result.Status != "success" { - return result, errors.New(result.Message) - } - return result, nil + return result.(float64), nil } // GetAddressBalance acceses the portfolio base and returns the balance by passed @@ -213,6 +150,18 @@ func (p *Base) ExchangeAddressExists(exchangeName, coinType string) bool { return false } +// AddExchangeAddress adds an exchange address to the portfolio base +func (p *Base) AddExchangeAddress(exchangeName, coinType string, balance float64) { + if p.ExchangeAddressExists(exchangeName, coinType) { + p.UpdateExchangeAddressBalance(exchangeName, coinType, balance) + } else { + p.Addresses = append( + p.Addresses, Address{Address: exchangeName, CoinType: coinType, + Balance: balance, Description: PortfolioAddressExchange}, + ) + } +} + // UpdateAddressBalance updates the portfolio base balance func (p *Base) UpdateAddressBalance(address string, amount float64) { for x := range p.Addresses { @@ -244,6 +193,10 @@ func (p *Base) UpdateExchangeAddressBalance(exchangeName, coinType string, balan // AddAddress adds an address to the portfolio base func (p *Base) AddAddress(address, coinType, description string, balance float64) { + if description == PortfolioAddressExchange { + p.AddExchangeAddress(address, coinType, balance) + return + } if !p.AddressExists(address) { p.Addresses = append( p.Addresses, Address{Address: address, CoinType: coinType, @@ -286,22 +239,12 @@ func (p *Base) UpdatePortfolio(addresses []string, coinType string) bool { } return true } - if len(addresses) > 1 { - result, err := GetBlockrAddressMulti(addresses, coinType) + for x := range addresses { + result, err := GetCryptoIDAddress(addresses[x], coinType) if err != nil { return false } - for _, x := range result.Data { - p.AddAddress(x.Address, coinType, PortfolioAddressPersonal, x.Balance) - } - } else { - result, err := GetBlockrBalanceSingle(addresses[0], coinType) - if err != nil { - return false - } - p.AddAddress( - addresses[0], coinType, PortfolioAddressPersonal, result.Data.Balance, - ) + p.AddAddress(addresses[x], coinType, PortfolioAddressPersonal, result) } return true } @@ -413,12 +356,7 @@ func (p *Base) GetPortfolioSummary() Summary { y = y / common.WeiPerEther personalHoldings[x] = y } - balance, ok := totalCoins[x] - if !ok { - totalCoins[x] = y - } else { - totalCoins[x] = y + balance - } + totalCoins[x] = y } for x, y := range exchangeHoldings { diff --git a/portfolio/portfolio_test.go b/portfolio/portfolio_test.go index 3a966481..86e689a0 100644 --- a/portfolio/portfolio_test.go +++ b/portfolio/portfolio_test.go @@ -32,62 +32,11 @@ func TestGetEthereumBalance(t *testing.T) { } } -func TestGetBlockrBalanceSingle(t *testing.T) { - litecoinAddress := "LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL" - bitcoinAddress := "3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r" - nonsenseAddress := "DingDong" - ltc := "LtC" - btc := "bTc" - - response, err := GetBlockrBalanceSingle(litecoinAddress, ltc) +func TestGetCryptoIDBalance(t *testing.T) { + ltcAddress := "LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1" + _, err := GetCryptoIDAddress(ltcAddress, "ltc") if err != nil { - t.Errorf("Test Failed - Portfolio GetBlockrBalanceSingle() Error: %s", err) - } - response, err = GetBlockrBalanceSingle(litecoinAddress, btc) - if err == nil { - t.Errorf("Test Failed - Portfolio GetBlockrBalanceSingle() Error: %s", err) - } - response, err = GetBlockrBalanceSingle(bitcoinAddress, btc) - if err != nil { - t.Errorf("Test Failed - Portfolio GetBlockrBalanceSingle() Error: %s", err) - } - response, err = GetBlockrBalanceSingle(bitcoinAddress, ltc) - if err != nil { - t.Errorf("Test Failed - Portfolio GetBlockrBalanceSingle() Error: %s", err) - } - response, err = GetBlockrBalanceSingle(nonsenseAddress, ltc+btc) - if err == nil { - t.Errorf("Test Failed - Portfolio GetBlockrBalanceSingle() Error: %s", err) - } - if response.Status == "success" { - t.Error( - "Test Failed - Portfolio GetBlockrBalanceSingle() Error: Incorrect status", - ) - } -} - -func TestGetBlockrAddressMulti(t *testing.T) { - litecoinAddresses := []string{ - "LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "LVa8wZ983PvWtdwXZ8viK6SocMENLCXkEy", - } - bitcoinAddresses := []string{ - "3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r", "3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v", - } - nonsenseAddresses := []string{"DingDong", "ningNang"} - ltc := "LtC" - btc := "bTc" - - _, err := GetBlockrAddressMulti(litecoinAddresses, ltc) - if err != nil { - t.Errorf("Test Failed - Portfolio GetBlockrAddressMulti() Error: %s", err) - } - _, err = GetBlockrAddressMulti(bitcoinAddresses, btc) - if err != nil { - t.Errorf("Test Failed - Portfolio GetBlockrAddressMulti() Error: %s", err) - } - _, err = GetBlockrAddressMulti(nonsenseAddresses, ltc) - if err == nil { - t.Errorf("Test Failed - Portfolio GetBlockrAddressMulti() Error") + t.Fatalf("Test failed. TestGetCryptoIDBalance error: %s", err) } } @@ -148,6 +97,16 @@ func TestExchangeAddressExists(t *testing.T) { } +func TestAddExchangeAddress(t *testing.T) { + newbase := Base{} + newbase.AddExchangeAddress("ANX", "BTC", 100) + newbase.AddExchangeAddress("ANX", "BTC", 200) + + if !newbase.ExchangeAddressExists("ANX", "BTC") { + t.Error("Test Failed - TestExchangeAddressExists address doesn't exist") + } +} + func TestUpdateAddressBalance(t *testing.T) { newbase := Base{} newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) @@ -178,7 +137,7 @@ func TestRemoveExchangeAddress(t *testing.T) { exchangeName := "BallerExchange" coinType := "LTC" - newbase.AddAddress(exchangeName, coinType, PortfolioAddressExchange, 420) + newbase.AddExchangeAddress(exchangeName, coinType, 420) if !newbase.ExchangeAddressExists(exchangeName, coinType) { t.Error("Test failed - portfolio_test.go - TestRemoveAddress") @@ -192,7 +151,7 @@ func TestRemoveExchangeAddress(t *testing.T) { func TestUpdateExchangeAddressBalance(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) + newbase.AddExchangeAddress("someaddress", "LTC", 0.02) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) portfolio.UpdateExchangeAddressBalance("someaddress", "LTC", 0.04) @@ -273,8 +232,8 @@ func TestUpdatePortfolio(t *testing.T) { func TestGetPortfolioByExchange(t *testing.T) { newbase := Base{} - newbase.AddAddress("ANX", "LTC", PortfolioAddressExchange, 0.07) - newbase.AddAddress("Bitfinex", "LTC", PortfolioAddressExchange, 0.05) + newbase.AddExchangeAddress("ANX", "LTC", 0.07) + newbase.AddExchangeAddress("Bitfinex", "LTC", 0.05) newbase.AddAddress("someaddress", "LTC", PortfolioAddressPersonal, 0.03) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) @@ -340,15 +299,17 @@ func TestGetPortfolioSummary(t *testing.T) { newbase := Base{} // Personal holdings newbase.AddAddress("someaddress", "LTC", PortfolioAddressPersonal, 1) + newbase.AddAddress("someaddress2", "LTC", PortfolioAddressPersonal, 2) + newbase.AddAddress("someaddress3", "BTC", PortfolioAddressPersonal, 100) newbase.AddAddress("0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", "ETH", PortfolioAddressPersonal, 865346880000000000) newbase.AddAddress("0x9edc81c813b26165f607a8d1b8db87a02f34307f", "ETH", PortfolioAddressPersonal, 165346880000000000) // Exchange holdings - newbase.AddAddress("Bitfinex", "LTC", PortfolioAddressExchange, 20) - newbase.AddAddress("Bitfinex", "BTC", PortfolioAddressExchange, 100) - newbase.AddAddress("ANX", "ETH", PortfolioAddressExchange, 42) + newbase.AddExchangeAddress("Bitfinex", "LTC", 20) + newbase.AddExchangeAddress("Bitfinex", "BTC", 100) + newbase.AddExchangeAddress("ANX", "ETH", 42) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) @@ -371,7 +332,11 @@ func TestGetPortfolioSummary(t *testing.T) { t.Error("Test Failed - portfolio_test.go - TestGetPortfolioSummary error") } - if getTotalsVal("LTC").Balance != 101 { + if getTotalsVal("LTC").Balance != 23 { + t.Error("Test Failed - portfolio_test.go - TestGetPortfolioSummary error") + } + + if getTotalsVal("BTC").Balance != 200 { t.Error("Test Failed - portfolio_test.go - TestGetPortfolioSummary error") } } @@ -400,7 +365,17 @@ func TestSeedPortfolio(t *testing.T) { } func TestStartPortfolioWatcher(t *testing.T) { - //Not until testTimeoutFeature and errors + newBase := Base{} + newBase.AddAddress("LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1", "LTC", PortfolioAddressPersonal, 0.02) + newBase.AddAddress("Testy", "LTC", PortfolioAddressPersonal, 0.02) + portfolio := GetPortfolio() + portfolio.SeedPortfolio(newBase) + + if !portfolio.AddressExists("LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1") { + t.Error("Test Failed - portfolio_test.go - TestStartPortfolioWatcher") + } + + go StartPortfolioWatcher() } func TestGetPortfolio(t *testing.T) {