From 3bbfdbb4d2c3e6022c145c04c63581dfe236adb4 Mon Sep 17 00:00:00 2001 From: Tanguy Herbron Date: Tue, 27 Feb 2018 19:52:33 +0100 Subject: [PATCH] Binance implementation | Exchange code cleanup --- .../coinfolio/Activities/HomeActivity.java | 7 - .../DataManagers/BalanceManager.java | 220 +++++++----------- .../CurrencyData/CurrencyDataRetriever.java | 2 +- .../ExchangeManager/BinanceManager.java | 76 ++++++ .../ExchangeManager/HitBtcManager.java | 131 +++++++++++ app/src/main/res/xml/pref_exchange.xml | 18 +- 6 files changed, 307 insertions(+), 147 deletions(-) create mode 100644 app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java create mode 100644 app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/HitBtcManager.java diff --git a/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java index 0d9d451..054b32d 100644 --- a/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java +++ b/app/src/main/java/com/nauk/coinfolio/Activities/HomeActivity.java @@ -720,12 +720,6 @@ public class HomeActivity extends AppCompatActivity { @Override public void onSuccess(Currency currency) { countCoins(true, false); - /*currency.updateName(getApplicationContext(), new Currency.CurrencyCallBack() { - @Override - public void onSuccess(Currency currency) { - countCoins(true, false); - } - });*/ } }); } @@ -750,7 +744,6 @@ public class HomeActivity extends AppCompatActivity { default: updateAll(true); } - //updateAll(); } }); diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java index a05faaa..5c05f78 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/BalanceManager.java @@ -17,6 +17,8 @@ import com.binance.api.client.BinanceApiRestClient; import com.binance.api.client.domain.account.Account; import com.binance.api.client.domain.account.AssetBalance; import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; +import com.nauk.coinfolio.DataManagers.ExchangeManager.BinanceManager; +import com.nauk.coinfolio.DataManagers.ExchangeManager.HitBtcManager; import com.nauk.coinfolio.R; import org.json.JSONArray; @@ -56,17 +58,26 @@ public class BalanceManager { private PreferencesManager preferenceManager; private DatabaseManager databaseManager; - private BinanceApiClientFactory binanceApiClientFactory; + private int balanceCounter; + + //NEW IMPLEMENTATION + private List hitBtcManagers; + private List binanceManagers; public BalanceManager(android.content.Context context) { this.context = context; + preferenceManager = new PreferencesManager(context); requestQueue = Volley.newRequestQueue(context); binanceBalance = new ArrayList(); hitBalance = new ArrayList(); manualBalances = new ArrayList(); databaseManager = new DatabaseManager(context); + hitBtcManagers = new ArrayList<>(); + binanceManagers = new ArrayList<>(); + + balanceCounter = 0; } public List getCurrenciesName() @@ -128,45 +139,25 @@ public class BalanceManager { public void updateExchangeKeys() { - publicHitKey = preferenceManager.getHitBTCPublicKey(); - privateHitKey = preferenceManager.getHitBTCPrivateKey(); + String publicKey = preferenceManager.getHitBTCPublicKey(); + String privateKey = preferenceManager.getHitBTCPrivateKey(); - publicBinanceKey = preferenceManager.getBinancePublicKey(); - privateBinanceKey = preferenceManager.getBinancePrivateKey(); - } + hitBtcManagers.clear(); - public boolean isBinanceConfigured() - { - boolean isConfigured = true; - - if(publicBinanceKey == null || privateBinanceKey == null) + if(publicKey != null && privateKey != null && preferenceManager.isHitBTCActivated()) { - isConfigured = false; + hitBtcManagers.add(new HitBtcManager(context, publicKey, privateKey)); } - return isConfigured; - } + publicKey = preferenceManager.getBinancePublicKey(); + privateKey = preferenceManager.getBinancePrivateKey(); - public boolean isHitBTCConfigured() - { - boolean isConfigured = true; + binanceManagers.clear(); - if(publicHitKey == null || privateHitKey == null) + if(publicKey != null && privateKey != null && preferenceManager.isBinanceActivated()) { - isConfigured = false; + binanceManagers.add(new BinanceManager(publicKey, privateKey)); } - - return isConfigured; - } - - public void setPublicHitKey(String newKey) - { - publicHitKey = newKey; - } - - public void setPrivateHitKey(String newKey) - { - privateHitKey = newKey; } public List getTotalBalance() @@ -174,38 +165,50 @@ public class BalanceManager { return totalBalance; } - public List getHitBalance() - { - return hitBalance; - } - - public List getManualBalances() - { - return manualBalances; - } - public void updateTotalBalance(final VolleyCallBack callBack) { boolean isUpdated = false; + manualBalances = databaseManager.getAllCurrencyFromManualCurrency(); - Log.d("coinfolio", "Updating balances " + (privateBinanceKey != null && publicBinanceKey != null && preferenceManager.isBinanceActivated())); - - if(privateHitKey != null && publicHitKey != null && preferenceManager.isHitBTCActivated()) + if(binanceManagers.size() > 0) { - updateHitBalance(callBack); isUpdated = true; - } - else - { - hitBalance = new ArrayList(); + + for(int i = 0; i < binanceManagers.size(); i++) + { + binanceManagers.get(i).updateBalance(new BinanceManager.BinanceCallBack() { + @Override + public void onSuccess() { + countBalances(callBack); + } + + @Override + public void onError(String error) { + + } + }); + } } - if(privateBinanceKey != null && publicBinanceKey != null && preferenceManager.isBinanceActivated()) + if(hitBtcManagers.size() > 0) { - Log.d("coinfolio", "Updating Binance"); - updateBinanceBalance(); isUpdated = true; + + for(int i = 0; i < hitBtcManagers.size(); i++) + { + hitBtcManagers.get(i).updateBalance(new HitBtcManager.HitBtcCallBack() { + @Override + public void onSuccess() { + countBalances(callBack); + } + + @Override + public void onError(String error) { + + } + }); + } } if(!isUpdated) @@ -214,89 +217,15 @@ public class BalanceManager { } } - private void updateBinanceBalance() + private void countBalances(VolleyCallBack callBack) { - Map accountBalanceCache; - BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(publicBinanceKey, privateBinanceKey); - BinanceApiRestClient client = factory.newRestClient(); + balanceCounter++; - Account account = client.getAccount(); - List assets = account.getBalances(); - - binanceBalance = new ArrayList(); - - for(int i = 0; i < assets.size(); i++) + if(balanceCounter == hitBtcManagers.size() + binanceManagers.size()) { - if(Double.parseDouble(assets.get(i).getFree()) > 0) - { - binanceBalance.add(new Currency(assets.get(i).getAsset(), assets.get(i).getFree())); - } - } + refreshAllBalances(callBack); - Log.d("coinfolio", "Binance size : " + binanceBalance.size()); - - for(int i = 0; i < binanceBalance.size(); i++) - { - Log.d("coinfolio", "Binance : " + binanceBalance.get(i).getSymbol() + " " + binanceBalance.get(i).getBalance()); - } - } - - private void updateHitBalance(final VolleyCallBack callBack) - { - JsonArrayRequest arrReq = new JsonArrayRequest(Request.Method.GET, hitBalanceUrl, - new Response.Listener() { - @Override - public void onResponse(JSONArray response) { - if (response.length() > 0) { - - parseHitBalance(response); - refreshAllBalances(callBack); - - } else { - //No balance - } - } - }, - new Response.ErrorListener() { - @Override - public void onErrorResponse(VolleyError error) { - Log.e(context.getResources().getString(R.string.debug_volley), "API Error : " + error.toString() + ":"); - callBack.onError(error.toString()); - } - } - ) { - @Override - public Map getHeaders()throws AuthFailureError { - Map headers = new HashMap<>(); - String credentials = publicHitKey + ":" + privateHitKey; - String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); - headers.put("Content-Type", "application/json"); - headers.put("Authorization", auth); - - return headers; - } - }; - - requestQueue.add(arrReq); - } - - private void parseHitBalance(JSONArray response) - { - hitBalance = new ArrayList<>(); - - for (int i = 0; i < response.length(); i++) - { - try { - JSONObject jsonObj = response.getJSONObject(i); - - if(Float.parseFloat(jsonObj.getString("available")) > 0) - { - hitBalance.add(new Currency(jsonObj.getString("currency"), Double.parseDouble(jsonObj.getString("available")))); - } - - } catch (JSONException e) { - Log.e(context.getResources().getString(R.string.debug_volley), "Invalid JSON Object"); - } + balanceCounter = 0; } } @@ -304,17 +233,34 @@ public class BalanceManager { { totalBalance = new ArrayList<>(); - totalBalance.addAll(hitBalance); + for(int i = 0; i < hitBtcManagers.size(); i++) + { + mergeBalanceTotal(hitBtcManagers.get(i).getBalance()); + } - for(int i = 0; i < manualBalances.size(); i++) + for(int i = 0; i < binanceManagers.size(); i++) + { + Log.d("coinfolio", "Merging binance " + i); + + mergeBalanceTotal(binanceManagers.get(i).getBalance()); + } + + mergeBalanceTotal(manualBalances); + + callBack.onSuccess(); + } + + private void mergeBalanceTotal(List balance) + { + for(int i = 0; i < balance.size(); i++) { boolean isIn = false; for(int j = 0; j < totalBalance.size(); j++) { - if(manualBalances.get(i).getSymbol().equals(totalBalance.get(j).getSymbol())) + if(balance.get(i).getSymbol().equals(totalBalance.get(j).getSymbol())) { - totalBalance.get(j).setBalance(totalBalance.get(j).getBalance() + manualBalances.get(i).getBalance()); + totalBalance.get(j).setBalance(totalBalance.get(j).getBalance() + balance.get(i).getBalance()); isIn = true; } @@ -322,11 +268,9 @@ public class BalanceManager { if(!isIn) { - totalBalance.add(manualBalances.get(i)); + totalBalance.add(balance.get(i)); } } - - callBack.onSuccess(); } public interface VolleyCallBack { diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java index feeab70..b7e59ab 100644 --- a/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/CurrencyData/CurrencyDataRetriever.java @@ -80,7 +80,7 @@ public class CurrencyDataRetriever { { List dataChart = new ArrayList<>(); - if(response.length() > 200) + if(response.length() > 250) { response = response.substring(response.indexOf("Data\":[{") + 7, response.lastIndexOf("}],\"TimeTo")); String[] tab = response.split(Pattern.quote("},{")); diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java new file mode 100644 index 0000000..8bf5f58 --- /dev/null +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/BinanceManager.java @@ -0,0 +1,76 @@ +package com.nauk.coinfolio.DataManagers.ExchangeManager; + +import android.util.Log; + +import com.android.volley.RequestQueue; +import com.binance.api.client.BinanceApiClientFactory; +import com.binance.api.client.BinanceApiRestClient; +import com.binance.api.client.domain.account.Account; +import com.binance.api.client.domain.account.AssetBalance; +import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by Guitoune on 26/02/2018. + */ + +public class BinanceManager { + + private String publicKey; + private String privateKey; + + private List balance; + + public BinanceManager(){} + + public BinanceManager(String publicKey, String privateKey) + { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public void updateBalance(BinanceCallBack callBack) + { + Map accountBalanceCache; + BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(publicKey, privateKey); + BinanceApiRestClient client = factory.newRestClient(); + + Account account = client.getAccount(); + List assets = account.getBalances(); + + balance = new ArrayList<>(); + + for(int i = 0; i < assets.size(); i++) + { + if(Double.parseDouble(assets.get(i).getFree()) > 0) + { + balance.add(new Currency(assets.get(i).getAsset(), Double.parseDouble(assets.get(i).getFree()))); + } + } + + callBack.onSuccess(); + } + + public void setPublicKey(String publicKey) + { + this.publicKey = publicKey; + } + + public void setPrivateKey(String privateKey) + { + this.privateKey = privateKey; + } + + public List getBalance() + { + return balance; + } + + public interface BinanceCallBack { + void onSuccess(); + void onError(String error); + } +} diff --git a/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/HitBtcManager.java b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/HitBtcManager.java new file mode 100644 index 0000000..43c7a91 --- /dev/null +++ b/app/src/main/java/com/nauk/coinfolio/DataManagers/ExchangeManager/HitBtcManager.java @@ -0,0 +1,131 @@ +package com.nauk.coinfolio.DataManagers.ExchangeManager; + +import android.util.Base64; +import android.util.Log; + +import com.android.volley.AuthFailureError; +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonArrayRequest; +import com.android.volley.toolbox.Volley; +import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; +import com.nauk.coinfolio.R; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by Guitoune on 26/02/2018. + */ + +public class HitBtcManager { + + private String publicKey; + private String privateKey; + final private String hitBalanceUrl = "https://api.hitbtc.com/api/2/trading/balance"; + private RequestQueue requestQueue; + + private List balance; + private android.content.Context context; + + public HitBtcManager(android.content.Context context) + { + this.context = context; + requestQueue = Volley.newRequestQueue(context); + } + + public HitBtcManager(android.content.Context context, String publicKey, String privateKey) + { + this.context = context; + requestQueue = Volley.newRequestQueue(context); + + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public void updateBalance(final HitBtcCallBack callBack) + { + JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.GET, hitBalanceUrl, + new Response.Listener() { + @Override + public void onResponse(JSONArray response) { + if (response.length() > 0) { + parseBalance(response); + } else { + //No balance + } + + callBack.onSuccess(); + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + Log.e(context.getResources().getString(R.string.debug), "API Error : " + error); + callBack.onError(error.toString()); + } + } + ) { + @Override + public Map getHeaders() throws AuthFailureError { + Map headers = new HashMap<>(); + String credentials = publicKey + ":" + privateKey; + String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); + headers.put("Content-Type", "application/json"); + headers.put("Authorization", auth); + + return headers; + } + }; + + requestQueue.add(arrayRequest); + } + + private void parseBalance(JSONArray response) + { + balance = new ArrayList<>(); + + for(int i = 0; i < response.length(); i++) + { + try { + JSONObject jsonObject = response.getJSONObject(i); + + if(Float.parseFloat(jsonObject.getString("available")) > 0) + { + balance.add(new Currency(jsonObject.getString("currency"), Double.parseDouble(jsonObject.getString("available")))); + } + + } catch (JSONException e) { + Log.e(context.getResources().getString(R.string.debug), "Invalid JSON Object"); + } + } + } + + public void setPublicKey(String publicKey) + { + this.publicKey = publicKey; + } + + private void setPrivateKey(String privateKey) + { + this.privateKey = privateKey; + } + + public List getBalance() + { + return balance; + } + + public interface HitBtcCallBack { + void onSuccess(); + void onError(String error); + } +} diff --git a/app/src/main/res/xml/pref_exchange.xml b/app/src/main/res/xml/pref_exchange.xml index 442d41b..0bd59ff 100644 --- a/app/src/main/res/xml/pref_exchange.xml +++ b/app/src/main/res/xml/pref_exchange.xml @@ -66,6 +66,22 @@ android:title="@string/pref_title_enable_synchronization_binance" /> + + + +