# Conflicts:
#	app/src/main/java/cy/agorise/crystalwallet/activities/ImportSeedActivity.java
feat_androidx_migration
Javier Varona 2018-10-24 23:07:11 -04:00
commit c216dfa209
15 changed files with 304 additions and 211 deletions

View File

@ -259,52 +259,7 @@ class CreateSeedActivity : CustomActivity() {
* */
if (result) {
/*
* Show the dialog for connection with the server
* */
val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_Server_validation))
creatingAccountMaterialDialog.progress()
creatingAccountMaterialDialog.show()
/*
* Validate the account does not exists
* */
val request = ValidateExistBitsharesAccountRequest(tietAccountName?.text.toString())
request.setListener {
/*
* Dismiss the dialog of loading
* */
creatingAccountMaterialDialog.dismiss()
if (request.accountExists) {
/*
* The account exists and is not valid
* */
tietAccountName.fieldValidatorModel.setInvalid()
tietAccountName.fieldValidatorModel.message = tietAccountName.resources.getString(R.string.account_name_already_exist)
/*
* Disaible button create
* */
disableCreate()
} else {
/*
* Passed all validations
* */
tietAccountName.fieldValidatorModel.setValid()
/*
* Enable button create
* */
enableCreate()
}
}
CryptoNetInfoRequests.getInstance().addRequest(request)
enableCreate()
} else {

View File

@ -3,7 +3,6 @@ package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
@ -12,7 +11,6 @@ import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
@ -23,7 +21,6 @@ import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.dialogs.material.CrystalLoading;
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
@ -32,7 +29,6 @@ import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.requestmanagers.ImportBitsharesAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator;
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
@ -78,6 +74,11 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
final Activity activity = this;
/*
* Flag to check correct PIN equality
* */
private boolean pinsOK = false;
@ -128,20 +129,20 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@Override
public void afterTextChanged(Editable s) {
/*
* Validate that PINs are equals
* */
validatePINS();
/*
* If all is ready to continue enable the button, contrarie case disable it
* */
if(allFieldsAreFill()){
if(allFieldsAreOK()){
enableCreate();
}
else{
disableCreate();
}
/*
* Validate that PINs are equals
* */
validatePINS();
}
});
etPinConfirmation.addTextChangedListener(new TextWatcher() {
@ -158,20 +159,20 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@Override
public void afterTextChanged(Editable s) {
/*
* Validate that PINs are equals
* */
validatePINS();
/*
* If all is ready to continue enable the button, contrarie case disable it
* */
if(allFieldsAreFill()){
if(allFieldsAreOK()){
enableCreate();
}
else{
disableCreate();
}
/*
* Validate that PINs are equals
* */
validatePINS();
}
});
etSeedWords.addTextChangedListener(new TextWatcher() {
@ -188,10 +189,15 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@Override
public void afterTextChanged(Editable s) {
/*
* Validate that PINs are equals
* */
validatePINS();
/*
* If all is ready to continue enable the button, contrarie case disable it
* */
if(allFieldsAreFill()){
if(allFieldsAreOK()){
enableCreate();
}
else{
@ -201,7 +207,7 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
/*
* Hide error field
* */
txtErrorAccount.setVisibility(View.INVISIBLE);
clearErrors();
}
});
/*
@ -219,10 +225,15 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@Override
public void afterTextChanged(Editable s) {
//
// Validate that PINs are equals
//
validatePINS();
//
// If all is ready to continue enable the button, contrarie case disable it
//
if(allFieldsAreFill()){
if(allFieldsAreOK()){
enableCreate();
}
else{
@ -237,6 +248,13 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
importSeedValidator.setListener(this);
}
private void clearErrors(){
txtErrorPIN.setVisibility(View.INVISIBLE);
txtErrorAccount.setVisibility(View.INVISIBLE);
}
/*
* Validate that PINs are equals
* */
@ -246,29 +264,34 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
final String confirmoPIN = etPinConfirmation.getText().toString().trim();
if(!pin.isEmpty() && !confirmoPIN.isEmpty()){
if(pin.compareTo(confirmoPIN)!=0){
pinsOK = false;
txtErrorPIN.setVisibility(View.VISIBLE);
}
else{
txtErrorPIN.setVisibility(View.INVISIBLE);
pinsOK = true;
clearErrors();
}
}
else{
txtErrorPIN.setVisibility(View.INVISIBLE);
pinsOK = false;
clearErrors();
}
}
/*
* Method to validate if all the fields are fill
* Method to validate if all the fields are fill and correctly
* */
private boolean allFieldsAreFill(){
private boolean allFieldsAreOK(){
boolean complete = false;
if( etPin.getText().toString().trim().compareTo("")!=0 &&
etPinConfirmation.getText().toString().trim().compareTo("")!=0 &&
etSeedWords.getText().toString().trim().compareTo("")!=0 /*&&
etAccountName.getText().toString().trim().compareTo("")!=0*/){
complete = true;
if(pinsOK){
complete = true;
}
}
return complete;
}
@ -327,6 +350,11 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
final CrystalLoading crystalLoading = new CrystalLoading(activity);
crystalLoading.show();
/*
* Final service connection
* */
finalStep(crystalLoading);
/*
* Validate mnemonic with the server
* */
@ -334,13 +362,10 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
request.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if(request.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)){
if(request.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED)){
//Correct
/*
* Final service connection
* */
finalStep(crystalLoading);
}
@ -380,27 +405,58 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
* */
crystalLoading.dismiss();
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
String errorText = "An error ocurred attempting to import the account";
if (!validatorRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
switch (validatorRequest.getStatus()){
case PETITION_FAILED:
case NO_INTERNET:
case NO_SERVER_CONNECTION:
errorText = "There was an error with the connection. Try again later";
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.NO_SERVER_CONNECTION));
}
});
break;
case ACCOUNT_DOESNT_EXIST:
errorText = "The account doesn't exists";
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.ACCOUNT_DOESNT_EXIST));
}
});
break;
case BAD_SEED:
errorText = "The seed is not valid";
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.BAD_SEED));
}
});
break;
case NO_ACCOUNT_DATA:
errorText = "The account doesn't have any data";
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.NO_ACCOUNT_DATA));
}
});
break;
default:
txtErrorAccount.setText(activity.getResources().getString(R.string.ERROR_UNRECOGNIZABLE));
}
Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setVisibility(View.VISIBLE);
}
});
//Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(thisActivity, BoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

