Merge remote-tracking branch 'origin/master'

pull/2/head
MadCake 7 years ago
commit 04f91578be
  1. 4
      app/build.gradle
  2. 2
      app/src/main/AndroidManifest.xml
  3. 89
      app/src/main/java/com/wallet/crypto/trustapp/controller/Controller.java
  4. 10
      app/src/main/java/com/wallet/crypto/trustapp/controller/EtherStore.java
  5. 18
      app/src/main/java/com/wallet/crypto/trustapp/controller/TrustRayService.java
  6. 110
      app/src/main/java/com/wallet/crypto/trustapp/model/TRTransaction.java
  7. 17
      app/src/main/java/com/wallet/crypto/trustapp/model/TRTransactionListResponse.java
  8. 22
      app/src/main/java/com/wallet/crypto/trustapp/model/VMNetwork.java
  9. 5
      app/src/main/java/com/wallet/crypto/trustapp/views/RequestActivity.java
  10. 145
      app/src/main/java/com/wallet/crypto/trustapp/views/SendActivity.java
  11. 13
      app/src/main/java/com/wallet/crypto/trustapp/views/TransactionDetailFragment.java
  12. 14
      app/src/main/java/com/wallet/crypto/trustapp/views/TransactionListActivity.java
  13. 82
      app/src/main/res/layout/activity_send.xml
  14. 6
      app/src/main/res/layout/transaction_detail.xml
  15. 32
      app/src/main/res/values/strings.xml

