Compare commits

...

11 Commits

Author SHA1 Message Date
Severiano Jaramillo b12b3b9546 Remove the eula from the strings and placed it instead as a file into the Assets folder.
We found that using the loadUrl WebView's method instead of loadData renders the html page better, for that reason the eula is now saved as a fule in the assets folder and loaded using the WebView's loadUrl method.
2019-01-02 14:29:29 -06:00
Javier Varona d04e847bba Merge branch 'develop' of https://github.com/agorise/crystal-wallet-android into develop 2018-11-30 21:55:46 -04:00
Javier Varona fe1068bcdf - Fixed bitshares QR scan won't load the amount 2018-11-30 21:54:54 -04:00
Severiano Jaramillo af4a4aca8b Merge branch 'develop' of github.com:Agorise/crystal-wallet-android into develop 2018-11-30 19:51:11 -06:00
Severiano Jaramillo 450a7c285b Increase the camera preview area to improve the QR read performance and make some UI improvements. 2018-11-30 19:49:40 -06:00
hvarona 08df53730b Fix send bad request
Change Send manager to send only the required amount from gtxio
added error capture for estimatefee
2018-11-30 20:58:13 -04:00
Severiano Jaramillo 618e71a6ac Fix FloatingActionButtons used in SendTransactionFragment and BoardActivity, after the migration to the new MaterialComponents they got messed up because the way they are designed in XML and its properties changed a bit. 2018-11-30 11:52:53 -06:00
Severiano Jaramillo 52f75eb3cf Make the area that shows the camera feed to always be a square. The camera feed still has a 3:4 aspect ratio but there is a black square behind it that creates the always square illusion. 2018-11-30 11:29:27 -06:00
Severiano Jaramillo 4bf1c14bb8 Temporarily remove AnimatedTabLayout library. 2018-11-29 21:06:36 -06:00
Severiano Jaramillo a32f7c9eb0 Merge branch 'develop' of github.com:Agorise/crystal-wallet-android into develop 2018-11-29 12:23:24 -06:00
hvarona 2c431ef4e0 Fix BitocinGtxIO Foreign Key Definition 2018-11-28 23:42:56 -04:00
15 changed files with 173 additions and 195 deletions

View File

@ -87,8 +87,6 @@ dependencies {
implementation 'com.github.bilthon:graphenej:0.4.6' implementation 'com.github.bilthon:graphenej:0.4.6'
implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'com.github.sjaramillo10:AnimatedTabLayout:1.0.3'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
implementation 'de.hdodenhof:circleimageview:2.2.0' implementation 'de.hdodenhof:circleimageview:2.2.0'

File diff suppressed because one or more lines are too long

View File

@ -70,12 +70,7 @@ public class LicenseActivity extends AppCompatActivity {
finish(); finish();
} }
else{ else{
wvEULA.loadUrl("file:///android_asset/crystal_eula.html");
/*
* Load the licence only if it is necesarry
* */
String html = getString(R.string.licence_html);
wvEULA.loadData(html, "text/html", "UTF-8");
} }
} }

View File