View File

@ -36,6 +36,19 @@ public class PatternRequestActivity extends AppCompatActivity {
@BindView(R.id.tvPatternText)
TextView tvPatternText;
@BindView(R.id.txtBadtry)
TextView txtBadtry;
/*
* Contains the bad tries
* */
private int tries = 0;
/*
* Seconds counter
* */
private int seconds = 15;
@ -111,10 +124,69 @@ public class PatternRequestActivity extends AppCompatActivity {
private void incorrect(){
/*
* One more bad try
* */
++tries;
final Activity activity = this;
/*
* User can not go more up to 5 bad tries
* */
if(tries==4) {
tries = 0;
patternLockView.setEnabled(false);
txtBadtry.setVisibility(View.VISIBLE);
txtBadtry.setText(txtBadtry.getText().toString().replace("%%",String.valueOf(seconds)));
final Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
--seconds;
if(seconds==0){
t.cancel();
seconds = 15;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
patternLockView.setEnabled(true);
txtBadtry.setVisibility(View.INVISIBLE);
patternLockView.clearPattern();
patternLockView.requestFocus();
}
});
}
else{
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtBadtry.setText(activity.getResources().getString(R.string.wrong_pin_wait).replace("%%",String.valueOf(seconds)));
}
});
}
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
return;
}
/*
* Show error
* */
final Activity activity = this;
tvPatternText.setText(activity.getResources().getString(R.string.Incorrect_pattern));
tvPatternText.setTextColor(Color.RED);
tvPatternText.setVisibility(View.VISIBLE);

View File

