This commit is contained in:
Javier Varona 2018-03-11 22:54:46 -04:00
commit ab1157faad
7 changed files with 333 additions and 18 deletions

View file

@ -12,12 +12,14 @@ import cy.agorise.crystalwallet.dao.BitsharesAssetDao;
import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao; import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao;
import cy.agorise.crystalwallet.dao.CryptoCurrencyDao; import cy.agorise.crystalwallet.dao.CryptoCurrencyDao;
import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.BitsharesAsset; import cy.agorise.crystalwallet.models.BitsharesAsset;
import cy.agorise.crystalwallet.models.BitsharesAssetInfo; import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
import cy.agorise.crystalwallet.models.CryptoCoinBalance; import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction; import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCurrency; import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence; import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
import cy.agorise.crystalwallet.network.CryptoNetManager;
import cy.agorise.crystalwallet.network.WebSocketThread; import cy.agorise.crystalwallet.network.WebSocketThread;
import cy.agorise.graphenej.Address; import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.Asset; import cy.agorise.graphenej.Asset;
@ -58,12 +60,8 @@ public abstract class GrapheneApiGenerator {
//TODO network connections //TODO network connections
//TODO make to work with all Graphene type, not only bitshares //TODO make to work with all Graphene type, not only bitshares
public static String url = "http://185.208.208.147:11012";
public static String faucetUrl = "http://185.208.208.147:5010"; public static String faucetUrl = "http://185.208.208.147:5010";
private static String equivalentUrl = "http://185.208.208.147:8090"; private static String equivalentUrl = "wss://bitshares.openledger.info/ws";
//public static String url = "wss://bitshares.openledger.info/ws";
//private static Str ing equivalentUrl = "wss://bitshares.openledger.info/ws";
// The message broker for bitshares // The message broker for bitshares
private static SubscriptionMessagesHub bitsharesSubscriptionHub = new SubscriptionMessagesHub("", "", true, new NodeErrorListener() { private static SubscriptionMessagesHub bitsharesSubscriptionHub = new SubscriptionMessagesHub("", "", true, new NodeErrorListener() {
@ -77,7 +75,7 @@ public abstract class GrapheneApiGenerator {
/** /**
* The subscription thread for the real time updates * The subscription thread for the real time updates
*/ */
private static WebSocketThread subscriptionThread = new WebSocketThread(bitsharesSubscriptionHub,url); private static WebSocketThread subscriptionThread = new WebSocketThread(bitsharesSubscriptionHub, CryptoNetManager.getURL(CryptoNet.BITSHARES));
/** /**
* This is used for manager each listener in the subscription thread * This is used for manager each listener in the subscription thread
*/ */
@ -110,7 +108,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -138,7 +136,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -165,7 +163,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -192,7 +190,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -219,7 +217,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -243,7 +241,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -288,7 +286,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -336,7 +334,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -509,7 +507,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
@ -536,7 +534,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),url); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }

View file

@ -6,6 +6,8 @@ import android.content.Intent;
import com.idescout.sql.SqlScoutServer; import com.idescout.sql.SqlScoutServer;
import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.network.CryptoNetManager;
import cy.agorise.crystalwallet.service.CrystalWalletService; import cy.agorise.crystalwallet.service.CrystalWalletService;
/** /**
@ -15,6 +17,20 @@ import cy.agorise.crystalwallet.service.CrystalWalletService;
*/ */
public class CrystalApplication extends Application { public class CrystalApplication extends Application {
public static String BITSHARES_URL[] =
{
"wss://de.palmpay.io/ws", // Custom node
"wss://bitshares.nu/ws",
"wss://dexnode.net/ws", // Dallas, USA
"wss://bitshares.crypto.fans/ws", // Munich, Germany
"wss://bitshares.openledger.info/ws", // Openledger node
"ws://185.208.208.147:8090" // Custom node
};
public static String BITSHARES_TESTNET_URL[] =
{
"http://185.208.208.147:11012", // Openledger node
};
@Override @Override
public void onCreate() { public void onCreate() {
@ -24,6 +40,11 @@ public class CrystalApplication extends Application {
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.getApplicationContext()); CrystalDatabase db = CrystalDatabase.getAppDatabase(this.getApplicationContext());
SqlScoutServer.create(this, getPackageName()); SqlScoutServer.create(this, getPackageName());
//Using Bitshares Agorise Testnet
CryptoNetManager.addCryptoNetURL(CryptoNet.BITSHARES,BITSHARES_TESTNET_URL);
//Next line is for use the bitshares main net
//CryptoNetManager.addCryptoNetURL(CryptoNet.BITSHARES,BITSHARES_URL);
Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class); Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class);
startService(intent); startService(intent);
} }

View file

@ -36,6 +36,7 @@ import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount; import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount; import cy.agorise.crystalwallet.models.GrapheneAccount;
import cy.agorise.crystalwallet.models.GrapheneAccountInfo; import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
import cy.agorise.crystalwallet.network.CryptoNetManager;
import cy.agorise.graphenej.Address; import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.Asset; import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.AssetAmount; import cy.agorise.graphenej.AssetAmount;
@ -56,7 +57,7 @@ import cy.agorise.graphenej.operations.TransferOperationBuilder;
*/ */
public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener { public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
private final static String BITSHARES_TESTNET_CHAIN_ID= "9cf6f255a208100d2bb275a3c52f4b1589b7ec9c9bfc2cb2a5fe6411295106d8"; //private final static String BITSHARES_TESTNET_CHAIN_ID= "9cf6f255a208100d2bb275a3c52f4b1589b7ec9c9bfc2cb2a5fe6411295106d8";
private final static String SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; private final static String SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
private final static String DEFAULT_TIME_ZONE = "GMT"; private final static String DEFAULT_TIME_ZONE = "GMT";
@ -395,7 +396,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
ECKey privateKey = sendRequest.getSourceAccount().getActiveKey(sendRequest.getContext()); ECKey privateKey = sendRequest.getSourceAccount().getActiveKey(sendRequest.getContext());
Transaction transaction = new Transaction(privateKey, null, operationList); Transaction transaction = new Transaction(privateKey, null, operationList);
transaction.setChainId(BITSHARES_TESTNET_CHAIN_ID); transaction.setChainId(CryptoNetManager.getChaindId(CryptoNet.BITSHARES));
ApiRequest transactionRequest = new ApiRequest(0, new ApiRequestListener() { ApiRequest transactionRequest = new ApiRequest(0, new ApiRequestListener() {
@Override @Override

View file

@ -0,0 +1,54 @@
package cy.agorise.crystalwallet.network;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.WitnessResponse;
/**
*
* Created by henry on 28/2/2018.
*/
public class BitsharesCryptoNetVerifier extends CryptoNetVerifier {
/**
* TODO We need to change this to a type of subCryptoNet
*/
private final CryptoNet cryptoNet = CryptoNet.BITSHARES;
/**
* Todo info need to be on the SubCryptoNet
*/
private final String CHAIN_ID = "9cf6f255a208100d2bb275a3c52f4b1589b7ec9c9bfc2cb2a5fe6411295106d8";//testnet
//private final String CHAIN_ID = "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8";//mainnet
@Override
public void checkURL(final String url) {
final long startTime = System.currentTimeMillis();
WebSocketThread thread = new WebSocketThread(new GetChainId(new WitnessResponseListener() {
@Override
public void onSuccess(WitnessResponse response) {
if(response.result instanceof String) {
if(response.result.equals(CHAIN_ID)) {
CryptoNetManager.verifiedCryptoNetURL(cryptoNet, url, System.currentTimeMillis() - startTime);
}else{
System.out.println(" BitsharesCryptoNetVerifier Error we are not in the net current chain id " + response.result + " excepted " + CHAIN_ID);
//TODO handle error bad chain
}
}
}
@Override
public void onError(BaseResponse.Error error) {
//TODO handle error
}
}),url);
thread.start();
}
@Override
public String getChainId() {
return CHAIN_ID;
}
}

View file

@ -0,0 +1,155 @@
package cy.agorise.crystalwallet.network;
import android.support.annotation.NonNull;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import cy.agorise.crystalwallet.enums.CryptoNet;
/**
* Created by henry on 6/3/2018.
*/
public abstract class CryptoNetManager {
/**
* This map contains the list of the urls to be tested
*/
private static HashMap<CryptoNet,HashSet<String>> CryptoNetURLs = new HashMap<>();
/**
* This map contains the list of urls been tested and ordered by the fastests
*/
private static HashMap<CryptoNet,ArrayList<TestedURL>> TestedURLs = new HashMap<>();
public static String getURL(CryptoNet crypto){
return CryptoNetManager.getURL(crypto,0);
}
public static String getURL(CryptoNet crypto, int index){
if(TestedURLs.containsKey(crypto) && TestedURLs.get(crypto).size()>index){
StringBuilder debugString = new StringBuilder("CryptoNetManager urls times: ");
for(TestedURL url : TestedURLs.get(crypto)){
debugString.append("\r\n ").append(url.getTime()).append(" ").append(url.getUrl());
}
System.out.println(debugString.toString());
return TestedURLs.get(crypto).get(index).getUrl();
}
if(CryptoNetURLs.containsKey(crypto) && !CryptoNetURLs.get(crypto).isEmpty()){
return CryptoNetURLs.get(crypto).iterator().next();
}
return null;
}
public static int getURLSize(CryptoNet crypto){
if(TestedURLs.containsKey(crypto)){
return TestedURLs.get(crypto).size();
}
return 0;
}
public static void addCryptoNetURL(CryptoNet crypto, String url){
if(!CryptoNetURLs.containsKey(crypto)){
CryptoNetURLs.put(crypto,new HashSet<String>());
}
CryptoNetURLs.get(crypto).add(url);
CryptoNetVerifier verifier = CryptoNetVerifier.getNetworkVerify(crypto);
if(verifier != null) {
verifier.checkURL(url);
}
}
public static void addCryptoNetURL(CryptoNet crypto, String[] urls){
if(!CryptoNetURLs.containsKey(crypto)){
CryptoNetURLs.put(crypto,new HashSet<String>());
}
CryptoNetVerifier verifier = CryptoNetVerifier.getNetworkVerify(crypto);
for(String url : urls) {
CryptoNetURLs.get(crypto).add(url);
if(verifier != null) {
verifier.checkURL(url);
}
}
}
public static void removeCryptoNetURL(CryptoNet crypto, String url){
if(CryptoNetURLs.containsKey(crypto)){
CryptoNetURLs.get(crypto).remove(url);
}
}
public static void verifiedCryptoNetURL(CryptoNet crypto, String url, long time){
if(CryptoNetURLs.containsKey(crypto) && CryptoNetURLs.get(crypto).contains(url)){
if(!TestedURLs.containsKey(crypto)){
TestedURLs.put(crypto,new ArrayList<TestedURL>());
}
TestedURL testedUrl = new TestedURL(time,url);
if(!TestedURLs.get(crypto).contains(testedUrl)){
TestedURLs.get(crypto).add(testedUrl);
Collections.sort(TestedURLs.get(crypto));
}
}else{
//TODO add error handler
}
}
public static String getChaindId(CryptoNet crypto){
CryptoNetVerifier verifier = CryptoNetVerifier.getNetworkVerify(crypto);
if(verifier != null) {
return verifier.getChainId();
}
return null;
}
private static class TestedURL implements Comparable{
private long time;
private String url;
public TestedURL(long time, String url) {
this.time = time;
this.url = url;
}
public long getTime() {
return time;
}
String getUrl() {
return url;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof TestedURL)) return false;
TestedURL testedURL = (TestedURL) o;
return getUrl().equals(testedURL.getUrl());
}
@Override
public int hashCode() {
return getUrl().hashCode();
}
@Override
public int compareTo(@NonNull Object o) {
if (this == o) return 0;
if (!(o instanceof TestedURL)) return 0;
TestedURL testedURL = (TestedURL) o;
return (int) (this.getTime() - testedURL.getTime());
}
}
}

View file

@ -0,0 +1,25 @@
package cy.agorise.crystalwallet.network;
import cy.agorise.crystalwallet.enums.CryptoNet;
/**
* This is used to check if the connection is stable and fast.
*
* Also verifies if the connection with the server is valid.
*
* Created by henry on 28/2/2018.
*/
public abstract class CryptoNetVerifier {
static CryptoNetVerifier getNetworkVerify(CryptoNet cryptoNet){
if(cryptoNet.getLabel().equals(CryptoNet.BITSHARES.getLabel())){
return new BitsharesCryptoNetVerifier();
}
return null;
}
public abstract void checkURL(final String url);
public abstract String getChainId();
}

View file

@ -0,0 +1,61 @@
package cy.agorise.crystalwallet.network;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketFrame;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.api.BaseGrapheneHandler;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Created by henry on 28/2/2018.
*/
public class GetChainId extends BaseGrapheneHandler {
private final WitnessResponseListener mListener;
public GetChainId(WitnessResponseListener listener) {
super(listener);
this.mListener = listener;
}
@Override
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
ApiCall getAccountByName = new ApiCall(0, "get_chain_id", new ArrayList<Serializable>(), RPC.VERSION, 1);
websocket.sendText(getAccountByName.toJsonString());
}
@Override
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
System.out.println("<<< "+frame.getPayloadText());
String response = frame.getPayloadText();
Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType();
GsonBuilder builder = new GsonBuilder();
WitnessResponse<List<String>> witnessResponse = builder.create().fromJson(response, GetChainIdResponse);
if(witnessResponse.error != null){
this.mListener.onError(witnessResponse.error);
}else{
this.mListener.onSuccess(witnessResponse);
}
websocket.disconnect();
}
@Override
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
if(frame.isTextFrame())
System.out.println(">>> "+frame.getPayloadText());
}
}