@ -1,22 +1,19 @@
package cy.agorise.crystalwallet.activities; package cy.agorise.crystalwallet.activities;
import android.content.Intent; import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.sjaramillo10.animatedtablayout.AnimatedTabLayout;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -37,7 +34,7 @@ public class SettingsActivity extends AppCompatActivity{
public ImageView ivGoBack; public ImageView ivGoBack;
@BindView(R.id.tabLayout) @BindView(R.id.tabLayout)
public AnimatedTabLayout tabLayout; public TabLayout tabLayout;
@BindView(R.id.pager) @BindView(R.id.pager)
public ViewPager mPager; public ViewPager mPager;

View File

@ -35,14 +35,18 @@ public abstract class GetEstimateFee {
call.enqueue(new Callback<JsonObject>() { call.enqueue(new Callback<JsonObject>() {
@Override @Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
listener.estimateFee((double) (response.body().get("2").getAsDouble())); try {
listener.estimateFee((double) (response.body().get("2").getAsDouble()));
}catch (Exception e){
e.printStackTrace();
listener.fail();
}
} }
@Override @Override
public void onFailure(Call<JsonObject> call, Throwable t) { public void onFailure(Call<JsonObject> call, Throwable t) {
listener.fail(); listener.fail();
listener.estimateFee(-1);
} }
}); });
}catch(Exception e){ }catch(Exception e){

View File

@ -97,8 +97,8 @@ class InsightApiServiceGenerator {
return chain.proceed(request); return chain.proceed(request);
} }
}); });
sClientBuilder.readTimeout(5, TimeUnit.MINUTES); sClientBuilder.readTimeout(30, TimeUnit.SECONDS);
sClientBuilder.connectTimeout(5, TimeUnit.MINUTES); sClientBuilder.connectTimeout(30, TimeUnit.SECONDS);
OkHttpClient client = sClientBuilder.build(); OkHttpClient client = sClientBuilder.build();
Retrofit retrofit = sBuilder.client(client).build(); Retrofit retrofit = sBuilder.client(client).build();
return retrofit.create(serviceClass); return retrofit.create(serviceClass);

View File