@ -22,8 +22,8 @@ android {
applicationId "com.wallet.crypto.trustapp"
minSdkVersion 23
targetSdkVersion 26
versionCode 16
versionName "1.3.12"
versionCode 18
versionName "1.3.14"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled = true

@ -84,4 +84,4 @@
android:value="74d3fa8b5038a154c0c05555d27112a0d4a80d68" />
</application>
</manifest>
</manifest>

@ -12,6 +12,7 @@ import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
@ -22,8 +23,8 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.wallet.crypto.trustapp.R;
import com.wallet.crypto.trustapp.model.CMTicker;
import com.wallet.crypto.trustapp.model.ESTransaction;
import com.wallet.crypto.trustapp.model.ESTransactionListResponse;
import com.wallet.crypto.trustapp.model.TRTransaction;
import com.wallet.crypto.trustapp.model.TRTransactionListResponse;
import com.wallet.crypto.trustapp.model.VMAccount;
import com.wallet.crypto.trustapp.model.VMNetwork;
import com.wallet.crypto.trustapp.util.KS;
@ -53,6 +54,7 @@ import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.protocol.infura.InfuraHttpService;
import org.web3j.utils.Numeric;
@ -106,9 +108,8 @@ public class Controller {
// View models
private ArrayList<VMNetwork> mNetworks;
private ArrayList<String> mEtherscanKeys;
private ArrayList<VMAccount> mAccounts;
private Map<String, List<ESTransaction>> mTransactions;
private Map<String, List<TRTransaction>> mTransactions;
private CMTicker mEthTicker = null; // if null, no data available
// Views
@ -144,19 +145,14 @@ public class Controller {
mEtherStore = new EtherStore(mKeystoreBaseDir, this);
// Create etherscan key list
mEtherscanKeys = new ArrayList<>();
mEtherscanKeys.add("{etherscan_key1}");
mEtherscanKeys.add("{etherscan_key2}");
mEtherscanKeys.add("{etherscan_key3}");
// Create networks list
mNetworks = new ArrayList<>();
mNetworks.add(new VMNetwork("mainnet", "https://mainnet.infura.io/llyrtzQ3YhkdESt2Fzrk", "https://api.etherscan.io", 1));
mNetworks.add(new VMNetwork("kovan", "https://kovan.infura.io/llyrtzQ3YhkdESt2Fzrk", "https://kovan.etherscan.io", 42));
mNetworks.add(new VMNetwork("ropstein", "https://ropstein.infura.io/llyrtzQ3YhkdESt2Fzrk", "https://ropstein.etherscan.io", 3));
mNetworks.add(new VMNetwork("rinkeby", "https://rinkeby.infura.io/llyrtzQ3YhkdESt2Fzrk", "https://rinkeby.etherscan.io", 4));
mNetworks.add(new VMNetwork("Ethereum", "ETH", "https://mainnet.infura.io/llyrtzQ3YhkdESt2Fzrk", "https://api.trustwalletapp.com/",
"https://etherscan.io/", 1));
mNetworks.add(new VMNetwork("Kovan (Test)", "ETH(Kovan)", "https://kovan.infura.io/llyrtzQ3YhkdESt2Fzrk", "https://kovan.trustwalletapp.com/", "https://kovan.etherscan.io", 42));
mNetworks.add(new VMNetwork("Ropsten (Test)", "ETH(Ropsten)", "https://ropsten.infura.io/llyrtzQ3YhkdESt2Fzrk", "https://ropsten.trustwalletapp.com/", "https://ropsten.etherscan.io", 3));
//mNetworks.add(new VMNetwork("oracles", "POA", "http://testnet.oracles.org:8545/", "https://oracles.trustwalletapp.com", 12648430));
// Load current from app preferences
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mAppContext);
@ -186,7 +182,7 @@ public class Controller {
}
for (VMAccount a : mAccounts) {
mTransactions.put(a.getAddress(), new ArrayList<ESTransaction>());
mTransactions.put(a.getAddress(), new ArrayList<TRTransaction>());
}
mHandler = new Handler();
@ -266,8 +262,8 @@ public class Controller {
return out;
}
public List<ESTransaction> getTransactions(String address) {
List<ESTransaction> txns = mTransactions.get(address);
public List<TRTransaction> getTransactions(String address) {
List<TRTransaction> txns = mTransactions.get(address);
if (txns == null) {
return new ArrayList<>();
}
@ -302,7 +298,7 @@ public class Controller {
public void navigateToSend(Context context, String to_address) {
Intent intent = new Intent(context, SendActivity.class);
intent.putExtra(getString(R.string.address_keyword), to_address);
intent.putExtra(Controller.KEY_ADDRESS, to_address);
context.startActivity(intent);
}
@ -322,7 +318,7 @@ public class Controller {
VMAccount account = createAccount(password);
mAccounts.add(account);
mTransactions.put(account.getAddress(), new ArrayList<ESTransaction>());
mTransactions.put(account.getAddress(), new ArrayList<TRTransaction>());
Intent intent = new Intent(activity.getApplicationContext(), WarningBackupActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@ -504,15 +500,15 @@ public class Controller {
}
}
public ESTransaction findTransaction(String address, String txn_hash) {
List<ESTransaction> txns = mTransactions.get(address);
public TRTransaction findTransaction(String address, String txn_hash) {
List<TRTransaction> txns = mTransactions.get(address);
if (txns == null) {
Log.e(TAG, "Can't find transactions with given address: " + address);
return null;
}
for (ESTransaction txn : txns) {
for (TRTransaction txn : txns) {
if (txn.getHash().equals(txn_hash)) {
return txn;
}
@ -555,7 +551,7 @@ public class Controller {
}
protected Void doInBackground(Void... params) {
Web3j web3 = Web3jFactory.build(new InfuraHttpService(mCurrentNetwork.getInfuraUrl()));
Web3j web3 = Web3jFactory.build(new HttpService(mCurrentNetwork.getRpcUrl()));
/*
Transaction transaction = Transaction.createFunctionCallTransaction(
from, gasPrice, gasLimit, contractAddress, amount, encodedFunction);
@ -573,7 +569,7 @@ public class Controller {
private class GetWeb3ClientVersionTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
try {
Web3j web3 = Web3jFactory.build(new InfuraHttpService(mCurrentNetwork.getInfuraUrl()));
Web3j web3 = Web3jFactory.build(new HttpService(mCurrentNetwork.getRpcUrl()));
Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().sendAsync().get();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
Log.d("INFO", "web3 client version: " + clientVersion);
@ -595,7 +591,7 @@ public class Controller {
private void getBalance(VMAccount account) {
try {
Web3j web3 = Web3jFactory.build(new InfuraHttpService(mCurrentNetwork.getInfuraUrl()));
Web3j web3 = Web3jFactory.build(new InfuraHttpService(mCurrentNetwork.getRpcUrl()));
EthGetBalance ethGetBalance = web3
.ethGetBalance(account.getAddress(), DefaultBlockParameterName.LATEST)
.sendAsync()
@ -743,14 +739,6 @@ public class Controller {
// }
// }
// Randomize etherscan key selection stay below rate limit
private String getRandomEtherscanKey() {
assert(mEtherscanKeys.size() > 0);
final int random = new Random().nextInt(mEtherscanKeys.size());
return mEtherscanKeys.get(random);
}
private class SendTransactionTask extends AsyncTask<Void, Void, Void> {
private String fromAddress;
private String toAddress;
@ -774,8 +762,9 @@ public class Controller {
}
protected Void doInBackground(Void... params) {
String txnHash = "";
try {
Web3j web3j = Web3jFactory.build(new InfuraHttpService(mCurrentNetwork.getInfuraUrl()));
Web3j web3j = Web3jFactory.build(new InfuraHttpService(mCurrentNetwork.getRpcUrl()));
Account fromAccount = mEtherStore.getAccount(fromAddress);
if (fromAccount == null) {
@ -806,6 +795,7 @@ public class Controller {
.get();
String result = raw.getTransactionHash();
Log.d(TAG, "Transaction hash " + result);
if (raw.hasError()) {
@ -814,15 +804,17 @@ public class Controller {
listener.onTaskCompleted(new TaskResult(TaskStatus.FAILURE, "Transaction error: " + raw.getError().getMessage()));
return null;
}
Log.d(TAG, "Transaction JSON-RPC"+ raw.getJsonrpc());
Log.d(TAG, "Transaction result: " + raw.getResult());
Log.d(TAG, "Transaction hash: " + raw.getTransactionHash());
txnHash = raw.getTransactionHash();
} catch (Exception e) {
Log.e(TAG, e.toString());
listener.onTaskCompleted(new TaskResult(TaskStatus.FAILURE, "Transaction error: " + e.toString()));
return null;
}
listener.onTaskCompleted(new TaskResult(TaskStatus.SUCCESS, "Payment sent"));
listener.onTaskCompleted(new TaskResult(TaskStatus.SUCCESS, txnHash));
return null;
}
}
@ -882,32 +874,21 @@ public class Controller {
Retrofit mRetrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(mCurrentNetwork.getEtherscanUrl())
.baseUrl(mCurrentNetwork.getBackendUrl())
.build();
EtherscanService service = mRetrofit.create(EtherscanService.class);
final String etherscanKey = getRandomEtherscanKey();
Log.d(TAG, "Using etherscan service: " + mCurrentNetwork.getName() + ", " + mCurrentNetwork.getEtherscanUrl() + ", " + etherscanKey);
Call<ESTransactionListResponse> call =
service.getTransactionList(
"account",
"txlist",
address,
"0",
"desc",
etherscanKey
);
TrustRayService service = mRetrofit.create(TrustRayService.class);
Call<TRTransactionListResponse> call =
service.getTransactionList(address,"50");
Log.d("INFO", "Request query:" + call.request().url().query());
call.enqueue(new Callback<ESTransactionListResponse>() {
call.enqueue(new Callback<TRTransactionListResponse>() {
@Override
public void onResponse(Call<ESTransactionListResponse> call, Response<ESTransactionListResponse> response) {
public void onResponse(Call<TRTransactionListResponse> call, Response<TRTransactionListResponse> response) {
try {
List<ESTransaction> transactions = response.body().getTransactionList();
List<TRTransaction> transactions = response.body().getTransactionList();
mTransactions.put(address, transactions);
Log.d("INFO", "Number of transactions: " + transactions.size());
if (transactions.size() > 0) {
@ -920,7 +901,7 @@ public class Controller {
}
@Override
public void onFailure(Call<ESTransactionListResponse> call, Throwable t) {
public void onFailure(Call<TRTransactionListResponse> call, Throwable t) {
Log.e("ERROR", t.toString());
Toast.makeText(mAppContext, "Error contacting RPC service. Check internet connection.", Toast.LENGTH_SHORT).show();
}

@ -56,7 +56,15 @@ public class EtherStore {
// Wei
public static long getMaxGasFee() {
return 100000000000000000L;
return 20000000000000000L;
}
public static int getTokenGasLimit() {
return 144000;
}
public static long getMinGasPrice() {
return 1000000000;
}
public Account createAccount(String password) throws Exception {

@ -0,0 +1,18 @@
package com.wallet.crypto.trustapp.controller;
import com.wallet.crypto.trustapp.model.ESTransactionListResponse;
import com.wallet.crypto.trustapp.model.TRTransactionListResponse;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
/**
* Created by msubkhankulov on 11/30/2017.
*/
public interface TrustRayService {
@GET("/transactions")
Call<TRTransactionListResponse> getTransactionList(@Query("address") String address,
@Query("limit") String limit);
}

@ -0,0 +1,110 @@
package com.wallet.crypto.trustapp.model;
import com.google.gson.annotations.SerializedName;
/**
* Created by msubkhankulov on 11/30/2017.
*/
/* Based on the following JSON
{
"_id": "0xa65e8541bc78479d5d2d62ebbcc1454f106dd9824cde3bcb66c01097e43ca39e",
"blockNumber": 4815300,
"timeStamp": "1511432228",
"nonce": 9,
"from": "0xaa3cc54d7f10fa3a1737e4997ba27c34f330ce16",
"to": "0x7d788fc8df7165b11a19f201558fcc3590fd8d97",
"value": "100000000000000",
"gas": "90000",
"gasPrice": "1000000000",
"input": "0x",
"gasUsed": "21000",
"operations": [],
"addresses": [
"0xaa3cc54d7f10fa3a1737e4997ba27c34f330ce16",
"0x7d788fc8df7165b11a19f201558fcc3590fd8d97"
],
"operations_localized": [],
"id": "0xa65e8541bc78479d5d2d62ebbcc1454f106dd9824cde3bcb66c01097e43ca39e"
}
*/
public class TRTransaction {
@SerializedName("blockNumber")
private String blockNumber;
@SerializedName("timeStamp")
private String timeStamp;
@SerializedName("nonce")
private String nonce;
@SerializedName("from")
private String from;
@SerializedName("to")
private String to;
@SerializedName("value")
private String value;
@SerializedName("gas")
private String gas;
@SerializedName("gasPrice")
private String gasPrice;
@SerializedName("input")
private String input;
@SerializedName("gasUsed")
private String gasUsed;
@SerializedName("id")
private String hash;
public String getBlockNumber() {
return blockNumber;
}
public String getTimeStamp() {
return timeStamp;
}
public String getNonce() {
return nonce;
}
public String getFrom() {
return from;
}
public String getTo() {
return to;
}
public String getValue() {
return value;
}
public String getGas() {
return gas;
}
public String getGasPrice() {
return gasPrice;
}
public String getInput() {
return input;
}
public String getGasUsed() {
return gasUsed;
}
public String getHash() {
return hash;
}
}

@ -0,0 +1,17 @@
package com.wallet.crypto.trustapp.model;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
/**
* Created by msubkhankulov on 11/30/2017.
*/
public class TRTransactionListResponse {
@SerializedName("docs")
private List<TRTransaction> transactionList = new ArrayList<TRTransaction>();
public List<TRTransaction> getTransactionList() { return transactionList; }
}

@ -6,13 +6,17 @@ package com.wallet.crypto.trustapp.model;
public class VMNetwork {
private String name;
private String infuraUrl;
private String symbol;
private String rpcServerUrl;
private String backendUrl;
private String etherscanUrl;
private int chainId;
public VMNetwork(String name, String infuraUrl, String etherscanUrl, int chainId) {
public VMNetwork(String name, String symbol, String rpcServerUrl, String backendUrl, String etherscanUrl, int chainId) {
this.name = name;
this.infuraUrl = infuraUrl;
this.symbol = symbol;
this.rpcServerUrl = rpcServerUrl;
this.backendUrl = backendUrl;
this.etherscanUrl = etherscanUrl;
this.chainId = chainId;
}
@ -22,14 +26,18 @@ public class VMNetwork {
return name;
}
public String getInfuraUrl() {
return infuraUrl;
public String getSymbol() { return symbol; }
public String getRpcUrl() {
return rpcServerUrl;
}
public String getEtherscanUrl() {
return etherscanUrl;
public String getBackendUrl() {
return backendUrl;
}
public String getEtherscanUrl() { return etherscanUrl; }
public int getChainId() {
return chainId;
}

@ -27,7 +27,6 @@ import com.wallet.crypto.trustapp.model.VMAccount;
public class RequestActivity extends AppCompatActivity {
final static String ETHEREUM_PREFIX = "ethereum:";
private static final String TAG = "REQUEST_ACTIVITY";
ImageView imageView;
@ -57,7 +56,7 @@ public class RequestActivity extends AppCompatActivity {
@Override
public void onClick(View view) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(getString(R.string.address_keyword), addressTextView.getText().toString());
ClipData clip = ClipData.newPlainText(Controller.KEY_ADDRESS, addressTextView.getText().toString());
clipboard.setPrimaryClip(clip);
Toast.makeText(RequestActivity.this, "Copied to clipboard", Toast.LENGTH_SHORT).show();
@ -65,7 +64,7 @@ public class RequestActivity extends AppCompatActivity {
});
try {
final Bitmap qrCode = TextToImageEncode(ETHEREUM_PREFIX + Controller.with(this).getCurrentAccount().getAddress() + "?value=0");
final Bitmap qrCode = TextToImageEncode(Controller.with(this).getCurrentAccount().getAddress());
imageView.setImageBitmap(qrCode);
} catch(Exception e) {
Log.d(TAG, e.getMessage());

@ -1,6 +1,7 @@
package com.wallet.crypto.trustapp.views;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Point;
import android.os.Bundle;
@ -13,6 +14,7 @@ import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
@ -31,6 +33,7 @@ import com.wallet.crypto.trustapp.views.barcode.BarcodeCaptureActivity;
import org.ethereum.geth.Address;
import java.util.List;
import java.math.BigInteger;
public class SendActivity extends AppCompatActivity {
@ -45,12 +48,16 @@ public class SendActivity extends AppCompatActivity {
public static final String EXTRA_SYMBOL = "extra_symbol";
public static final String EXTRA_DECIMALS = "extra_decimals";
private final Handler handler = new Handler();
private final Handler handler = new Handler();
private EditText mTo;
private EditText mAmount;
private EditText mGasLimit;
private EditText mGasPrice;
private EditText mTo;
private EditText mAmount;
private SeekBar mGasLimit;
private SeekBar mGasPrice;
private int gasLimitSelected;
private int gasPriceSelected; //Gwei
private static long weiInGwei = 1000000000;
private TextView mResultTextView;
@ -72,7 +79,7 @@ public class SendActivity extends AppCompatActivity {
mController = Controller.with(this);
mTo = findViewById(R.id.date);
mAmount = findViewById(R.id.amount);
String toAddress = getIntent().getStringExtra(getString(R.string.address_keyword));
String toAddress = getIntent().getStringExtra(Controller.KEY_ADDRESS);
if (toAddress != null) {
mTo.setText(toAddress);
}
@ -80,25 +87,74 @@ public class SendActivity extends AppCompatActivity {
mDecimals = getIntent().getIntExtra(EXTRA_DECIMALS, -1);
mSymbol = getIntent().getStringExtra(EXTRA_SYMBOL);
mSendingTokens = getIntent().getBooleanExtra(EXTRA_SENDING_TOKENS, false);
assert(!mSendingTokens || (mSendingTokens && mDecimals > -1 && mContractAddress != null));
if (mSendingTokens && mSymbol != null) {
mAmount.setHint(mSymbol + " amount");
} else {
mAmount.setHint("ETH amount");
mAmount.setHint(mController.getCurrentNetwork().getSymbol() + " amount");
}
mGasLimit = findViewById(R.id.gas_limit_text);
mGasLimit.setText(Integer.toString(EtherStore.getDefaultGasLimit()));
final TextView gasLimitText = findViewById(R.id.gas_limit_text);
mGasLimit = findViewById(R.id.gas_limit_slider);
mGasLimit.setMax(EtherStore.getMaxGasLimit() - EtherStore.getMinGasLimit());
if (mSendingTokens) {
gasLimitSelected = EtherStore.getTokenGasLimit();
} else {
gasLimitSelected = EtherStore.getDefaultGasLimit();
}
mGasLimit.setProgress(gasLimitSelected - EtherStore.getMinGasLimit());
mGasLimit.refreshDrawableState();
gasLimitText.setText("" + (gasLimitSelected));
mGasLimit.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progress = progress / 100;
progress = progress * 100;
gasLimitSelected = progress + EtherStore.getMinGasLimit();
gasLimitText.setText("" + (gasLimitSelected));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mGasPrice = findViewById(R.id.gas_price_text);
mGasPrice.setText(Long.toString(EtherStore.getDefaultGasPrice()));
final TextView gasPriceText = findViewById(R.id.gas_price_text);
final int minGasPrice = (int)(EtherStore.getMinGasPrice()/weiInGwei);
mGasPrice = findViewById(R.id.gas_price_slider);
mGasPrice.setMax((int)(EtherStore.getMaxGasFee() / EtherStore.getMaxGasLimit() / weiInGwei - minGasPrice));
gasPriceSelected = (int)(EtherStore.getDefaultGasPrice() / weiInGwei);
mGasPrice.setProgress((int)(EtherStore.getDefaultGasPrice()/weiInGwei - minGasPrice));
gasPriceText.setText("" + (gasPriceSelected));
mGasPrice.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
gasPriceSelected = progress + minGasPrice;
gasPriceText.setText("" + (gasPriceSelected));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Button mSendButton = findViewById(R.id.send_button);
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onSendClick();
onSendClick();
}
});
@ -122,7 +178,6 @@ public class SendActivity extends AppCompatActivity {
private void onSendClick() {
// Validate input fields
showSendProgress();
boolean inputValid = true;
final String to = mTo.getText().toString();
if (!isAddressValid(to)) {
@ -135,27 +190,26 @@ public class SendActivity extends AppCompatActivity {
inputValid = false;
}
final String gasLimit = mGasLimit.getText().toString();
if (!isValidGasLimit(gasLimit)) {
mGasLimit.setError("Invalid gas limit");
inputValid = false;
if (!isValidGasLimit(gasLimitSelected)) {
Toast.makeText(SendActivity.this, "Invalid gas limit: " + gasLimitSelected, Toast.LENGTH_LONG).show();
inputValid = false;
}
final String gasPrice = mGasPrice.getText().toString();
if (!isValidGasPrice(gasPrice)) {
mGasPrice.setError("Invalid gas price");
inputValid = false;
if (!isValidGasPrice(gasPriceSelected)) {
Toast.makeText(SendActivity.this, "Invalid gas price: " + gasPriceSelected, Toast.LENGTH_LONG).show();
inputValid = false;
}
if (!isValidGasFee(gasLimit, gasPrice)) {
mGasLimit.setError("Resulting gas fee is invalid");
mGasPrice.setError("Resulting gas fee is invalid");
inputValid = false;
if (!isValidGasFee(Integer.toString(gasLimitSelected), Long.toString(gasPriceSelected * weiInGwei))) {
Toast.makeText(SendActivity.this, "Gas fee (limit*price) is invalid", Toast.LENGTH_LONG).show();
inputValid = false;
}
if (!inputValid) {
return;
}
showSendProgress();
try {
if (mSendingTokens) {
mController.clickSendTokens(
@ -163,8 +217,8 @@ public class SendActivity extends AppCompatActivity {
mTo.getText().toString(),
mContractAddress,
mAmount.getText().toString(),
mGasLimit.getText().toString(),
mGasPrice.getText().toString(),
Integer.toString(gasLimitSelected),
Long.toString(gasPriceSelected * weiInGwei),
mDecimals,
onSendCompleteListener);
} else {
@ -172,8 +226,8 @@ public class SendActivity extends AppCompatActivity {
mController.getCurrentAccount().getAddress(),
mTo.getText().toString(),
mAmount.getText().toString(),
mGasLimit.getText().toString(),
mGasPrice.getText().toString(),
Integer.toString(gasLimitSelected),
Long.toString(gasPriceSelected * weiInGwei),
onSendCompleteListener);
}
} catch (ServiceErrorException ex) {
@ -202,20 +256,18 @@ public class SendActivity extends AppCompatActivity {
}
}
boolean isValidGasLimit(String limit) {
try {
long l = Long.parseLong(limit);
// Though no bound exists on gas price, it has to be at least within the bounds of the fee
return l >= EtherStore.getMinGasLimit() && l <= EtherStore.getMaxGasLimit();
boolean isValidGasLimit(int l) {
try {
// Though no bound exists on gas price, it has to be at least within the bounds of the fee
return l >= EtherStore.getMinGasLimit() && l <= EtherStore.getMaxGasLimit();
} catch (Exception e) {
return false;
}
}
boolean isValidGasPrice(String price) {
boolean isValidGasPrice(int price) {
try {
long l = Long.parseLong(price);
return l >= EtherStore.getMinGasFee() && l <= EtherStore.getMaxGasFee();
return price*weiInGwei >= EtherStore.getMinGasPrice() && price*weiInGwei <= EtherStore.getMaxGasFee();
} catch (Exception e) {
return false;
}
@ -307,11 +359,22 @@ public class SendActivity extends AppCompatActivity {
@Override
public void run() {
if (result.getStatus() == TaskStatus.SUCCESS) {
finish();
}
hideSendProgress();
Toast.makeText(getApplicationContext(), result.getMessage(), Toast.LENGTH_LONG).show();
AlertDialog alertDialog = new AlertDialog.Builder(SendActivity.this).create();
if (result.getStatus() == TaskStatus.SUCCESS) {
alertDialog.setTitle("Sent");
} else {
alertDialog.setTitle("Error");
}
alertDialog.setMessage(result.getMessage());
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
}

@ -15,7 +15,7 @@ import android.widget.TextView;
import com.wallet.crypto.trustapp.R;
import com.wallet.crypto.trustapp.controller.Controller;
import com.wallet.crypto.trustapp.model.ESTransaction;
import com.wallet.crypto.trustapp.model.TRTransaction;
public class TransactionDetailFragment extends Fragment implements View.OnClickListener {
/**
@ -24,14 +24,13 @@ public class TransactionDetailFragment extends Fragment implements View.OnClickL
*/
public static final String ARG_TXN_HASH = "item_id";
public static final String ARG_ADDRESS = "address";
private static final String URL_ETHERSCAN_TXN_BASE = "https://etherscan.io/tx/";
private static final String TAG = "TXN_DETAIL_FRAG";
/**
* The dummy content this fragment is presenting.
*/
private ESTransaction mItem;
private TRTransaction mItem;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
@ -91,7 +90,7 @@ public class TransactionDetailFragment extends Fragment implements View.OnClickL
}
if (appBarLayout != null) {
appBarLayout.setTitle(eth + " ETH");
appBarLayout.setTitle(eth + " " + mController.getCurrentNetwork().getSymbol());
}
}
}
@ -105,11 +104,11 @@ public class TransactionDetailFragment extends Fragment implements View.OnClickL
if (mItem != null) {
((TextView) rootView.findViewById(R.id.from)).setText(mItem.getFrom());
((TextView) rootView.findViewById(R.id.to)).setText(mItem.getTo());
((TextView) rootView.findViewById(R.id.gas_fee)).setText(Controller.WeiToGwei(mItem.getGasUsed()));
((TextView) rootView.findViewById(R.id.confirmation)).setText(mItem.getConfirmations());
((TextView) rootView.findViewById(R.id.gas_fee)).setText(mItem.getGasUsed());
//((TextView) rootView.findViewById(R.id.confirmation)).setText("TBD");
((TextView) rootView.findViewById(R.id.txn_hash)).setText(mItem.getHash());
((TextView) rootView.findViewById(R.id.txn_time)).setText(Controller.GetDate(Long.decode(mItem.getTimeStamp())));
((TextView) rootView.findViewById(R.id.block_hash)).setText(mItem.getBlockHash());
((TextView) rootView.findViewById(R.id.block_number)).setText(mItem.getBlockNumber());
rootView.findViewById(R.id.more_detail).setOnClickListener(this);
}

@ -30,6 +30,7 @@ import com.wallet.crypto.trustapp.controller.OnTaskCompleted;
import com.wallet.crypto.trustapp.controller.ServiceErrorException;
import com.wallet.crypto.trustapp.controller.TaskResult;
import com.wallet.crypto.trustapp.model.ESTransaction;
import com.wallet.crypto.trustapp.model.TRTransaction;
import com.wallet.crypto.trustapp.model.VMAccount;
import com.wallet.crypto.trustapp.util.KS;
import com.wallet.crypto.trustapp.util.PMMigrateHelper;
@ -133,9 +134,9 @@ public class TransactionListActivity extends AppCompatActivity {
// Conversion data may not be available, in which case, hide it
if (usd != null) {
getSupportActionBar().setTitle("$" + usd);
getSupportActionBar().setSubtitle(balance + " ETH");
getSupportActionBar().setSubtitle(balance + " " + mController.getCurrentNetwork().getSymbol());
} else {
getSupportActionBar().setTitle(balance + " ETH");
getSupportActionBar().setTitle(balance + " " + mController.getCurrentNetwork().getSymbol());
getSupportActionBar().setSubtitle(mAddress);
}
@ -277,16 +278,16 @@ public class TransactionListActivity extends AppCompatActivity {
private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
Controller controller = Controller.with(this);
List<ESTransaction> txns = controller.getTransactions(mAddress);
List<TRTransaction> txns = controller.getTransactions(mAddress);
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(txns));
}
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final List<ESTransaction> mValues;
private final List<TRTransaction> mValues;
public SimpleItemRecyclerViewAdapter(List<ESTransaction> items) {
public SimpleItemRecyclerViewAdapter(List<TRTransaction> items) {
mValues = items;
}
@ -352,10 +353,9 @@ public class TransactionListActivity extends AppCompatActivity {
public final TextView mSentOrReceived;
public final TextView mAddressView;
public final TextView mDateView;
//public final TextView mBalanceView;
public final TextView mValueView;
public ESTransaction mItem;
public TRTransaction mItem;
public ViewHolder(View view) {
super(view);

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/email_login_form"
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/email_login_form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@ -48,41 +49,74 @@
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
<Button
android:id="@+id/send_button"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_send" />
<EditText
android:id="@+id/gas_limit_text"
android:layout_width="match_parent"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
>
<TextView
android:text="@string/gas_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/gas_limit"
android:inputType="number"
android:maxLines="1" />
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
/>
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/gas_price_text"
android:text="30"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
/>
<android.support.design.widget.TextInputLayout
</RelativeLayout>
<SeekBar
android:id="@+id/gas_price_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
/>
<EditText
android:id="@+id/gas_price_text"
android:layout_width="match_parent"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp">
<TextView
android:text="@string/gas_limit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/gas_price"
android:inputType="number"
android:maxLines="1" />
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"/>
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/gas_limit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="90000"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
<Button
android:id="@+id/send_button"
style="@style/Widget.AppCompat.Button.Colored"
<SeekBar
android:id="@+id/gas_limit_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_send" />
android:layout_marginTop="10dp"
/>
<TextView
android:id="@+id/result_textview"

@ -47,7 +47,7 @@
android:id="@+id/gas_fee_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Gas Fee"
android:text="@string/gas_fee_title"
android:textAppearance="?attr/textAppearanceListItem" />
<TextView
@ -58,6 +58,7 @@
android:textSize="9dp"
android:textAppearance="?attr/textAppearanceListItemSmall" />
<!-- TODO
<TextView
android:id="@+id/confirmation_title"
android:layout_width="wrap_content"
@ -72,6 +73,7 @@
android:text="107443"
android:textSize="9dp"
android:textAppearance="?attr/textAppearanceListItemSmall" />
-->
<TextView
android:id="@+id/txn_hash_title"
@ -111,7 +113,7 @@
android:textAppearance="?attr/textAppearanceListItem" />
<TextView
android:id="@+id/block_hash"
android:id="@+id/block_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="4238793"

@ -18,7 +18,6 @@
<!-- String related to sending -->
<string name="prompt_to">To</string>
<string name="prompt_amount">ETH Amount</string>
<string name="action_send">Send</string>
<string name="error_invalid_email">This email address is invalid</string>
@ -107,23 +106,24 @@
<string name="tab_keystore">Keystore</string>
<string name="tab_private_key">Private key</string>
<string name="action_transaction_detail">More details</string>
<string name="lock_title">Lock screen</string>
<string name="lock_body">Secure lock screen hasn\'t set up. It is not safe.</string>
<string name="lock_settings">Lock settings</string>
<string name="lock_exit">Exit</string>
<string name="unlock_screen_title_android">Unlock screen</string>
<string name="unlock_screen_prompt_android">Please unlock your Android device to continue.</string>
<string name="sending_progress">Sending...</string>
<string name="lock_title">Lock screen</string>
<string name="lock_body">Secure lock screen hasn\'t set up. It is not safe.</string>
<string name="lock_settings">Lock settings</string>
<string name="lock_exit">Exit</string>
<string name="unlock_screen_title_android">Unlock screen</string>
<string name="unlock_screen_prompt_android">Please unlock your Android device to continue.</string>
<string name="sending_progress">Sending...</string>
<string name="backup_new_password_text">Think of a password that will be installed on the backup.\nThe password will be available for this account.</string>
<string name="do_manage_make_backup">Did you manage to make a backup?</string>
<string name="yes_continue">Yes, continue</string>
<string name="no_repeat">No, repeat</string>
<string name="unable_unblock_device">Unable to unlock the device.</string>
<string name="backup_new_password_text">Think of a password that will be installed on the backup.\nThe password will be available for this account.</string>
<string name="do_manage_make_backup">Did you manage to make a backup?</string>
<string name="yes_continue">Yes, continue</string>
<string name="no_repeat">No, repeat</string>
<string name="unable_unblock_device">Unable to unlock the device.</string>
<string name="gas_limit">Gas Limit</string>
<string name="gas_price">Gas Price (Wei)</string>
<string name="skip">Skip</string>
<string name="root_title">DEVICE SECURITY COMPROMISED</string>
<string name="root_body">Any \'rooted\' app can access Trust\'s keychain data and steal your wallet! Wipe this wallet immediately and restore on a secure device.</string>
<string name="skip">Skip</string>
<string name="root_title">DEVICE SECURITY COMPROMISED</string>
<string name="root_body">Any \'rooted\' app can access Trust\'s keychain data and steal your wallet! Wipe this wallet immediately and restore on a secure device.</string>
<string name="gas_fee_title">Gas Fee (Gwei)</string>
</resources>

Loading…
Cancel
Save