@ -18,11 +18,9 @@ public class InsightApiGenerator {
* Fecth all the transaciton for a giving address
* @param cryptoCoin the crypto net of the address
* @param address The address String
* @param request the request api to response
* @param subscribe If needs to follow the address (Real time)
*/
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address,
ApiRequest request, boolean subscribe){
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address, boolean subscribe){
if(!transactionGetters.containsKey(cryptoCoin)){
transactionGetters.put(cryptoCoin,new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet())));
}

View File

@ -31,6 +31,9 @@ public interface BitcoinAddressDao {
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'true' ")
long getLastChangeAddress(long accountId);
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'false' ")
long getLastExternalAddress(long accountId);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public long[] insertBitcoinAddresses(BitcoinAddress... addresses);
}

View File

@ -28,6 +28,7 @@ import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.ChildViewPager;
import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
@ -45,9 +46,17 @@ public class PatternSecurityFragment extends Fragment {
@BindView(R.id.tvPatternText)
TextView tvPatternText;
/*
* Contains the ChildViewPager to block the viewpager when the user is using the pattern control
* */
private ChildViewPager childViewPager;
private PatternLockViewListener actualPatternListener;
private String patternEntered;
public PatternSecurityFragment() {
// Required empty public constructor
}
@ -80,6 +89,11 @@ public class PatternSecurityFragment extends Fragment {
return patternString;
}
public void setChildViewPager(ChildViewPager childViewPager) {
this.childViewPager = childViewPager;
}
public void removePatternListener(){
if (actualPatternListener != null){
patternLockView.removePatternLockListener(actualPatternListener);
@ -96,7 +110,6 @@ public class PatternSecurityFragment extends Fragment {
actualPatternListener = new PatternLockViewListener() {
@Override
public void onStarted() {
}
@Override
@ -193,8 +206,8 @@ public class PatternSecurityFragment extends Fragment {
* */
tvPatternText.setText(getActivity().getResources().getString(R.string.Pattern_set_correctly));
tvPatternText.setTextColor(Color.GREEN);
final Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
final Timer t_ = new Timer();
t_.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
@ -203,7 +216,7 @@ public class PatternSecurityFragment extends Fragment {
@Override
public void run() {
t.cancel();
t_.cancel();
showNewPatternUI();
}
});

View File

@ -83,6 +83,11 @@ public class SecuritySettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_security_settings, container, false);
ButterKnife.bind(this, v);
/*
* For now this will not be implemented
* */
sPocketSecurity.setEnabled(false);
securityPagerAdapter = new SecurityPagerAdapter(getChildFragmentManager());
mPager.setAdapter(securityPagerAdapter);
@ -96,7 +101,6 @@ public class SecuritySettingsFragment extends Fragment {
default:
mPager.setCurrentItem(0);
}
mPager.setSwipeLocked(true);
TabLayout tabLayout = v.findViewById(R.id.tabs);
@ -134,7 +138,9 @@ public class SecuritySettingsFragment extends Fragment {
case 1:
return new PinSecurityFragment();
case 2:
return new PatternSecurityFragment();
final PatternSecurityFragment patternSecurityFragment = new PatternSecurityFragment();
patternSecurityFragment.setChildViewPager(mPager);
return patternSecurityFragment;
}
return null; //new OnConstructionFragment();

View File

@ -1,6 +1,5 @@
package cy.agorise.crystalwallet.manager;
import android.accounts.Account;
import android.content.Context;
import org.bitcoinj.core.Address;
@ -26,7 +25,6 @@ import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
import cy.agorise.crystalwallet.application.CrystalApplication;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.AccountSeed;
@ -37,11 +35,11 @@ import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GTxIO;
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
import cy.agorise.crystalwallet.requestmanagers.BitcoinSendRequest;
import cy.agorise.crystalwallet.requestmanagers.CreateBitcoinAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
import cy.agorise.crystalwallet.requestmanagers.GeneralAccountSendRequest;
import cy.agorise.crystalwallet.requestmanagers.NextBitcoinAccountAddressRequest;
import cy.agorise.graphenej.Util;
public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
@ -85,9 +83,14 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
@Override
public void onNewRequest(CryptoNetInfoRequest request) {
if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
if(request instanceof GeneralAccountSendRequest){
this.send((GeneralAccountSendRequest)request);
//if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
if(request.getCoin().equals(this.cryptoCoin)){
if(request instanceof BitcoinSendRequest) {
this.send((BitcoinSendRequest) request);
}else if(request instanceof CreateBitcoinAccountRequest){
}else if(request instanceof NextBitcoinAccountAddressRequest){
this.getNextAddress((NextBitcoinAccountAddressRequest) request);
}else{
System.out.println("Invalid " +this.cryptoCoin.getLabel() + " request ");
}
@ -255,7 +258,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance);
}
public void send(final GeneralAccountSendRequest request){
public void send(final BitcoinSendRequest request){
//TODO check server connection
//TODO validate to address
@ -271,19 +274,19 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
db.bitcoinTransactionDao();
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getAccount().getId(),db);
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(),db);
if(currentAmount< request.getAmount() + fee){
request.setStatus(GeneralAccountSendRequest.StatusCode.NO_BALANCE);
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
return;
}
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().getSeedId());
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.getAccount().getAccountIndex(), true));
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
@ -309,7 +312,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
//Change address
long remain = currentAmount - request.getAmount() - fee;
if( remain > 0 ) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getAccount().getId());
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr;
if(btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size()<=0){
@ -323,7 +326,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
}
btAddress = new BitcoinAddress();
btAddress.setIndex(index);
btAddress.setAccountId(request.getAccount().getId());
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);
@ -342,7 +345,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
if(btAddress.isChange()){
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
}else{
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), true));
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
}
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
}
@ -350,24 +353,51 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
InsightApiGenerator.broadcastTransaction(cryptoCoin,Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
request.setStatus(GeneralAccountSendRequest.StatusCode.SUCCEEDED);
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
request.setStatus(GeneralAccountSendRequest.StatusCode.PETITION_FAILED);
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
}
}));
}
@Override
public void fail(int idPetition) {
request.setStatus(GeneralAccountSendRequest.StatusCode.NO_FEE);
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
}
}));
}
private void getNextAddress(NextBitcoinAccountAddressRequest request){
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
long index = db.bitcoinAddressDao().getLastExternalAddress(request.getAccount().getId());
index++;
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().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.getAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
ECKey addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) index, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(false);
address.setAccountId(request.getAccount().getId());
address.setIndex(index);
String addressString =addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin,addressString,true);
request.setAddress(addressString);
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
}
private List<BitcoinTransactionGTxIO> getUtxos(long accountId, CrystalDatabase db){
List<BitcoinTransactionGTxIO> answer = new ArrayList<>();
List<BitcoinTransactionGTxIO> bTGTxI = new ArrayList<>();

View File

@ -21,6 +21,8 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
SUCCEEDED,
NO_INTERNET,
NO_SERVER_CONNECTION,
NO_BALANCE,
NO_FEE,
PETITION_FAILED
}