@ -52,8 +52,8 @@ public class CrystalApplication extends Application {
public static final String BITCOIN_SERVER_URLS[] ={ public static final String BITCOIN_SERVER_URLS[] ={
"https://testnet.blockexplorer.com/",
"https://test-insight.bitpay.com", "https://test-insight.bitpay.com",
//"https://testnet.blockexplorer.com/",
//"https://insight.bitpay.com/" //"https://insight.bitpay.com/"
}; };

View File

@ -28,8 +28,6 @@ import android.text.Editable;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
@ -129,9 +127,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
@BindView(R.id.gravatar) @BindView(R.id.gravatar)
CircularImageView userImg; CircularImageView userImg;
@BindView(R.id.viewCamera)
View viewCamera;
/* Flag to control when the camera is visible and when is hidden */ /* Flag to control when the camera is visible and when is hidden */
private boolean cameraVisible = false; private boolean cameraVisible = false;
@ -142,9 +137,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
private FloatingActionButton fabSend; private FloatingActionButton fabSend;
private AlertDialog.Builder builder; private AlertDialog.Builder builder;
/* /* Dialog for loading */
Dialog for loading
*/
private CrystalDialog crystalDialog; private CrystalDialog crystalDialog;
public static SendTransactionFragment newInstance(long cryptoNetAccountId) { public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
@ -171,7 +164,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
//AlertDialog.Builder //AlertDialog.Builder
builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full); builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full);
//builder.setTitle("Send");
LayoutInflater inflater = getActivity().getLayoutInflater(); LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.send_transaction, null); View view = inflater.inflate(R.layout.send_transaction, null);
@ -179,11 +171,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1); this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1);
final Activity activity = getActivity(); /* Add style to the spinner android */
/*
* Add style to the spinner android
* */
spFrom.setBackground(getContext().getDrawable(R.drawable.square_color)); spFrom.setBackground(getContext().getDrawable(R.drawable.square_color));
if (this.cryptoNetAccountId != -1) { if (this.cryptoNetAccountId != -1) {
@ -194,36 +182,10 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList(); List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts); CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
/*
* If only one account block the control
* */
//if(cryptoNetAccounts.size()==1){
// spFrom.setEnabled(false);
//}
spFrom.setAdapter(fromSpinnerAdapter); spFrom.setAdapter(fromSpinnerAdapter);
spFrom.setSelection(0); spFrom.setSelection(0);
setAccountUI(); setAccountUI();
/*
* Custom material spinner implementation
* */
//spFrom.setItems(cryptoNetAccounts);
//spFrom.setSelectedIndex(0);
//spFrom.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<CryptoNetAccount>() {
// @Override
// public void onItemSelected(MaterialSpinner view, int position, long id, CryptoNetAccount item) {
// sendTransactionValidator.validate();
// }
//});
//spFrom.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {
// @Override public void onNothingSelected(MaterialSpinner spinner) {
// }
//});
// etFrom.setText(this.grapheneAccount.getName());
} }
loadUserImage(); loadUserImage();
@ -264,7 +226,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
//cryptoCurrencyList.add(crypto1); //cryptoCurrencyList.add(crypto1);
CryptoCurrencyAdapter assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList); assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
spAsset.setAdapter(assetAdapter); spAsset.setAdapter(assetAdapter);
} }
}); });
@ -340,12 +302,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mScannerView.setResultHandler(this); mScannerView.setResultHandler(this);
mScannerView.startCamera();
// Force dialog fragment to use the full width of the screen
Window dialogWindow = getDialog().getWindow();
assert dialogWindow != null;
dialogWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
loadUserImage(); loadUserImage();
} }
@ -421,7 +378,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
* */ * */
private void showCamera(){ private void showCamera(){
/* Change visibilities of views */ /* Change visibilities of views */
viewCamera.setVisibility(View.GONE);
mScannerView.setVisibility(View.VISIBLE); mScannerView.setVisibility(View.VISIBLE);
/* Change icon */ /* Change icon */
@ -440,7 +396,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
* */ * */
private void hideCamera(){ private void hideCamera(){
/* Change visibilities of views */ /* Change visibilities of views */
viewCamera.setVisibility(View.VISIBLE);
mScannerView.setVisibility(View.INVISIBLE); mScannerView.setVisibility(View.INVISIBLE);
/* Change icon */ /* Change icon */
@ -516,10 +471,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
if (fromAccountSelected.getCryptoNet() == CryptoNet.BITSHARES) { if (fromAccountSelected.getCryptoNet() == CryptoNet.BITSHARES) {
/* /* This is only for graphene accounts. */
* this is only for graphene accounts.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected); GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId())); grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId()));
@ -550,6 +502,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
throwable.printStackTrace(); throwable.printStackTrace();
} }
} else { } else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG); Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
} }
} }
@ -582,22 +535,19 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
throwable.printStackTrace(); throwable.printStackTrace();
} }
} else { } else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG); Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
} }
} }
}); });
} }
/* /* If exists mode security show it and validate events in case of success or fail */
* If exists mode scurity show it and valide events in case of success or fail
* */
CrystalSecurityMonitor.getInstance(this.getActivity()).callPasswordRequest(this.getActivity(), new OnResponse() { CrystalSecurityMonitor.getInstance(this.getActivity()).callPasswordRequest(this.getActivity(), new OnResponse() {
@Override @Override
public void onSuccess() { public void onSuccess() {
/* /* Show loading dialog */
* Show loading dialog
* */
crystalDialog = new CrystalDialog((Activity) getContext()); crystalDialog = new CrystalDialog((Activity) getContext());
crystalDialog.setText("Sending"); crystalDialog.setText("Sending");
crystalDialog.progress(); crystalDialog.progress();
@ -628,10 +578,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
// Camera Permissions // Camera Permissions
private static final int REQUEST_CAMERA_PERMISSION = 1; private static final int REQUEST_CAMERA_PERMISSION = 1;
private static String[] PERMISSIONS_CAMERA = {
Manifest.permission.CAMERA
};
@Override @Override
public void onValidationSucceeded(final ValidationField field) { public void onValidationSucceeded(final ValidationField field) {

View File

@ -241,11 +241,12 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
ccTransaction.setAccountId(address.getAccountId()); ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setFrom(addr); ccTransaction.setFrom(addr);
ccTransaction.setInput(false); ccTransaction.setInput(false);
amount -= (long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision()));
} }
if (ccTransaction.getAccountId() == address.getAccountId()) { //if (ccTransaction.getAccountId() == address.getAccountId()) {
amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision())); amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision()));
} //}
} }
if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) { if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) {
@ -280,9 +281,9 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
ccTransaction.setTo(addr); ccTransaction.setTo(addr);
} }
if (ccTransaction.getAccountId() == address.getAccountId()) { //if (ccTransaction.getAccountId() == address.getAccountId()) {
amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision())); amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision()));
} //}
} else { } else {
//TOOD multiple send address //TOOD multiple send address
if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) { if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) {
@ -309,7 +310,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
btTransaction.setCryptoCoinTransactionId(ccId); btTransaction.setCryptoCoinTransactionId(ccId);
long btId = db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction)[0]; long btId = db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction)[0];
for (BitcoinTransactionGTxIO gtxio : gtxios) { for (BitcoinTransactionGTxIO gtxio : gtxios) {
gtxio.setBitcoinTransactionId(btId); gtxio.setBitcoinTransactionId(ccId);
db.bitcoinTransactionDao().insertBitcoinTransactionGTxIO(gtxio); db.bitcoinTransactionDao().insertBitcoinTransactionGTxIO(gtxio);
} }
@ -374,39 +375,52 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
//TODO check server connection //TODO check server connection
//TODO validate to address //TODO validate to address
System.out.println("GeneralAccount Manager Send request, asking fee");
InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() { InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
Transaction tx = new Transaction(cryptoCoin.getParameters()); System.out.println("GeneralAccount Manager Send request, fee " + answer.toString());
long currentAmount = 0; try {
long fee = -1; Transaction tx = new Transaction(cryptoCoin.getParameters());
long feeRate = (long)(((double)answer) * Math.pow(10,cryptoCoin.getPrecision())); long currentAmount = 0;
fee = 226 * feeRate; long fee = -1;
long feeRate = (long) (((double) answer) * Math.pow(10, cryptoCoin.getPrecision()));
fee = 226 * feeRate;
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext()); System.out.println("GeneralAccount Manager Send request getting utxos" );
db.bitcoinTransactionDao(); CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
db.bitcoinTransactionDao();
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(),db); List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(), db);
System.out.println("GeneralAccount Manager Send request utxos found " + utxos.size() );
for(BitcoinTransactionGTxIO utxo : utxos){
currentAmount += utxo.getAmount();
if(currentAmount >= request.getAmount() + fee) {
break;
}
}
if(currentAmount< request.getAmount() + fee){ if (currentAmount < request.getAmount() + fee) {
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE); System.out.println("GeneralAccount Manager Send request no balance" );
return; request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
} return;
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId()); }
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
//String to an address AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId());
Address toAddr = Address.fromBase58(cryptoCoin.getParameters(), request.getToAccount()); DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr); new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
//String to an address
Address toAddr = Address.fromBase58(cryptoCoin.getParameters(), request.getToAccount());
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr);
/*if(request.getMemo()!= null && !request.getMemo().isEmpty()){ /*if(request.getMemo()!= null && !request.getMemo().isEmpty()){
String memo = request.getMemo(); String memo = request.getMemo();
@ -421,62 +435,74 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
tx.addOutput(Coin.valueOf(0),memoScript); tx.addOutput(Coin.valueOf(0),memoScript);
}*/ }*/
//Change address //Change address
long remain = currentAmount - request.getAmount() - fee; long remain = currentAmount - request.getAmount() - fee;
if( remain > 0 ) { if (remain > 0) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId()); long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index); BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr; Address changeAddr;
if(btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size()<=0){ if (btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size() <= 0) {
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress()); changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
}else{ } else {
if(btAddress == null){ if (btAddress == null) {
index = 0; index = 0;
}else{ } else {
index++; index++;
}
btAddress = new BitcoinAddress();
btAddress.setIndex(index);
btAddress.setAccountId(request.getSourceAccount().getId());
btAddress.setChange(true);
btAddress.setAddress(HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)).toAddress(cryptoCoin.getParameters()).toString());
db.bitcoinAddressDao().insertBitcoinAddresses(btAddress);
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
} }
btAddress = new BitcoinAddress(); tx.addOutput(Coin.valueOf(remain), changeAddr);
btAddress.setIndex(index);
btAddress.setAccountId(request.getSourceAccount().getId());
btAddress.setChange(true);
btAddress.setAddress(HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)).toAddress(cryptoCoin.getParameters()).toString());
db.bitcoinAddressDao().insertBitcoinAddresses(btAddress);
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
} }
tx.addOutput(Coin.valueOf(remain), changeAddr);
for (BitcoinTransactionGTxIO utxo : utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId());
Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash);
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress());
ECKey addrKey;
if (btAddress.isChange()) {
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
} else {
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
}
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
currentAmount -= utxo.getAmount();
if(currentAmount<= 0){
break;
}
}
System.out.println("GeneralAccount Manager Send request rawtx " +Util.bytesToHex(tx.bitcoinSerialize()) );
InsightApiGenerator.broadcastTransaction(cryptoCoin, Util.bytesToHex(tx.bitcoinSerialize()), new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
System.out.println("GeneralAccount MAnager succed send");
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
System.out.println("GeneralAccount MAnager succed fail");
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
}
}));
}catch(Exception e){
System.out.println("GeneralAccount Manager Send request error ");
e.printStackTrace();
} }
for(BitcoinTransactionGTxIO utxo: utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId());
Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash);
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress());
ECKey addrKey;
if(btAddress.isChange()){
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
}else{
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
}
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
}
InsightApiGenerator.broadcastTransaction(cryptoCoin,Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
}
}));
} }
@Override @Override
public void fail(int idPetition) { public void fail(int idPetition) {
System.out.println("GeneralAccount Manager Send request fee fail" );
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE); request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
} }