View File

@ -1,85 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
public class GeneralAccountSendRequest extends CryptoNetInfoRequest {
/**
* The status code of this request
*/
public enum StatusCode{
NOT_STARTED,
SUCCEEDED,
NO_INTERNET,
NO_SERVER_CONNECTION,
BAD_TO_ADDRESS,
NO_FEE,
NO_BALANCE,
PETITION_FAILED
}
// The app context
private Context mContext;
//The soruce Account
private CryptoNetAccount mAccount;
// The destination account address
private String mToAccount;
// The amount of the transaction
private long mAmount;
// The memo, can be null
private String mMemo;
// The state of this request
private StatusCode status = StatusCode.NOT_STARTED;
public GeneralAccountSendRequest(CryptoCoin coin, Context context, CryptoNetAccount account, String toAccount, long amount, String memo) {
super(coin);
this.mContext = context;
this.mAccount = account;
this.mToAccount = toAccount;
this.mAmount = amount;
this.mMemo = memo;
}
public GeneralAccountSendRequest(CryptoCoin coin, Context context, CryptoNetAccount account, String toAccount, long amount) {
this(coin,context,account,toAccount,amount,null);
}
public Context getContext() {
return mContext;
}
public CryptoNetAccount getAccount() {
return mAccount;
}
public String getToAccount() {
return mToAccount;
}
public long getAmount() {
return mAmount;
}
public String getMemo() {
return mMemo;
}
public void validate(){
if ((this.status != StatusCode.NOT_STARTED)){
this._fireOnCarryOutEvent();
}
}
public void setStatus(StatusCode code){
this.status = code;
this._fireOnCarryOutEvent();
}
public StatusCode getStatus() {
return status;
}
}