View File

@ -14,8 +14,8 @@ import android.arch.persistence.room.ForeignKey;
primaryKeys = {"bitcoin_transaction_id", "io_index", "is_output"}, primaryKeys = {"bitcoin_transaction_id", "io_index", "is_output"},
foreignKeys = { foreignKeys = {
@ForeignKey( @ForeignKey(
entity = BitcoinTransaction.class, entity = CryptoCoinTransaction.class,
parentColumns = "crypto_coin_transaction_id", parentColumns = "id",
childColumns = "bitcoin_transaction_id", childColumns = "bitcoin_transaction_id",
onDelete = ForeignKey.CASCADE onDelete = ForeignKey.CASCADE
) )

View File

@ -89,7 +89,7 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
public void setStatus(StatusCode code){ public void setStatus(StatusCode code){
this.status = code; this.status = code;
this._fireOnCarryOutEvent(); this.validate();
} }
public StatusCode getStatus() { public StatusCode getStatus() {

View File

@ -79,13 +79,12 @@
</android.support.v7.widget.Toolbar> </android.support.v7.widget.Toolbar>
<com.sjaramillo10.animatedtablayout.AnimatedTabLayout <android.support.design.widget.TabLayout
android:id="@+id/tabLayout" android:id="@+id/tabLayout"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:animateLayoutChanges="true" android:animateLayoutChanges="true"
app:tabBoldText="true"
app:tabMode="fixed" /> app:tabMode="fixed" />
</RelativeLayout> </RelativeLayout>

View File

@ -96,7 +96,7 @@
</android.support.v7.widget.Toolbar> </android.support.v7.widget.Toolbar>
<com.sjaramillo10.animatedtablayout.AnimatedTabLayout <android.support.design.widget.TabLayout
android:id="@+id/tabLayout" android:id="@+id/tabLayout"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:background="@color/transparent" android:background="@color/transparent"
@ -124,21 +124,25 @@
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/fabReceive" android:id="@+id/fabReceive"
android:layout_width="250dp" android:layout_width="wrap_content"
android:layout_height="250dp" android:layout_height="wrap_content"
android:layout_gravity="start|bottom" android:layout_gravity="start|bottom"
android:layout_marginBottom="-125dp" android:layout_marginBottom="-125dp"
android:layout_marginStart="-125dp" android:layout_marginStart="-125dp"
app:fabCustomSize="250dp"
app:maxImageSize="200dp"
app:backgroundTint="@color/white" app:backgroundTint="@color/white"
app:srcCompat="@drawable/receive_icon" /> app:srcCompat="@drawable/receive_icon" />
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/fabSend" android:id="@+id/fabSend"
android:layout_width="250dp" android:layout_width="wrap_content"
android:layout_height="250dp" android:layout_height="wrap_content"
android:layout_gravity="end|bottom" android:layout_gravity="end|bottom"
android:layout_marginBottom="-125dp" android:layout_marginBottom="-125dp"
android:layout_marginEnd="-125dp" android:layout_marginEnd="-125dp"
app:fabCustomSize="250dp"
app:maxImageSize="200dp"
app:backgroundTint="@color/white" app:backgroundTint="@color/white"
app:srcCompat="@drawable/send_icon" /> app:srcCompat="@drawable/send_icon" />

View File

@ -18,6 +18,13 @@
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/> app:layout_constraintGuide_percent="0.5"/>
<android.support.constraint.Guideline
android:id="@+id/cameraVerticalGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.65"/>
<View <View
android:id="@+id/topView" android:id="@+id/topView"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -206,13 +213,26 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvMemoError" /> app:layout_constraintTop_toBottomOf="@id/tvMemoError" />
<View
android:id="@+id/viewCamera"
android:background="@color/black"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:visibility="visible"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toBottomOf="@+id/tvScan"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/cameraVerticalGuideline"/>
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/fabCloseCamera" android:id="@+id/fabCloseCamera"
android:layout_width="32dp" android:layout_width="wrap_content"
android:layout_height="32dp" android:layout_height="wrap_content"
app:backgroundTint="@color/send_strong_orange" app:backgroundTint="@color/send_strong_orange"
app:fabSize="mini" app:fabCustomSize="32dp"
app:layout_constraintStart_toEndOf="@id/centeredVerticalGuideline" app:layout_constraintStart_toEndOf="@id/cameraVerticalGuideline"
app:layout_constraintTop_toBottomOf="@+id/tvScan" app:layout_constraintTop_toBottomOf="@+id/tvScan"
app:srcCompat="@drawable/ok" /> app:srcCompat="@drawable/ok" />
@ -220,26 +240,12 @@
android:id="@+id/ivCamera" android:id="@+id/ivCamera"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:contentDescription="@string/camera_feed_to_scan_qr" android:contentDescription="@string/camera_feed_to_scan_qr"
android:src="#666" app:layout_constraintDimensionRatio="w,3:4"
app:layout_constraintDimensionRatio="h,3:4" app:layout_constraintTop_toTopOf="@+id/viewCamera"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="@id/viewCamera"
app:layout_constraintEnd_toStartOf="@id/centeredVerticalGuideline" app:layout_constraintStart_toStartOf="@id/viewCamera"
app:layout_constraintTop_toTopOf="@+id/fabCloseCamera" /> app:layout_constraintEnd_toEndOf="@id/viewCamera" />
<View
android:id="@+id/viewCamera"
android:background="@color/black"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="visible"
android:src="#666"
app:layout_constraintTop_toTopOf="@id/ivCamera"
app:layout_constraintStart_toStartOf="@id/ivCamera"
app:layout_constraintEnd_toEndOf="@id/ivCamera"
app:layout_constraintBottom_toBottomOf="@+id/ivCamera"/>
<View <View
android:id="@+id/viewSend" android:id="@+id/viewSend"
@ -248,13 +254,16 @@
android:layout_marginEnd="0dp" android:layout_marginEnd="0dp"
android:background="@drawable/send_transaction_send_view" android:background="@drawable/send_transaction_send_view"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/ivCamera" /> app:layout_constraintTop_toTopOf="@id/viewCamera"
app:layout_constraintBottom_toBottomOf="@id/viewCamera"/>
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/btnSend" android:id="@+id/btnSend"
android:layout_width="90dp" android:layout_width="wrap_content"
android:layout_height="90dp" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
app:fabCustomSize="90dp"
app:maxImageSize="70dp"
app:backgroundTint="@color/send_strong_orange" app:backgroundTint="@color/send_strong_orange"
app:srcCompat="@drawable/ic_arrow_forward" app:srcCompat="@drawable/ic_arrow_forward"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

File diff suppressed because one or more lines are too long