View File

@ -19,6 +19,8 @@ public class NextBitcoinAccountAddressRequest extends CryptoNetInfoRequest {
private CryptoCoin cryptoCoin;
private Context context;
private String address = null;
/**
* The status code of this request
*/
@ -62,4 +64,12 @@ public class NextBitcoinAccountAddressRequest extends CryptoNetInfoRequest {
public StatusCode getStatus() {
return status;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View File

@ -4,6 +4,10 @@ import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;
/**
* Created by xd on 1/18/18.
@ -14,36 +18,47 @@ import android.view.MotionEvent;
public class ChildViewPager extends ViewPager {
private boolean swipeLocked;
public ChildViewPager(Context context) {
super(context);
setMyScroller();
}
public ChildViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean getSwipeLocked() {
return swipeLocked;
}
public void setSwipeLocked(boolean swipeLocked) {
this.swipeLocked = swipeLocked;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return !swipeLocked && super.onTouchEvent(event);
// stop swipe
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return !swipeLocked && super.onInterceptTouchEvent(event);
// stop switching pages
return false;
}
@Override
public boolean canScrollHorizontally(int direction) {
return !swipeLocked && super.canScrollHorizontally(direction);
private void setMyScroller() {
try {
Class<?> viewpager = ViewPager.class;
Field scroller = viewpager.getDeclaredField("mScroller");
scroller.setAccessible(true);
scroller.set(this, new MyScroller(getContext()));
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyScroller extends Scroller {
public MyScroller(Context context) {
super(context, new DecelerateInterpolator());
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
}
}
}

View File

@ -101,6 +101,7 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
result = false
accountNameField.fieldValidatorModel.setInvalid()
accountNameField.fieldValidatorModel.message = this.accountNameField.resources.getString(R.string.create_account_window_err_at_least_one_character)
} else {
/*

View File

@ -21,4 +21,15 @@
android:layout_centerInParent="true"
android:background="@drawable/gradient"/>
<TextView
android:id="@+id/txtBadtry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/patternLockView"
android:text="@string/wrong_pin_wait"
android:layout_marginTop="5dp"
android:layout_centerHorizontal="true"
android:textColor="@color/red"
android:visibility="invisible"/>
</RelativeLayout>

View File

@ -91,6 +91,12 @@
<string name="save">SAVE</string>
<string name="next">NEXT</string>
<string name="ERROR_UNRECOGNIZABLE">An error ocurred attempting to import the account</string>
<string name="NO_ACCOUNT_DATA">The account does not have any data</string>
<string name="BAD_SEED">The seed is not valid</string>
<string name="ACCOUNT_DOESNT_EXIST">The account does not exists</string>
<string name="NO_SERVER_CONNECTION">There was an error with the connection. Try again later</string>
<string name="ASK_PERMISSION">A permission need to be granted before to continue</string>
<string name="please_enter_brainkey">Please enter brainkey</string>
@ -214,7 +220,7 @@
<string name="fee_capital">Fee</string>
<string name="ok">OK</string>
<string name="wrong_pin_wait">Wrong PIN you have to wait %% seconds ...</string>
<string name="wrong_pin_wait">Wrong match you have to wait %% seconds ...</string>
<string name="loading">Loading...</string>
<string name="pay_to">Pay to</string>