Merge remote-tracking branch 'origin/develop' into develop
# Conflicts: # app/build.gradle
This commit is contained in:
commit
64866632d2
41 changed files with 1396 additions and 457 deletions
|
@ -1,6 +1,8 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
apply plugin: 'kotlin-kapt' // add this line
|
||||||
|
|
||||||
|
|
||||||
kapt {
|
kapt {
|
||||||
generateStubs = true
|
generateStubs = true
|
||||||
|
@ -15,8 +17,8 @@ android {
|
||||||
applicationId "cy.agorise.crystalwallet"
|
applicationId "cy.agorise.crystalwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 4
|
versionCode 3
|
||||||
versionName "0.4M.alpha"
|
versionName "0.3M.alpha"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary true
|
useSupportLibrary true
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.NFC" />
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".application.CrystalApplication"
|
android:name=".application.CrystalApplication"
|
||||||
|
|
|
@ -43,6 +43,14 @@ public class AccountSettingsActivity extends AppCompatActivity{
|
||||||
@BindView(R.id.tvBuildVersion)
|
@BindView(R.id.tvBuildVersion)
|
||||||
public TextView tvBuildVersion;
|
public TextView tvBuildVersion;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the window animation
|
||||||
|
* */
|
||||||
|
private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -57,7 +65,7 @@ public class AccountSettingsActivity extends AppCompatActivity{
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||||
//Log.d(TAG,"surfaceCreated");
|
//Log.d(TAG,"surfaceCreated");
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(AccountSettingsActivity.this, R.raw.appbar_background);
|
mediaPlayer = MediaPlayer.create(AccountSettingsActivity.this, R.raw.appbar_background);
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
||||||
mediaPlayer.setLooping(true);
|
mediaPlayer.setLooping(true);
|
||||||
mediaPlayer.start();
|
mediaPlayer.start();
|
||||||
|
@ -83,6 +91,19 @@ public class AccountSettingsActivity extends AppCompatActivity{
|
||||||
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager));
|
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
//Release the media player
|
||||||
|
if(mediaPlayer!=null){
|
||||||
|
mediaPlayer.release();
|
||||||
|
mediaPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class SettingsPagerAdapter extends FragmentStatePagerAdapter {
|
private class SettingsPagerAdapter extends FragmentStatePagerAdapter {
|
||||||
SettingsPagerAdapter(FragmentManager fm) {
|
SettingsPagerAdapter(FragmentManager fm) {
|
||||||
super(fm);
|
super(fm);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
@ -34,6 +35,7 @@ public class BackupSeedActivity extends AppCompatActivity {
|
||||||
@BindView(R.id.btnCopy)
|
@BindView(R.id.btnCopy)
|
||||||
Button btnCopy;
|
Button btnCopy;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -41,6 +43,15 @@ public class BackupSeedActivity extends AppCompatActivity {
|
||||||
|
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If comes from new account creation hide the cancel button
|
||||||
|
* */
|
||||||
|
Bundle b = getIntent().getExtras();
|
||||||
|
boolean newAccount = b.getBoolean("newAccount");
|
||||||
|
if(newAccount ){
|
||||||
|
btnOk.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
long seedId = getIntent().getLongExtra("SEED_ID",-1);
|
long seedId = getIntent().getLongExtra("SEED_ID",-1);
|
||||||
|
|
||||||
if (seedId > -1) {
|
if (seedId > -1) {
|
||||||
|
|
|
@ -98,6 +98,14 @@ public class BoardActivity extends CustomActivity {
|
||||||
|
|
||||||
File photoDirectory;
|
File photoDirectory;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the window animation
|
||||||
|
* */
|
||||||
|
private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -170,7 +178,7 @@ public class BoardActivity extends CustomActivity {
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||||
//Log.d(TAG,"surfaceCreated");
|
//Log.d(TAG,"surfaceCreated");
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(BoardActivity.this, R.raw.appbar_background);
|
mediaPlayer = MediaPlayer.create(BoardActivity.this, R.raw.appbar_background);
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
||||||
mediaPlayer.setLooping(true);
|
mediaPlayer.setLooping(true);
|
||||||
mediaPlayer.start();
|
mediaPlayer.start();
|
||||||
|
@ -271,6 +279,17 @@ public class BoardActivity extends CustomActivity {
|
||||||
loadUserImage();
|
loadUserImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
//Release the media player
|
||||||
|
if(mediaPlayer!=null){
|
||||||
|
mediaPlayer.release();
|
||||||
|
mediaPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void loadUserImage(){
|
public void loadUserImage(){
|
||||||
//Search for a existing photo
|
//Search for a existing photo
|
||||||
File photoFile = new File(photoDirectory + File.separator + "photo.png");
|
File photoFile = new File(photoDirectory + File.separator + "photo.png");
|
||||||
|
|
|
@ -200,6 +200,7 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
val intent = Intent(applicationContext, BackupSeedActivity::class.java)
|
val intent = Intent(applicationContext, BackupSeedActivity::class.java)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
intent.putExtra("SEED_ID", accountSeed.id)
|
intent.putExtra("SEED_ID", accountSeed.id)
|
||||||
|
intent.putExtra("newAccount", true)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
else if (request.status == ValidateCreateBitsharesAccountRequest.StatusCode.ACCOUNT_EXIST) {
|
else if (request.status == ValidateCreateBitsharesAccountRequest.StatusCode.ACCOUNT_EXIST) {
|
||||||
|
|
|
@ -56,6 +56,14 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
|
||||||
|
|
||||||
private CryptoNetAccount cryptoNetAccount;
|
private CryptoNetAccount cryptoNetAccount;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the window animation
|
||||||
|
* */
|
||||||
|
private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -98,7 +106,7 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||||
//Log.d(TAG,"surfaceCreated");
|
//Log.d(TAG,"surfaceCreated");
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(CryptoNetAccountSettingsActivity.this, R.raw.appbar_background);
|
mediaPlayer = MediaPlayer.create(CryptoNetAccountSettingsActivity.this, R.raw.appbar_background);
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
||||||
mediaPlayer.setLooping(true);
|
mediaPlayer.setLooping(true);
|
||||||
mediaPlayer.start();
|
mediaPlayer.start();
|
||||||
|
@ -121,6 +129,19 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
//Release the media player
|
||||||
|
if(mediaPlayer!=null){
|
||||||
|
mediaPlayer.release();
|
||||||
|
mediaPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class SettingsPagerAdapter extends FragmentStatePagerAdapter {
|
private class SettingsPagerAdapter extends FragmentStatePagerAdapter {
|
||||||
SettingsPagerAdapter(FragmentManager fm) {
|
SettingsPagerAdapter(FragmentManager fm) {
|
||||||
super(fm);
|
super(fm);
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package cy.agorise.crystalwallet.activities;
|
package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
@ -14,6 +16,7 @@ import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.CrystalLoading;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
|
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
|
||||||
|
@ -53,6 +56,8 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
@BindView(R.id.btnCancel)
|
@BindView(R.id.btnCancel)
|
||||||
Button btnCancel;
|
Button btnCancel;
|
||||||
|
|
||||||
|
final Activity activity = this;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -60,12 +65,136 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
|
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
btnImport.setEnabled(false);
|
/*
|
||||||
|
* Initially the button CREATE WALLET should be disabled
|
||||||
|
* */
|
||||||
|
disableCreate();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a text change in any of the fields
|
||||||
|
* */
|
||||||
|
etPin.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
* */
|
||||||
|
if(allFieldsAreFill()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
etPinConfirmation.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
* */
|
||||||
|
if(allFieldsAreFill()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
etSeedWords.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
* */
|
||||||
|
if(allFieldsAreFill()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
etAccountName.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
* */
|
||||||
|
if(allFieldsAreFill()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class);
|
accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class);
|
||||||
importSeedValidator = new ImportSeedValidator(this.getApplicationContext(),etPin,etPinConfirmation,etAccountName,etSeedWords);
|
importSeedValidator = new ImportSeedValidator(this.getApplicationContext(),etPin,etPinConfirmation,etAccountName,etSeedWords);
|
||||||
importSeedValidator.setListener(this);
|
importSeedValidator.setListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to validate if all the fields are fill
|
||||||
|
* */
|
||||||
|
private boolean allFieldsAreFill(){
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return complete;
|
||||||
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etPin,
|
@OnTextChanged(value = R.id.etPin,
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||||
void afterPinChanged(Editable editable) {
|
void afterPinChanged(Editable editable) {
|
||||||
|
@ -102,12 +231,25 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
|
|
||||||
if (this.importSeedValidator.isValid()) {
|
if (this.importSeedValidator.isValid()) {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loading dialog
|
||||||
|
* */
|
||||||
|
final CrystalLoading crystalLoading = new CrystalLoading(activity);
|
||||||
|
crystalLoading.show();
|
||||||
|
|
||||||
final ValidateImportBitsharesAccountRequest validatorRequest =
|
final ValidateImportBitsharesAccountRequest validatorRequest =
|
||||||
new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
|
new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
|
||||||
|
|
||||||
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
|
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCarryOut() {
|
public void onCarryOut() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hide the loading dialog
|
||||||
|
* */
|
||||||
|
crystalLoading.dismiss();
|
||||||
|
|
||||||
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
|
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
|
||||||
String errorText = "An error ocurred attempting to import the account";
|
String errorText = "An error ocurred attempting to import the account";
|
||||||
|
|
||||||
|
@ -182,9 +324,9 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.importSeedValidator.isValid()){
|
if (activity.importSeedValidator.isValid()){
|
||||||
btnImport.setEnabled(true);
|
enableCreate();
|
||||||
} else {
|
} else {
|
||||||
btnImport.setEnabled(false);
|
disableCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -203,4 +345,31 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
//tvSeedWordsError.setText(field.getMessage());
|
//tvSeedWordsError.setText(field.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable create button
|
||||||
|
* */
|
||||||
|
private void enableCreate() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
btnImport.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
||||||
|
btnImport.setEnabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable create button
|
||||||
|
* */
|
||||||
|
private void disableCreate() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
btnImport.setEnabled(false);
|
||||||
|
btnImport.setBackground(getDrawable(R.drawable.disable_style));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
@ -52,6 +54,14 @@ public class IntroActivity extends CustomActivity {
|
||||||
@BindView(R.id.btnImportAccount)
|
@BindView(R.id.btnImportAccount)
|
||||||
public Button btnImportAccount;
|
public Button btnImportAccount;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the window animation
|
||||||
|
* */
|
||||||
|
private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -64,7 +74,7 @@ public class IntroActivity extends CustomActivity {
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||||
//Log.d(TAG,"surfaceCreated");
|
//Log.d(TAG,"surfaceCreated");
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(IntroActivity.this, R.raw.appbar_background);
|
mediaPlayer = MediaPlayer.create(IntroActivity.this, R.raw.appbar_background);
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
||||||
mediaPlayer.setLooping(true);
|
mediaPlayer.setLooping(true);
|
||||||
mediaPlayer.start();
|
mediaPlayer.start();
|
||||||
|
@ -146,6 +156,17 @@ public class IntroActivity extends CustomActivity {
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
//Release the media player
|
||||||
|
if(mediaPlayer!=null){
|
||||||
|
mediaPlayer.release();
|
||||||
|
mediaPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btnImportAccount)
|
@OnClick(R.id.btnImportAccount)
|
||||||
public void importAccount() {
|
public void importAccount() {
|
||||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||||
|
|
|
@ -71,7 +71,8 @@ public class PatternRequestActivity extends AppCompatActivity {
|
||||||
public void onComplete(List<PatternLockView.Dot> pattern) {
|
public void onComplete(List<PatternLockView.Dot> pattern) {
|
||||||
if (PasswordManager.checkPassword(patternEncrypted,patternToString(pattern))){
|
if (PasswordManager.checkPassword(patternEncrypted,patternToString(pattern))){
|
||||||
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
|
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
|
||||||
CrystalSecurityMonitor.getInstance(null).call2ndFactor(thisActivity);
|
//CrystalSecurityMonitor.getInstance(null).call2ndFactor(thisActivity);
|
||||||
|
thisActivity.finish();
|
||||||
} else {
|
} else {
|
||||||
thisActivity.finish();
|
thisActivity.finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
@ -62,6 +63,9 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
|
||||||
//@BindView(R.id.btnCancel)
|
//@BindView(R.id.btnCancel)
|
||||||
Button btnCancel;
|
Button btnCancel;
|
||||||
|
|
||||||
|
@BindView(R.id.fabCloseCamera)
|
||||||
|
FloatingActionButton btnCloseCamera;
|
||||||
|
|
||||||
private long cryptoNetAccountId;
|
private long cryptoNetAccountId;
|
||||||
private CryptoNetAccount cryptoNetAccount;
|
private CryptoNetAccount cryptoNetAccount;
|
||||||
private GrapheneAccount grapheneAccount;
|
private GrapheneAccount grapheneAccount;
|
||||||
|
@ -146,6 +150,15 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
|
||||||
this.finish();
|
this.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@OnClick(R.id.fabCloseCamera)
|
||||||
|
public void onClicCloseCamera(){
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//@OnClick(R.id.btnSend)
|
//@OnClick(R.id.btnSend)
|
||||||
public void importSend(){
|
public void importSend(){
|
||||||
if (this.sendTransactionValidator.isValid()) {
|
if (this.sendTransactionValidator.isValid()) {
|
||||||
|
|
|
@ -50,6 +50,14 @@ public class SettingsActivity extends AppCompatActivity{
|
||||||
|
|
||||||
private SecuritySettingsFragment securitySettingsFragment;
|
private SecuritySettingsFragment securitySettingsFragment;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the window animation
|
||||||
|
* */
|
||||||
|
private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -64,7 +72,7 @@ public class SettingsActivity extends AppCompatActivity{
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||||
//Log.d(TAG,"surfaceCreated");
|
//Log.d(TAG,"surfaceCreated");
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(SettingsActivity.this, R.raw.appbar_background);
|
mediaPlayer = MediaPlayer.create(SettingsActivity.this, R.raw.appbar_background);
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
||||||
mediaPlayer.setLooping(true);
|
mediaPlayer.setLooping(true);
|
||||||
mediaPlayer.start();
|
mediaPlayer.start();
|
||||||
|
@ -123,6 +131,17 @@ public class SettingsActivity extends AppCompatActivity{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
//Release the media player
|
||||||
|
if(mediaPlayer != null){
|
||||||
|
mediaPlayer.release();
|
||||||
|
mediaPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OnClick(R.id.ivGoBack)
|
@OnClick(R.id.ivGoBack)
|
||||||
public void goBack(){
|
public void goBack(){
|
||||||
onBackPressed();
|
onBackPressed();
|
||||||
|
|
|
@ -1,47 +1,74 @@
|
||||||
package cy.agorise.crystalwallet.apigenerator;
|
package cy.agorise.crystalwallet.apigenerator;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.apigenerator.insightapi.AddressesActivityWatcher;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.GetEstimateFee;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.GetEstimateFee;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionByAddress;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionByAddress;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionData;
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.enums.CryptoNet;
|
|
||||||
import cy.agorise.crystalwallet.network.CryptoNetManager;
|
import cy.agorise.crystalwallet.network.CryptoNetManager;
|
||||||
|
|
||||||
public class InsightApiGenerator {
|
public class InsightApiGenerator {
|
||||||
|
|
||||||
private static HashMap<CryptoNet,BroadcastTransaction> broadcaster = new HashMap();
|
private static HashMap<CryptoCoin,GetTransactionByAddress> transactionGetters = new HashMap();
|
||||||
private static HashMap<CryptoNet,GetTransactionByAddress> transactionGetters = new HashMap();
|
private static HashMap<CryptoCoin,AddressesActivityWatcher> transactionFollowers = new HashMap();
|
||||||
private static HashMap<CryptoNet,GetTransactionData> transacitonFollowers = new HashMap();
|
|
||||||
|
|
||||||
public static void getTransactionFromAddress(CryptoNet cryptoNet, String address,
|
/**
|
||||||
ApiRequest request, Context context,
|
* Fecth all the transaciton for a giving address
|
||||||
boolean subscribe){
|
* @param cryptoCoin the crypto net of the address
|
||||||
if(!transactionGetters.containsKey(cryptoNet)){
|
* @param address The address String
|
||||||
//TODO change this line
|
* @param request the request api to response
|
||||||
transactionGetters.put(cryptoNet,new GetTransactionByAddress(null,CryptoNetManager.getURL(cryptoNet),context));
|
* @param subscribe If needs to follow the address (Real time)
|
||||||
|
*/
|
||||||
|
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address,
|
||||||
|
ApiRequest request, boolean subscribe){
|
||||||
|
if(!transactionGetters.containsKey(cryptoCoin)){
|
||||||
|
transactionGetters.put(cryptoCoin,new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet())));
|
||||||
}
|
}
|
||||||
|
transactionGetters.get(cryptoCoin).addAddress(address);
|
||||||
|
transactionGetters.get(cryptoCoin).start();
|
||||||
|
if(subscribe){
|
||||||
|
if(!transactionFollowers.containsKey(cryptoCoin)){
|
||||||
|
transactionFollowers.put(cryptoCoin,new AddressesActivityWatcher(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),cryptoCoin));
|
||||||
}
|
}
|
||||||
|
transactionFollowers.get(cryptoCoin).addAddress(address);
|
||||||
public static void followTransaction(CryptoNet cryptoNet, String txid, Context context){
|
transactionFollowers.get(cryptoCoin).connect();
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void broadcastTransaction(CryptoNet cryptoNet, String rawtx, ApiRequest request){
|
|
||||||
if(!broadcaster.containsKey(cryptoNet)){
|
|
||||||
//TODO change to multiple broadcast
|
|
||||||
broadcaster.put(cryptoNet,new BroadcastTransaction(rawtx,null,
|
|
||||||
CryptoNetManager.getURL(cryptoNet),null));
|
|
||||||
broadcaster.get(cryptoNet).start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getEstimateFee(CryptoNet cryptoNet, final ApiRequest request){
|
/**
|
||||||
GetEstimateFee.getEstimateFee(CryptoNetManager.getURL(cryptoNet), new GetEstimateFee.estimateFeeListener() {
|
* Broadcast an insight api transaction
|
||||||
|
* @param cryptoCoin The cryptoNet of the transaction
|
||||||
|
* @param rawtx the transaction to be broadcasted
|
||||||
|
*/
|
||||||
|
public static void broadcastTransaction(CryptoCoin cryptoCoin, String rawtx, final ApiRequest request){
|
||||||
|
BroadcastTransaction bTransaction = new BroadcastTransaction(rawtx,
|
||||||
|
CryptoNetManager.getURL(cryptoCoin.getCryptoNet()), "api", new BroadcastTransaction.BroadCastTransactionListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
request.getListener().success(true,request.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(String msg) {
|
||||||
|
request.getListener().fail(request.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnecitonFailure() {
|
||||||
|
request.getListener().fail(request.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
bTransaction.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the estimated fee for a transaction
|
||||||
|
*/
|
||||||
|
public static void getEstimateFee(CryptoCoin cryptoCoin, final ApiRequest request){
|
||||||
|
GetEstimateFee.getEstimateFee(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),
|
||||||
|
new GetEstimateFee.estimateFeeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void estimateFee(long value) {
|
public void estimateFee(long value) {
|
||||||
request.listener.success(value,request.getId());
|
request.listener.success(value,request.getId());
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
||||||
import io.socket.client.IO;
|
import io.socket.client.IO;
|
||||||
import io.socket.client.Socket;
|
import io.socket.client.Socket;
|
||||||
|
@ -24,12 +25,9 @@ import io.socket.emitter.Emitter;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AccountActivityWatcher {
|
public class AddressesActivityWatcher {
|
||||||
|
|
||||||
/**
|
private final CryptoCoin cryptoCoin;
|
||||||
* The mAccount to be monitor
|
|
||||||
*/
|
|
||||||
private final GeneralCoinAccount mAccount;
|
|
||||||
/**
|
/**
|
||||||
* The list of address to monitor
|
* The list of address to monitor
|
||||||
*/
|
*/
|
||||||
|
@ -38,10 +36,6 @@ public class AccountActivityWatcher {
|
||||||
* the Socket.IO
|
* the Socket.IO
|
||||||
*/
|
*/
|
||||||
private Socket mSocket;
|
private Socket mSocket;
|
||||||
/**
|
|
||||||
* This app mContext, used to save on the DB
|
|
||||||
*/
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
private final String mServerUrl;
|
private final String mServerUrl;
|
||||||
|
|
||||||
|
@ -55,9 +49,9 @@ public class AccountActivityWatcher {
|
||||||
try {
|
try {
|
||||||
System.out.println("Receive accountActivtyWatcher " + os[0].toString() );
|
System.out.println("Receive accountActivtyWatcher " + os[0].toString() );
|
||||||
String txid = ((JSONObject) os[0]).getString(InsightApiConstants.sTxTag);
|
String txid = ((JSONObject) os[0]).getString(InsightApiConstants.sTxTag);
|
||||||
new GetTransactionData(txid, mAccount, mServerUrl, mContext).start();
|
new GetTransactionData(txid, mServerUrl, cryptoCoin).start();
|
||||||
} catch (JSONException ex) {
|
} catch (JSONException ex) {
|
||||||
Logger.getLogger(AccountActivityWatcher.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(AddressesActivityWatcher.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -84,7 +78,9 @@ public class AccountActivityWatcher {
|
||||||
private final Emitter.Listener onDisconnect = new Emitter.Listener() {
|
private final Emitter.Listener onDisconnect = new Emitter.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void call(Object... os) {
|
public void call(Object... os) {
|
||||||
System.out.println("Disconnected to accountActivityWatcher");
|
try {
|
||||||
|
Thread.sleep(60000);
|
||||||
|
} catch (InterruptedException ignore) {}
|
||||||
mSocket.connect();
|
mSocket.connect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -99,19 +95,20 @@ public class AccountActivityWatcher {
|
||||||
for(Object ob : os) {
|
for(Object ob : os) {
|
||||||
System.out.println("accountActivityWatcher " + ob.toString());
|
System.out.println("accountActivityWatcher " + ob.toString());
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(60000);
|
||||||
|
} catch (InterruptedException ignore) {}
|
||||||
|
mSocket.connect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic constructor
|
* Basic constructor
|
||||||
*
|
*
|
||||||
* @param mAccount The mAccount to be monitor
|
|
||||||
* @param mContext This app mContext
|
|
||||||
*/
|
*/
|
||||||
public AccountActivityWatcher(String serverUrl, GeneralCoinAccount mAccount, Context mContext) {
|
public AddressesActivityWatcher(String serverUrl, CryptoCoin cryptoCoin) {
|
||||||
this.mServerUrl = serverUrl;
|
this.mServerUrl = serverUrl;
|
||||||
this.mAccount = mAccount;
|
this.cryptoCoin = cryptoCoin;
|
||||||
this.mContext = mContext;
|
|
||||||
try {
|
try {
|
||||||
this.mSocket = IO.socket(serverUrl);
|
this.mSocket = IO.socket(serverUrl);
|
||||||
this.mSocket.on(Socket.EVENT_CONNECT, onConnect);
|
this.mSocket.on(Socket.EVENT_CONNECT, onConnect);
|
||||||
|
@ -141,13 +138,11 @@ public class AccountActivityWatcher {
|
||||||
* Connects the Socket
|
* Connects the Socket
|
||||||
*/
|
*/
|
||||||
public void connect() {
|
public void connect() {
|
||||||
//TODO change to use log
|
|
||||||
System.out.println("accountActivityWatcher connecting");
|
|
||||||
try{
|
try{
|
||||||
|
if(this.mSocket == null || !this.mSocket.connected()) {
|
||||||
this.mSocket.connect();
|
this.mSocket.connect();
|
||||||
}catch(Exception e){
|
}
|
||||||
//TODO change exception handler
|
}catch(Exception ignore){
|
||||||
System.out.println("accountActivityWatcher exception " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,29 +22,21 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
* The serviceGenerator to call
|
* The serviceGenerator to call
|
||||||
*/
|
*/
|
||||||
private InsightApiServiceGenerator mServiceGenerator;
|
private InsightApiServiceGenerator mServiceGenerator;
|
||||||
/**
|
|
||||||
* This app context, used to save on the DB
|
|
||||||
*/
|
|
||||||
private Context mContext;
|
|
||||||
/**
|
|
||||||
* The account who sign the transaction
|
|
||||||
*/
|
|
||||||
private GeneralCoinAccount mAccount;
|
|
||||||
|
|
||||||
private String serverUrl;
|
private String mPath;
|
||||||
|
|
||||||
|
private BroadCastTransactionListener listener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic Consturctor
|
* Basic Consturctor
|
||||||
* @param RawTx The RawTX in Hex String
|
* @param RawTx The RawTX in Hex String
|
||||||
* @param account The account who signs the transaction
|
*
|
||||||
* @param context This app context
|
|
||||||
*/
|
*/
|
||||||
public BroadcastTransaction(String RawTx, GeneralCoinAccount account, String serverUrl, Context context){
|
public BroadcastTransaction(String RawTx, String serverUrl, String path, BroadCastTransactionListener listener){
|
||||||
this.serverUrl = serverUrl;
|
|
||||||
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
||||||
this.mContext = context;
|
|
||||||
this.mRawTx = RawTx;
|
this.mRawTx = RawTx;
|
||||||
this.mAccount = account;
|
this.listener = listener;
|
||||||
|
this.mPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,13 +46,9 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
//TODO invalidated send
|
listener.onSuccess();
|
||||||
//TODO call getTransactionData
|
|
||||||
GetTransactionData trData = new GetTransactionData(response.body().txid,this.mAccount, this.serverUrl, this.mContext);
|
|
||||||
trData.start();
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println("SENDTEST: not succesful " + response.message());
|
listener.onFailure(response.message());
|
||||||
//TODO change how to handle invalid transaction
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +57,7 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<Txi> call, Throwable t) {
|
public void onFailure(Call<Txi> call, Throwable t) {
|
||||||
//TODO change how to handle invalid transaction
|
listener.onConnecitonFailure();
|
||||||
System.out.println("SENDTEST: sendError " + t.getMessage() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +66,13 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
||||||
Call<Txi> broadcastTransaction = service.broadcastTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),this.mRawTx);
|
Call<Txi> broadcastTransaction = service.broadcastTransaction(this.mPath,this.mRawTx);
|
||||||
broadcastTransaction.enqueue(this);
|
broadcastTransaction.enqueue(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface BroadCastTransactionListener{
|
||||||
|
void onSuccess();
|
||||||
|
void onFailure(String msg);
|
||||||
|
void onConnecitonFailure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,21 @@ package cy.agorise.crystalwallet.apigenerator.insightapi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.idescout.sql.SqlScoutServer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.AddressTxi;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.AddressTxi;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
import cy.agorise.crystalwallet.manager.GeneralAccountManager;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoCurrency;
|
||||||
import cy.agorise.crystalwallet.models.GTxIO;
|
import cy.agorise.crystalwallet.models.GTxIO;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
||||||
|
@ -25,43 +32,34 @@ import retrofit2.Response;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GetTransactionByAddress extends Thread implements Callback<AddressTxi> {
|
public class GetTransactionByAddress extends Thread implements Callback<AddressTxi> {
|
||||||
/**
|
|
||||||
* The account to be query
|
|
||||||
*/
|
|
||||||
private GeneralCoinAccount mAccount;
|
|
||||||
/**
|
/**
|
||||||
* The list of address to query
|
* The list of address to query
|
||||||
*/
|
*/
|
||||||
private List<GeneralCoinAddress> mAddresses = new ArrayList<>();
|
private List<String> mAddresses = new ArrayList<>();
|
||||||
/**
|
/**
|
||||||
* The serviceGenerator to call
|
* The serviceGenerator to call
|
||||||
*/
|
*/
|
||||||
private InsightApiServiceGenerator mServiceGenerator;
|
private InsightApiServiceGenerator mServiceGenerator;
|
||||||
/**
|
|
||||||
* This app context, used to save on the DB
|
|
||||||
*/
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
private String serverUrl;
|
private String serverUrl;
|
||||||
|
private CryptoCoin cryptoNet;
|
||||||
|
|
||||||
|
private boolean inProcess = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic consturcotr
|
* Basic consturcotr
|
||||||
* @param account The account to be query
|
|
||||||
* @param context This app context
|
|
||||||
*/
|
*/
|
||||||
public GetTransactionByAddress(GeneralCoinAccount account, String serverUrl, Context context) {
|
public GetTransactionByAddress(CryptoCoin cryptoNet, String serverUrl) {
|
||||||
|
this.cryptoNet = cryptoNet;
|
||||||
this.serverUrl = serverUrl;
|
this.serverUrl = serverUrl;
|
||||||
this.mAccount = account;
|
|
||||||
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
||||||
this.mContext = context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add an address to be query
|
* add an address to be query
|
||||||
* @param address the address to be query
|
* @param address the address to be query
|
||||||
*/
|
*/
|
||||||
public void addAddress(GeneralCoinAddress address) {
|
public void addAddress(String address) {
|
||||||
this.mAddresses.add(address);
|
this.mAddresses.add(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,110 +71,15 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<AddressTxi> call, Response<AddressTxi> response) {
|
public void onResponse(Call<AddressTxi> call, Response<AddressTxi> response) {
|
||||||
|
inProcess = false;
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
AddressTxi addressTxi = response.body();
|
AddressTxi addressTxi = response.body();
|
||||||
|
|
||||||
for (Txi txi : addressTxi.items) {
|
for (Txi txi : addressTxi.items) {
|
||||||
GeneralCoinAccount tempAccount = null;
|
GeneralAccountManager.getAccountManager(this.cryptoNet).processTxi(txi);
|
||||||
GeneralTransaction transaction = new GeneralTransaction();
|
|
||||||
transaction.setAccount(this.mAccount);
|
|
||||||
transaction.setTxid(txi.txid);
|
|
||||||
transaction.setBlock(txi.blockheight);
|
|
||||||
transaction.setDate(new Date(txi.time * 1000));
|
|
||||||
transaction.setFee((long) (txi.fee * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
transaction.setConfirm(txi.confirmations);
|
|
||||||
transaction.setType(this.mAccount.getCryptoCoin());
|
|
||||||
transaction.setBlockHeight(txi.blockheight);
|
|
||||||
|
|
||||||
for (Vin vin : txi.vin) {
|
|
||||||
GTxIO input = new GTxIO();
|
|
||||||
input.setAmount((long) (vin.value * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
input.setTransaction(transaction);
|
|
||||||
input.setOut(true);
|
|
||||||
input.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vin.addr;
|
|
||||||
input.setAddressString(addr);
|
|
||||||
input.setIndex(vin.n);
|
|
||||||
input.setScriptHex(vin.scriptSig.hex);
|
|
||||||
input.setOriginalTxid(vin.txid);
|
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
input.setAddress(address);
|
|
||||||
tempAccount = address.getAccount();
|
|
||||||
|
|
||||||
if (!address.hasTransactionOutput(input, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionOutput().add(input);
|
|
||||||
}
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transaction.getTxInputs().add(input);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Vout vout : txi.vout) {
|
|
||||||
if(vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0){
|
|
||||||
// The address is null, this must be a memo
|
|
||||||
String hex = vout.scriptPubKey.hex;
|
|
||||||
int opReturnIndex = hex.indexOf("6a");
|
|
||||||
if(opReturnIndex >= 0) {
|
|
||||||
byte[] memoBytes = new byte[Integer.parseInt(hex.substring(opReturnIndex+2,opReturnIndex+4),16)];
|
|
||||||
for(int i = 0; i < memoBytes.length;i++){
|
|
||||||
memoBytes[i] = Byte.parseByte(hex.substring(opReturnIndex+4+(i*2),opReturnIndex+6+(i*2)),16);
|
|
||||||
}
|
|
||||||
transaction.setMemo(new String(memoBytes));
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
GTxIO output = new GTxIO();
|
|
||||||
output.setAmount((long) (vout.value * Math.pow(10, this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
output.setTransaction(transaction);
|
|
||||||
output.setOut(false);
|
|
||||||
output.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vout.scriptPubKey.addresses[0];
|
|
||||||
output.setAddressString(addr);
|
|
||||||
output.setIndex(vout.n);
|
|
||||||
output.setScriptHex(vout.scriptPubKey.hex);
|
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
output.setAddress(address);
|
|
||||||
tempAccount = address.getAccount();
|
|
||||||
|
|
||||||
if (!address.hasTransactionInput(output, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionInput().add(output);
|
|
||||||
}
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.getTxOutputs().add(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(txi.txlock && txi.confirmations< this.mAccount.getCryptoNet().getConfirmationsNeeded()){
|
|
||||||
transaction.setConfirm(this.mAccount.getCryptoNet().getConfirmationsNeeded());
|
|
||||||
}
|
|
||||||
//TODO database
|
|
||||||
/*SCWallDatabase db = new SCWallDatabase(this.mContext);
|
|
||||||
long idTransaction = db.getGeneralTransactionId(transaction);
|
|
||||||
if (idTransaction == -1) {
|
|
||||||
db.putGeneralTransaction(transaction);
|
|
||||||
} else {
|
|
||||||
transaction.setId(idTransaction);
|
|
||||||
db.updateGeneralTransaction(transaction);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (tempAccount != null && transaction.getConfirm() < this.mAccount.getCryptoNet().getConfirmationsNeeded()) {
|
|
||||||
new GetTransactionData(transaction.getTxid(), tempAccount, this.serverUrl, this.mContext, true).start();
|
|
||||||
}
|
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
|
||||||
if (address.updateTransaction(transaction)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(changed) {
|
|
||||||
this.mAccount.balanceChange();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +90,7 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<AddressTxi> call, Throwable t) {
|
public void onFailure(Call<AddressTxi> call, Throwable t) {
|
||||||
|
inProcess = false;
|
||||||
Log.e("GetTransactionByAddress", "Error in json format");
|
Log.e("GetTransactionByAddress", "Error in json format");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,14 +99,15 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (this.mAddresses.size() > 0) {
|
if (this.mAddresses.size() > 0 && !inProcess) {
|
||||||
|
inProcess = true;
|
||||||
StringBuilder addressToQuery = new StringBuilder();
|
StringBuilder addressToQuery = new StringBuilder();
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
for (String address : this.mAddresses) {
|
||||||
addressToQuery.append(address.getAddressString(this.mAccount.getNetworkParam())).append(",");
|
addressToQuery.append(address).append(",");
|
||||||
}
|
}
|
||||||
addressToQuery.deleteCharAt(addressToQuery.length() - 1);
|
addressToQuery.deleteCharAt(addressToQuery.length() - 1);
|
||||||
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
||||||
Call<AddressTxi> addressTxiCall = service.getTransactionByAddress(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),addressToQuery.toString());
|
Call<AddressTxi> addressTxiCall = service.getTransactionByAddress(this.serverUrl,addressToQuery.toString());
|
||||||
addressTxiCall.enqueue(this);
|
addressTxiCall.enqueue(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Date;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.manager.GeneralAccountManager;
|
||||||
import cy.agorise.crystalwallet.models.GTxIO;
|
import cy.agorise.crystalwallet.models.GTxIO;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
||||||
|
@ -20,10 +22,6 @@ import retrofit2.Response;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GetTransactionData extends Thread implements Callback<Txi> {
|
public class GetTransactionData extends Thread implements Callback<Txi> {
|
||||||
/**
|
|
||||||
* The account to be query
|
|
||||||
*/
|
|
||||||
private final GeneralCoinAccount mAccount;
|
|
||||||
/**
|
/**
|
||||||
* The transaction txid to be query
|
* The transaction txid to be query
|
||||||
*/
|
*/
|
||||||
|
@ -32,10 +30,6 @@ public class GetTransactionData extends Thread implements Callback<Txi> {
|
||||||
* The serviceGenerator to call
|
* The serviceGenerator to call
|
||||||
*/
|
*/
|
||||||
private InsightApiServiceGenerator mServiceGenerator;
|
private InsightApiServiceGenerator mServiceGenerator;
|
||||||
/**
|
|
||||||
* This app context, used to save on the DB
|
|
||||||
*/
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
private String mServerUrl;
|
private String mServerUrl;
|
||||||
/**
|
/**
|
||||||
|
@ -43,30 +37,28 @@ public class GetTransactionData extends Thread implements Callback<Txi> {
|
||||||
*/
|
*/
|
||||||
private boolean mMustWait = false;
|
private boolean mMustWait = false;
|
||||||
|
|
||||||
|
private CryptoCoin cryptoCoin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used to query for a transaction with unknown confirmations
|
* Constructor used to query for a transaction with unknown confirmations
|
||||||
* @param txid The txid of the transaciton to be query
|
* @param txid The txid of the transaciton to be query
|
||||||
* @param account The account to be query
|
|
||||||
* @param context This app Context
|
|
||||||
*/
|
*/
|
||||||
public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context) {
|
public GetTransactionData(String txid, String serverUrl, CryptoCoin cryptoCoin) {
|
||||||
this(txid, account, serverUrl, context, false);
|
this(txid, serverUrl, cryptoCoin, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consturctor to be used qhen the confirmations of the transaction are known
|
* Consturctor to be used qhen the confirmations of the transaction are known
|
||||||
* @param txid The txid of the transaciton to be query
|
* @param txid The txid of the transaciton to be query
|
||||||
* @param account The account to be query
|
|
||||||
* @param context This app Context
|
|
||||||
* @param mustWait If there is less confirmation that needed
|
* @param mustWait If there is less confirmation that needed
|
||||||
*/
|
*/
|
||||||
public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context, boolean mustWait) {
|
public GetTransactionData(String txid, String serverUrl, CryptoCoin cryptoCoin, boolean mustWait) {
|
||||||
this.mServerUrl = serverUrl;
|
this.mServerUrl = serverUrl;
|
||||||
this.mAccount = account;
|
|
||||||
this.mTxId= txid;
|
this.mTxId= txid;
|
||||||
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
||||||
this.mContext = context;
|
|
||||||
this.mMustWait = mustWait;
|
this.mMustWait = mustWait;
|
||||||
|
this.cryptoCoin = cryptoCoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,104 +76,19 @@ public class GetTransactionData extends Thread implements Callback<Txi> {
|
||||||
}
|
}
|
||||||
|
|
||||||
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
||||||
Call<Txi> txiCall = service.getTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),this.mTxId);
|
Call<Txi> txiCall = service.getTransaction(this.mServerUrl,this.mTxId);
|
||||||
txiCall.enqueue(this);
|
txiCall.enqueue(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
|
|
||||||
Txi txi = response.body();
|
Txi txi = response.body();
|
||||||
|
GeneralAccountManager.getAccountManager(this.cryptoCoin).processTxi(txi);
|
||||||
GeneralTransaction transaction = new GeneralTransaction();
|
if (txi.confirmations < this.cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
|
||||||
transaction.setAccount(this.mAccount);
|
|
||||||
transaction.setTxid(txi.txid);
|
|
||||||
transaction.setBlock(txi.blockheight);
|
|
||||||
transaction.setDate(new Date(txi.time * 1000));
|
|
||||||
transaction.setFee((long) (txi.fee * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
transaction.setConfirm(txi.confirmations);
|
|
||||||
transaction.setType(this.mAccount.getCryptoCoin());
|
|
||||||
transaction.setBlockHeight(txi.blockheight);
|
|
||||||
|
|
||||||
for (Vin vin : txi.vin) {
|
|
||||||
GTxIO input = new GTxIO();
|
|
||||||
input.setAmount((long) (vin.value * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
input.setTransaction(transaction);
|
|
||||||
input.setOut(true);
|
|
||||||
input.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vin.addr;
|
|
||||||
input.setAddressString(addr);
|
|
||||||
input.setIndex(vin.n);
|
|
||||||
input.setScriptHex(vin.scriptSig.hex);
|
|
||||||
input.setOriginalTxid(vin.txid);
|
|
||||||
for (GeneralCoinAddress address : this.mAccount.getAddresses()) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
input.setAddress(address);
|
|
||||||
if (!address.hasTransactionOutput(input, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionOutput().add(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transaction.getTxInputs().add(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Vout vout : txi.vout) {
|
|
||||||
if(vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0){
|
|
||||||
// The address is null, this must be a memo
|
|
||||||
String hex = vout.scriptPubKey.hex;
|
|
||||||
int opReturnIndex = hex.indexOf("6a");
|
|
||||||
if(opReturnIndex >= 0) {
|
|
||||||
byte[] memoBytes = new byte[Integer.parseInt(hex.substring(opReturnIndex+2,opReturnIndex+4),16)];
|
|
||||||
for(int i = 0; i < memoBytes.length;i++){
|
|
||||||
memoBytes[i] = Byte.parseByte(hex.substring(opReturnIndex+4+(i*2),opReturnIndex+6+(i*2)),16);
|
|
||||||
}
|
|
||||||
transaction.setMemo(new String(memoBytes));
|
|
||||||
System.out.println("Memo read : " + transaction.getMemo()); //TODO log this line
|
|
||||||
}
|
|
||||||
|
|
||||||
}else {
|
|
||||||
GTxIO output = new GTxIO();
|
|
||||||
output.setAmount((long) (vout.value * Math.pow(10, this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
output.setTransaction(transaction);
|
|
||||||
output.setOut(false);
|
|
||||||
output.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vout.scriptPubKey.addresses[0];
|
|
||||||
output.setAddressString(addr);
|
|
||||||
output.setIndex(vout.n);
|
|
||||||
output.setScriptHex(vout.scriptPubKey.hex);
|
|
||||||
for (GeneralCoinAddress address : this.mAccount.getAddresses()) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
output.setAddress(address);
|
|
||||||
if (!address.hasTransactionInput(output, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionInput().add(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transaction.getTxOutputs().add(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is for features like dash instantSend
|
|
||||||
if(txi.txlock && txi.confirmations< this.mAccount.getCryptoNet().getConfirmationsNeeded()){
|
|
||||||
transaction.setConfirm(this.mAccount.getCryptoNet().getConfirmationsNeeded());
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO database
|
|
||||||
/*SCWallDatabase db = new SCWallDatabase(this.mContext);
|
|
||||||
long idTransaction = db.getGeneralTransactionId(transaction);
|
|
||||||
if (idTransaction == -1) {
|
|
||||||
db.putGeneralTransaction(transaction);
|
|
||||||
} else {
|
|
||||||
transaction.setId(idTransaction);
|
|
||||||
db.updateGeneralTransaction(transaction);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
this.mAccount.updateTransaction(transaction);
|
|
||||||
this.mAccount.balanceChange();
|
|
||||||
|
|
||||||
if (transaction.getConfirm() < this.mAccount.getCryptoNet().getConfirmationsNeeded()) {
|
|
||||||
//If transaction weren't confirmed, add the transaction to watch for change on the confirmations
|
//If transaction weren't confirmed, add the transaction to watch for change on the confirmations
|
||||||
new GetTransactionData(this.mTxId, this.mAccount, this.mServerUrl, this.mContext, true).start();
|
new GetTransactionData(this.mTxId, this.mServerUrl, this.cryptoCoin, true).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package cy.agorise.crystalwallet.dao;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.arch.persistence.room.Dao;
|
||||||
|
import android.arch.persistence.room.Insert;
|
||||||
|
import android.arch.persistence.room.OnConflictStrategy;
|
||||||
|
import android.arch.persistence.room.Query;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransaction;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransactionExtended;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Henry Varona on 10/02/2018.
|
||||||
|
*/
|
||||||
|
@Dao
|
||||||
|
public interface BitcoinTransactionDao {
|
||||||
|
|
||||||
|
@Query("SELECT * FROM crypto_coin_transaction cct, bitcoin_transaction bt WHERE bt.crypto_coin_transaction_id = cct.id")
|
||||||
|
LiveData<BitcoinTransactionExtended> getAll();
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_transaction bt WHERE bt.tx_id = :txid")
|
||||||
|
BitcoinTransaction getByTxid(String txid);
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
public long[] insertBitcoinTransaction(BitcoinTransaction... transactions);
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ import android.content.Context;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.dao.converters.Converters;
|
import cy.agorise.crystalwallet.dao.converters.Converters;
|
||||||
import cy.agorise.crystalwallet.models.AccountSeed;
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransaction;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransactionGTxIO;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
|
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
|
||||||
import cy.agorise.crystalwallet.models.Contact;
|
import cy.agorise.crystalwallet.models.Contact;
|
||||||
|
@ -39,8 +41,10 @@ import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
|
||||||
BitsharesAssetInfo.class,
|
BitsharesAssetInfo.class,
|
||||||
BitsharesAccountNameCache.class,
|
BitsharesAccountNameCache.class,
|
||||||
CryptoCurrencyEquivalence.class,
|
CryptoCurrencyEquivalence.class,
|
||||||
GeneralSetting.class
|
GeneralSetting.class,
|
||||||
}, version = 4, exportSchema = false)
|
BitcoinTransaction.class,
|
||||||
|
BitcoinTransactionGTxIO.class
|
||||||
|
}, version = 5, exportSchema = false)
|
||||||
@TypeConverters({Converters.class})
|
@TypeConverters({Converters.class})
|
||||||
public abstract class CrystalDatabase extends RoomDatabase {
|
public abstract class CrystalDatabase extends RoomDatabase {
|
||||||
|
|
||||||
|
@ -57,6 +61,7 @@ public abstract class CrystalDatabase extends RoomDatabase {
|
||||||
public abstract BitsharesAccountNameCacheDao bitsharesAccountNameCacheDao();
|
public abstract BitsharesAccountNameCacheDao bitsharesAccountNameCacheDao();
|
||||||
public abstract CryptoCurrencyEquivalenceDao cryptoCurrencyEquivalenceDao();
|
public abstract CryptoCurrencyEquivalenceDao cryptoCurrencyEquivalenceDao();
|
||||||
public abstract GeneralSettingDao generalSettingDao();
|
public abstract GeneralSettingDao generalSettingDao();
|
||||||
|
public abstract BitcoinTransactionDao bitcoinTransactionDao();
|
||||||
|
|
||||||
public static CrystalDatabase getAppDatabase(Context context) {
|
public static CrystalDatabase getAppDatabase(Context context) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
|
@ -66,6 +71,7 @@ public abstract class CrystalDatabase extends RoomDatabase {
|
||||||
.allowMainThreadQueries()
|
.allowMainThreadQueries()
|
||||||
.addMigrations(MIGRATION_2_3)
|
.addMigrations(MIGRATION_2_3)
|
||||||
.addMigrations(MIGRATION_3_4)
|
.addMigrations(MIGRATION_3_4)
|
||||||
|
.addMigrations(MIGRATION_4_5)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -91,4 +97,25 @@ public abstract class CrystalDatabase extends RoomDatabase {
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static final Migration MIGRATION_4_5 = new Migration(4, 5) {
|
||||||
|
@Override
|
||||||
|
public void migrate(SupportSQLiteDatabase database) {
|
||||||
|
database.execSQL("CREATE TABLE bitcoin_transaction ("
|
||||||
|
+"crypto_coin_transaction_id INTEGER PRIMARY KEY NOT NULL,"
|
||||||
|
+"tx_id TEXT NOT NULL,"
|
||||||
|
+"block INTEGER NOT NULL,"
|
||||||
|
+"fee INTEGER NOT NULL,"
|
||||||
|
+"confirmations INTEGER NOT NULL,"
|
||||||
|
+"FOREIGN KEY (crypto_coin_transaction_id) REFERENCES crypto_coin_transaction(id) ON DELETE CASCADE)");
|
||||||
|
|
||||||
|
database.execSQL("CREATE TABLE bitcoin_transaction_gt_io ("
|
||||||
|
+"bitcoin_transaction_id INTEGER NOT NULL,"
|
||||||
|
+"io_index INTEGER NOT NULL,"
|
||||||
|
+"address TEXT,"
|
||||||
|
+"is_output INTEGER NOT NULL,"
|
||||||
|
+"PRIMARY KEY (bitcoin_transaction_id, io_index, is_output),"
|
||||||
|
+"FOREIGN KEY (bitcoin_transaction_id) REFERENCES bitcoin_transaction(crypto_coin_transaction_id) ON DELETE CASCADE)");
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class BalanceFragment extends Fragment {
|
||||||
vCryptoNetBalanceListView.setData(cryptoNetBalances, fragment);
|
vCryptoNetBalanceListView.setData(cryptoNetBalances, fragment);
|
||||||
|
|
||||||
final int size = cryptoNetBalances.size();
|
final int size = cryptoNetBalances.size();
|
||||||
if(size==1){
|
if(size==0){
|
||||||
tvNobalances.setVisibility(View.VISIBLE);
|
tvNobalances.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package cy.agorise.crystalwallet.fragments;
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -8,11 +12,13 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
import cy.agorise.crystalwallet.models.AccountSeed;
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
@ -30,9 +36,15 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
|
||||||
@BindView(R.id.tvMnemonic)
|
@BindView(R.id.tvMnemonic)
|
||||||
TextView tvMnemonic;
|
TextView tvMnemonic;
|
||||||
|
|
||||||
|
@BindView(R.id.btnCopy)
|
||||||
|
Button btnCopy;
|
||||||
|
|
||||||
CryptoNetAccount cryptoNetAccount;
|
CryptoNetAccount cryptoNetAccount;
|
||||||
AccountSeed accountSeed;
|
AccountSeed accountSeed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public GeneralCryptoNetAccountSettingsFragment() {
|
public GeneralCryptoNetAccountSettingsFragment() {
|
||||||
|
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
|
@ -83,4 +95,24 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
|
||||||
tvMnemonic.setText(this.accountSeed.getMasterSeed());
|
tvMnemonic.setText(this.accountSeed.getMasterSeed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clic on button copy to clipboard
|
||||||
|
* */
|
||||||
|
@OnClick(R.id.btnCopy)
|
||||||
|
public void btnCopyClick(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save to clipboard the brainkey chain
|
||||||
|
* */
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText(tvMnemonic.getText(), tvMnemonic.getText().toString());
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Success message
|
||||||
|
* */
|
||||||
|
Toast.makeText(activity,getResources().getString(R.string.window_seed_toast_clipboard), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,17 @@ import android.app.Dialog;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
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.ViewGroup;
|
||||||
|
@ -19,6 +24,8 @@ import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.vincent.filepicker.ToastUtil;
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
|
@ -50,6 +57,7 @@ public class ImportAccountOptionsFragment extends DialogFragment {
|
||||||
@BindView(R.id.btnImportBackup)
|
@BindView(R.id.btnImportBackup)
|
||||||
Button btnImportBackup;
|
Button btnImportBackup;
|
||||||
|
|
||||||
|
private static final int PERMISSION_REQUEST_CODE = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Dialog for loading
|
Dialog for loading
|
||||||
|
@ -110,18 +118,88 @@ public class ImportAccountOptionsFragment extends DialogFragment {
|
||||||
|
|
||||||
@OnClick (R.id.btnImportBackup)
|
@OnClick (R.id.btnImportBackup)
|
||||||
public void importBackup(){
|
public void importBackup(){
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
|
|
||||||
|
if (checkPermission()) {
|
||||||
|
|
||||||
Intent fileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
Intent fileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
fileIntent.setType("*/*");
|
fileIntent.setType("*/*");
|
||||||
fileIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
fileIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
startActivityForResult(fileIntent, FILE_CONTENT_REQUEST_CODE);
|
startActivityForResult(fileIntent, FILE_CONTENT_REQUEST_CODE);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
requestPermission(); // Code for permission
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
Intent fileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
|
fileIntent.setType("*/*");
|
||||||
|
fileIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
startActivityForResult(fileIntent, FILE_CONTENT_REQUEST_CODE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick (R.id.btnImportSeed)
|
@OnClick (R.id.btnImportSeed)
|
||||||
public void importSeed(){
|
public void importSeed(){
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
|
|
||||||
|
if (checkPermission()) {
|
||||||
|
|
||||||
Intent intent = new Intent(this.getActivity(), ImportSeedActivity.class);
|
Intent intent = new Intent(this.getActivity(), ImportSeedActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
requestPermission(); // Code for permission
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Intent intent = new Intent(this.getActivity(), ImportSeedActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean checkPermission() {
|
||||||
|
int result = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
|
if (result == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void requestPermission() {
|
||||||
|
|
||||||
|
Log.i("log", "requestPermission() entered");
|
||||||
|
|
||||||
|
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||||
|
Toast.makeText(getActivity(), "Write External Storage permission allows us to do store images. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
|
||||||
|
} else {
|
||||||
|
// ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
|
||||||
|
requestPermissions(new String[] {android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
|
||||||
|
switch (requestCode) {
|
||||||
|
case PERMISSION_REQUEST_CODE:
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
||||||
|
Intent intent = new Intent(getActivity(), ImportSeedActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ToastUtil.getInstance(getActivity()).showToast(getActivity().getString(R.string.Permission_Denied_WRITE_EXTERNAL_STORAGE));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,11 +8,13 @@ import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ContextWrapper;
|
import android.content.ContextWrapper;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
@ -22,20 +24,20 @@ import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.text.Editable;
|
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.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ScrollView;
|
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
@ -56,6 +58,8 @@ import butterknife.OnClick;
|
||||||
import butterknife.OnItemSelected;
|
import butterknife.OnItemSelected;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.CrystalDialog;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.ToastIt;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
|
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
|
||||||
|
@ -93,6 +97,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
View viewSend;
|
View viewSend;
|
||||||
@BindView(R.id.tvToError)
|
@BindView(R.id.tvToError)
|
||||||
TextView tvToError;
|
TextView tvToError;
|
||||||
|
@BindView(R.id.fabCloseCamera)
|
||||||
|
FloatingActionButton btnCloseCamera;
|
||||||
@BindView(R.id.spAsset)
|
@BindView(R.id.spAsset)
|
||||||
Spinner spAsset;
|
Spinner spAsset;
|
||||||
@BindView(R.id.tvAssetError)
|
@BindView(R.id.tvAssetError)
|
||||||
|
@ -122,6 +128,14 @@ 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 hide
|
||||||
|
* */
|
||||||
|
private boolean cameraVisible = true;
|
||||||
|
|
||||||
Button btnScanQrCode;
|
Button btnScanQrCode;
|
||||||
|
|
||||||
private long cryptoNetAccountId;
|
private long cryptoNetAccountId;
|
||||||
|
@ -131,7 +145,10 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
private FloatingActionButton fabSend;
|
private FloatingActionButton fabSend;
|
||||||
private AlertDialog.Builder builder;
|
private AlertDialog.Builder builder;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dialog for loading
|
||||||
|
*/
|
||||||
|
private CrystalDialog crystalDialog;
|
||||||
|
|
||||||
public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
|
public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
|
||||||
SendTransactionFragment f = new SendTransactionFragment();
|
SendTransactionFragment f = new SendTransactionFragment();
|
||||||
|
@ -273,19 +290,123 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
loadUserImage();
|
loadUserImage();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for CAMERA permission
|
||||||
|
* */
|
||||||
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
|
if (checkPermission()) {
|
||||||
|
// Code for above or equal 23 API Oriented Device
|
||||||
|
// Your Permission granted already .Do next code
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init the camera
|
||||||
|
* */
|
||||||
try {
|
try {
|
||||||
verifyCameraPermissions(getActivity());
|
|
||||||
beginScanQrCode();
|
beginScanQrCode();
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
requestPermission(); // Code for permission
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Code for Below 23 API Oriented Device
|
||||||
|
// Do next code
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init the camera
|
||||||
|
* */
|
||||||
|
try {
|
||||||
|
beginScanQrCode();
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return builder.setView(view).create();
|
return builder.setView(view).create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void requestPermission() {
|
||||||
|
|
||||||
|
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
|
||||||
|
Toast.makeText(getActivity(), getActivity().getString(R.string.permission_denied_camera), Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the button of the camera visibility
|
||||||
|
* */
|
||||||
|
disableVisibilityCamera();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
requestPermissions(new String[] {android.Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableVisibilityCamera(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hide the button, the user can not modify the visibility
|
||||||
|
* */
|
||||||
|
btnCloseCamera.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkPermission() {
|
||||||
|
int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA);
|
||||||
|
if (result == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
|
||||||
|
switch (requestCode) {
|
||||||
|
case REQUEST_CAMERA_PERMISSION:
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Log.e("value", "Permission Granted, Now you can use camera .");
|
||||||
|
|
||||||
|
getActivity().runOnUiThread(new Runnable(){
|
||||||
|
public void run() {
|
||||||
|
Toast.makeText(getActivity(), getActivity().getString(R.string.permission_granted_camera), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init the camera
|
||||||
|
* */
|
||||||
|
try {
|
||||||
|
beginScanQrCode();
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.e("value", "Permission Denied, You cannot use the camera.");
|
||||||
|
|
||||||
|
getActivity().runOnUiThread(new Runnable(){
|
||||||
|
public void run() {
|
||||||
|
Toast.makeText(getActivity(), getActivity().getString(R.string.permission_denied_camera), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
mScannerView.setResultHandler(this);
|
||||||
|
mScannerView.startCamera();
|
||||||
/*builder.setNeutralButton("Scan QR Code", new DialogInterface.OnClickListener() {
|
/*builder.setNeutralButton("Scan QR Code", new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
@ -300,6 +421,12 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
loadUserImage();
|
loadUserImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mScannerView.stopCamera();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
@ -351,6 +478,71 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OnClick(R.id.fabCloseCamera)
|
||||||
|
public void onClicCloseCamera(){
|
||||||
|
mScannerView.stopCamera();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hide the camera or show it
|
||||||
|
* */
|
||||||
|
if(cameraVisible){
|
||||||
|
hideCamera();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
showCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show the camera and hide the black background
|
||||||
|
* */
|
||||||
|
private void showCamera(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change visibilities of views
|
||||||
|
* */
|
||||||
|
viewCamera.setVisibility(View.GONE);
|
||||||
|
mScannerView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change icon
|
||||||
|
* */
|
||||||
|
btnCloseCamera.setImageDrawable(getResources().getDrawable(R.drawable.ic_close));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset variable
|
||||||
|
* */
|
||||||
|
cameraVisible = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Star the camera again
|
||||||
|
* */
|
||||||
|
beginScanQrCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hide the camera and show the black background
|
||||||
|
* */
|
||||||
|
private void hideCamera(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change visibilities of views
|
||||||
|
* */
|
||||||
|
viewCamera.setVisibility(View.VISIBLE);
|
||||||
|
mScannerView.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change icon
|
||||||
|
* */
|
||||||
|
btnCloseCamera.setImageDrawable(getResources().getDrawable(R.drawable.ok));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset variable
|
||||||
|
* */
|
||||||
|
cameraVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etMemo,
|
@OnTextChanged(value = R.id.etMemo,
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||||
void afterMemoChanged(Editable editable) {
|
void afterMemoChanged(Editable editable) {
|
||||||
|
@ -408,6 +600,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
|
|
||||||
@OnClick(R.id.btnSend)
|
@OnClick(R.id.btnSend)
|
||||||
public void sendTransaction(){
|
public void sendTransaction(){
|
||||||
|
final SendTransactionFragment thisFragment = this;
|
||||||
|
|
||||||
if (this.sendTransactionValidator.isValid()) {
|
if (this.sendTransactionValidator.isValid()) {
|
||||||
CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex());
|
CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex());
|
||||||
|
|
||||||
|
@ -439,13 +633,26 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
public void onCarryOut() {
|
public void onCarryOut() {
|
||||||
if (sendRequest.getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)){
|
if (sendRequest.getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)){
|
||||||
try {
|
try {
|
||||||
this.finalize();
|
crystalDialog.dismiss();
|
||||||
|
thisFragment.dismiss();
|
||||||
|
//thisFragment.finalize();
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show loading dialog
|
||||||
|
* */
|
||||||
|
crystalDialog = new CrystalDialog((Activity) getContext());
|
||||||
|
crystalDialog.setText("Sending");
|
||||||
|
crystalDialog.progress();
|
||||||
|
crystalDialog.show();
|
||||||
|
|
||||||
CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
|
CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,6 +660,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
public void beginScanQrCode(){
|
public void beginScanQrCode(){
|
||||||
//mScannerView = new ZXingScannerView(getContext());
|
//mScannerView = new ZXingScannerView(getContext());
|
||||||
mScannerView.setFormats(listOf(BarcodeFormat.QR_CODE));
|
mScannerView.setFormats(listOf(BarcodeFormat.QR_CODE));
|
||||||
|
mScannerView.setAspectTolerance(0.5f);
|
||||||
mScannerView.setAutoFocus(true);
|
mScannerView.setAutoFocus(true);
|
||||||
mScannerView.setLaserColor(R.color.colorAccent);
|
mScannerView.setLaserColor(R.color.colorAccent);
|
||||||
mScannerView.setMaskColor(R.color.colorAccent);
|
mScannerView.setMaskColor(R.color.colorAccent);
|
||||||
|
@ -467,20 +675,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public static void verifyCameraPermissions(Activity activity) {
|
|
||||||
// Check if we have write permission
|
|
||||||
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
|
|
||||||
|
|
||||||
if (permission != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
// We don't have permission so prompt the user
|
|
||||||
ActivityCompat.requestPermissions(
|
|
||||||
activity,
|
|
||||||
PERMISSIONS_CAMERA,
|
|
||||||
REQUEST_CAMERA_PERMISSION
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValidationSucceeded(final ValidationField field) {
|
public void onValidationSucceeded(final ValidationField field) {
|
||||||
final SendTransactionFragment fragment = this;
|
final SendTransactionFragment fragment = this;
|
||||||
|
@ -534,7 +728,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
@Override
|
@Override
|
||||||
public void handleResult(Result result) {
|
public void handleResult(Result result) {
|
||||||
try {
|
try {
|
||||||
System.out.println("CAMERA result " + result.getText() );
|
|
||||||
Invoice invoice = Invoice.fromQrCode(result.getText());
|
Invoice invoice = Invoice.fromQrCode(result.getText());
|
||||||
|
|
||||||
etTo.setText(invoice.getTo());
|
etTo.setText(invoice.getTo());
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cy.agorise.crystalwallet.manager;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.common.primitives.UnsignedLong;
|
import com.google.common.primitives.UnsignedLong;
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
|
||||||
import cy.agorise.crystalwallet.apigenerator.grapheneoperation.AccountUpgradeOperationBuilder;
|
import cy.agorise.crystalwallet.apigenerator.grapheneoperation.AccountUpgradeOperationBuilder;
|
||||||
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
|
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
|
||||||
import cy.agorise.crystalwallet.dao.AccountSeedDao;
|
import cy.agorise.crystalwallet.dao.AccountSeedDao;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
||||||
import cy.agorise.crystalwallet.models.seed.BIP39;
|
import cy.agorise.crystalwallet.models.seed.BIP39;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetEquivalentRequest;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetEquivalentRequest;
|
||||||
|
@ -64,8 +66,6 @@ import cy.agorise.graphenej.operations.TransferOperationBuilder;
|
||||||
*/
|
*/
|
||||||
public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
||||||
|
|
||||||
//private final static String BITSHARES_TESTNET_CHAIN_ID= "9cf6f255a208100d2bb275a3c52f4b1589b7ec9c9bfc2cb2a5fe6411295106d8";
|
|
||||||
|
|
||||||
private final static String SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
private final static String SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
||||||
private final static String DEFAULT_TIME_ZONE = "GMT";
|
private final static String DEFAULT_TIME_ZONE = "GMT";
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
long[] idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
long[] idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
||||||
grapheneAccount.setId(idAccount[0]);
|
grapheneAccount.setId(idAccount[0]);
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
//subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -147,7 +147,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
//subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,7 +159,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context);
|
//subscribeBitsharesAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,26 +221,28 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onNewRequest(CryptoNetInfoRequest request) {
|
public void onNewRequest(CryptoNetInfoRequest request) {
|
||||||
if (request instanceof ValidateImportBitsharesAccountRequest){
|
if(request.getCoin().equals(CryptoCoin.BITSHARES)) {
|
||||||
|
if (request instanceof ValidateImportBitsharesAccountRequest) {
|
||||||
this.validateImportAccount((ValidateImportBitsharesAccountRequest) request);
|
this.validateImportAccount((ValidateImportBitsharesAccountRequest) request);
|
||||||
} else if (request instanceof ValidateExistBitsharesAccountRequest){
|
} else if (request instanceof ValidateExistBitsharesAccountRequest) {
|
||||||
this.validateExistAcccount((ValidateExistBitsharesAccountRequest) request);
|
this.validateExistAcccount((ValidateExistBitsharesAccountRequest) request);
|
||||||
} else if (request instanceof ValidateBitsharesSendRequest){
|
} else if (request instanceof ValidateBitsharesSendRequest) {
|
||||||
this.validateSendRequest((ValidateBitsharesSendRequest) request);
|
this.validateSendRequest((ValidateBitsharesSendRequest) request);
|
||||||
}else if (request instanceof CryptoNetEquivalentRequest){
|
} else if (request instanceof CryptoNetEquivalentRequest) {
|
||||||
this.getEquivalentValue((CryptoNetEquivalentRequest) request);
|
this.getEquivalentValue((CryptoNetEquivalentRequest) request);
|
||||||
}else if (request instanceof ValidateCreateBitsharesAccountRequest){
|
} else if (request instanceof ValidateCreateBitsharesAccountRequest) {
|
||||||
this.validateCreateAccount((ValidateCreateBitsharesAccountRequest) request);
|
this.validateCreateAccount((ValidateCreateBitsharesAccountRequest) request);
|
||||||
}else if (request instanceof ValidateBitsharesLTMUpgradeRequest){
|
} else if (request instanceof ValidateBitsharesLTMUpgradeRequest) {
|
||||||
this.validateLTMAccountUpgrade((ValidateBitsharesLTMUpgradeRequest) request);
|
this.validateLTMAccountUpgrade((ValidateBitsharesLTMUpgradeRequest) request);
|
||||||
}else if (request instanceof GetBitsharesAccountNameCacheRequest){
|
} else if (request instanceof GetBitsharesAccountNameCacheRequest) {
|
||||||
this.getBitsharesAccountNameCacheRequest((GetBitsharesAccountNameCacheRequest) request);
|
this.getBitsharesAccountNameCacheRequest((GetBitsharesAccountNameCacheRequest) request);
|
||||||
}else{
|
} else {
|
||||||
|
|
||||||
//TODO not implemented
|
//TODO not implemented
|
||||||
System.out.println("Error request not implemented " + request.getClass().getName());
|
System.out.println("Error request not implemented " + request.getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the import account request
|
* Process the import account request
|
||||||
|
|
|
@ -12,14 +12,25 @@ import org.bitcoinj.crypto.HDKeyDerivation;
|
||||||
import org.bitcoinj.script.Script;
|
import org.bitcoinj.script.Script;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.apigenerator.ApiRequest;
|
import cy.agorise.crystalwallet.apigenerator.ApiRequest;
|
||||||
import cy.agorise.crystalwallet.apigenerator.ApiRequestListener;
|
import cy.agorise.crystalwallet.apigenerator.ApiRequestListener;
|
||||||
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
|
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
|
||||||
|
import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionData;
|
||||||
|
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.dao.CrystalDatabase;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransaction;
|
||||||
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
import cy.agorise.crystalwallet.models.GTxIO;
|
import cy.agorise.crystalwallet.models.GTxIO;
|
||||||
|
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
||||||
import cy.agorise.crystalwallet.models.GeneralTransaction;
|
import cy.agorise.crystalwallet.models.GeneralTransaction;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
|
||||||
|
@ -29,6 +40,28 @@ import cy.agorise.graphenej.Util;
|
||||||
|
|
||||||
public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
||||||
|
|
||||||
|
static HashMap<CryptoCoin, GeneralAccountManager> generalAccountManagers = new HashMap();
|
||||||
|
|
||||||
|
private static CryptoCoin[] SUPPORTED_COINS = new CryptoCoin[]{
|
||||||
|
CryptoCoin.BITCOIN,
|
||||||
|
CryptoCoin.BITCOIN_TEST,
|
||||||
|
CryptoCoin.DASH,
|
||||||
|
CryptoCoin.LITECOIN
|
||||||
|
} ;
|
||||||
|
|
||||||
|
final CryptoCoin cryptoCoin;
|
||||||
|
final Context context;
|
||||||
|
|
||||||
|
public static GeneralAccountManager getAccountManager(CryptoCoin coin){
|
||||||
|
return generalAccountManagers.get(coin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeneralAccountManager(CryptoCoin cryptoCoin, Context context) {
|
||||||
|
this.cryptoCoin = cryptoCoin;
|
||||||
|
this.context = context;
|
||||||
|
generalAccountManagers.put(cryptoCoin,this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createAccountFromSeed(CryptoNetAccount account, ManagerRequest request, Context context) {
|
public void createAccountFromSeed(CryptoNetAccount account, ManagerRequest request, Context context) {
|
||||||
|
|
||||||
|
@ -46,14 +79,131 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNewRequest(CryptoNetInfoRequest request) {
|
public void onNewRequest(CryptoNetInfoRequest request) {
|
||||||
|
if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
|
||||||
|
if(request instanceof GeneralAccountSendRequest){
|
||||||
|
this.send((GeneralAccountSendRequest)request);
|
||||||
|
}else{
|
||||||
|
System.out.println("Invalid " +this.cryptoCoin.getLabel() + " request ");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that process each transaction fetched by the insight api
|
||||||
|
* @param txi
|
||||||
|
*/
|
||||||
|
public void processTxi(Txi txi){
|
||||||
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
|
||||||
|
BitcoinTransaction btTransaction = db.bitcoinTransactionDao().getByTxid(txi.txid);
|
||||||
|
if(btTransaction != null){
|
||||||
|
btTransaction.setConfirmations(txi.confirmations);
|
||||||
|
db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction);
|
||||||
|
}else {
|
||||||
|
|
||||||
|
|
||||||
|
GeneralTransaction transaction = new GeneralTransaction();
|
||||||
|
//transaction.setAccount(this.mAccount);
|
||||||
|
transaction.setTxid(txi.txid);
|
||||||
|
transaction.setBlock(txi.blockheight);
|
||||||
|
transaction.setDate(new Date(txi.time * 1000));
|
||||||
|
transaction.setFee((long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision())));
|
||||||
|
transaction.setConfirm(txi.confirmations);
|
||||||
|
transaction.setType(cryptoCoin);
|
||||||
|
transaction.setBlockHeight(txi.blockheight);
|
||||||
|
|
||||||
|
for (Vin vin : txi.vin) {
|
||||||
|
GTxIO input = new GTxIO();
|
||||||
|
input.setAmount((long) (vin.value * Math.pow(10, cryptoCoin.getPrecision())));
|
||||||
|
input.setTransaction(transaction);
|
||||||
|
input.setOut(true);
|
||||||
|
input.setType(cryptoCoin);
|
||||||
|
String addr = vin.addr;
|
||||||
|
input.setAddressString(addr);
|
||||||
|
input.setIndex(vin.n);
|
||||||
|
input.setScriptHex(vin.scriptSig.hex);
|
||||||
|
input.setOriginalTxid(vin.txid);
|
||||||
|
/*for (GeneralCoinAddress address : this.mAddresses) {
|
||||||
|
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
||||||
|
input.setAddress(address);
|
||||||
|
tempAccount = address.getAccount();
|
||||||
|
|
||||||
|
if (!address.hasTransactionOutput(input, this.mAccount.getNetworkParam())) {
|
||||||
|
address.getTransactionOutput().add(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
transaction.getTxInputs().add(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Vout vout : txi.vout) {
|
||||||
|
if (vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0) {
|
||||||
|
// The address is null, this must be a memo
|
||||||
|
String hex = vout.scriptPubKey.hex;
|
||||||
|
int opReturnIndex = hex.indexOf("6a");
|
||||||
|
if (opReturnIndex >= 0) {
|
||||||
|
byte[] memoBytes = new byte[Integer.parseInt(hex.substring(opReturnIndex + 2, opReturnIndex + 4), 16)];
|
||||||
|
for (int i = 0; i < memoBytes.length; i++) {
|
||||||
|
memoBytes[i] = Byte.parseByte(hex.substring(opReturnIndex + 4 + (i * 2), opReturnIndex + 6 + (i * 2)), 16);
|
||||||
|
}
|
||||||
|
transaction.setMemo(new String(memoBytes));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GTxIO output = new GTxIO();
|
||||||
|
output.setAmount((long) (vout.value * Math.pow(10, cryptoCoin.getPrecision())));
|
||||||
|
output.setTransaction(transaction);
|
||||||
|
output.setOut(false);
|
||||||
|
output.setType(cryptoCoin);
|
||||||
|
String addr = vout.scriptPubKey.addresses[0];
|
||||||
|
output.setAddressString(addr);
|
||||||
|
output.setIndex(vout.n);
|
||||||
|
output.setScriptHex(vout.scriptPubKey.hex);
|
||||||
|
/*for (GeneralCoinAddress address : this.mAddresses) {
|
||||||
|
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
||||||
|
output.setAddress(address);
|
||||||
|
tempAccount = address.getAccount();
|
||||||
|
|
||||||
|
if (!address.hasTransactionInput(output, this.mAccount.getNetworkParam())) {
|
||||||
|
address.getTransactionInput().add(output);
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
transaction.getTxOutputs().add(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (txi.txlock && txi.confirmations < cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
|
||||||
|
transaction.setConfirm(cryptoCoin.getCryptoNet().getConfirmationsNeeded());
|
||||||
|
}
|
||||||
|
//TODO database
|
||||||
|
/*SCWallDatabase db = new SCWallDatabase(this.mContext);
|
||||||
|
long idTransaction = db.getGeneralTransactionId(transaction);
|
||||||
|
if (idTransaction == -1) {
|
||||||
|
db.putGeneralTransaction(transaction);
|
||||||
|
} else {
|
||||||
|
transaction.setId(idTransaction);
|
||||||
|
db.updateGeneralTransaction(transaction);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*if (tempAccount != null && transaction.getConfirm() < this.mAccount.getCryptoNet().getConfirmationsNeeded()) {
|
||||||
|
InsightApiGenerator.followTransaction();
|
||||||
|
new GetTransactionData(transaction.getTxid(), tempAccount, this.serverUrl, this.mContext, true).start();
|
||||||
|
}
|
||||||
|
for (GeneralCoinAddress address : this.mAddresses) {
|
||||||
|
if (address.updateTransaction(transaction)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void send(final GeneralAccountSendRequest request){
|
public void send(final GeneralAccountSendRequest request){
|
||||||
//TODO check server connection
|
//TODO check server connection
|
||||||
//TODO validate to address
|
//TODO validate to address
|
||||||
|
|
||||||
InsightApiGenerator.getEstimateFee(request.getAccount().getCryptoNet(),new ApiRequest(1, new ApiRequestListener() {
|
InsightApiGenerator.getEstimateFee(request.getAccount().getCryptoCoin(),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(request.getAccount().getNetworkParam());
|
Transaction tx = new Transaction(request.getAccount().getNetworkParam());
|
||||||
|
@ -122,7 +272,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
|
||||||
tx.addSignedInput(outPoint, script, utxo.getAddress().getKey(), Transaction.SigHash.ALL, true);
|
tx.addSignedInput(outPoint, script, utxo.getAddress().getKey(), Transaction.SigHash.ALL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
InsightApiGenerator.broadcastTransaction(request.getAccount().getCryptoNet(),Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
|
InsightApiGenerator.broadcastTransaction(request.getAccount().getCryptoCoin(),Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
|
||||||
@Override
|
@Override
|
||||||
public void success(Object answer, int idPetition) {
|
public void success(Object answer, int idPetition) {
|
||||||
request.setStatus(GeneralAccountSendRequest.StatusCode.SUCCEEDED);
|
request.setStatus(GeneralAccountSendRequest.StatusCode.SUCCEEDED);
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo;
|
||||||
|
import android.arch.persistence.room.Entity;
|
||||||
|
import android.arch.persistence.room.ForeignKey;
|
||||||
|
import android.arch.persistence.room.Ignore;
|
||||||
|
import android.arch.persistence.room.Index;
|
||||||
|
import android.arch.persistence.room.PrimaryKey;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.util.DiffUtil;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Bitcoin alike Transaction
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/2/2018.
|
||||||
|
*/
|
||||||
|
@Entity(
|
||||||
|
tableName="bitcoin_transaction",
|
||||||
|
primaryKeys = {"crypto_coin_transaction_id"},
|
||||||
|
foreignKeys = {
|
||||||
|
@ForeignKey(
|
||||||
|
entity = CryptoCoinTransaction.class,
|
||||||
|
parentColumns = "id",
|
||||||
|
childColumns = "crypto_coin_transaction_id",
|
||||||
|
onDelete = ForeignKey.CASCADE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class BitcoinTransaction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the base transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="crypto_coin_transaction_id")
|
||||||
|
protected long cryptoCoinTransactionId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The transaction id in the blockchain
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="tx_id")
|
||||||
|
@NonNull protected String txId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The block id in the blockchain
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="block")
|
||||||
|
protected long block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fee of the transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="fee")
|
||||||
|
protected long fee;
|
||||||
|
/**
|
||||||
|
* The confirmations of the transaction in the blockchain
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="confirmations")
|
||||||
|
protected int confirmations;
|
||||||
|
|
||||||
|
public BitcoinTransaction(long cryptoCoinTransactionId, String txId, long block, long fee, int confirmations) {
|
||||||
|
this.cryptoCoinTransactionId = cryptoCoinTransactionId;
|
||||||
|
this.txId = txId;
|
||||||
|
this.block = block;
|
||||||
|
this.fee = fee;
|
||||||
|
this.confirmations = confirmations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCryptoCoinTransactionId() {
|
||||||
|
return cryptoCoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCryptoCoinTransactionId(long cryptoCoinTransactionId) {
|
||||||
|
this.cryptoCoinTransactionId = cryptoCoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTxId() {
|
||||||
|
return txId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTxId(String txId) {
|
||||||
|
this.txId = txId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBlock() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlock(long block) {
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFee() {
|
||||||
|
return fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFee(long fee) {
|
||||||
|
this.fee = fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConfirmations() {
|
||||||
|
return confirmations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfirmations(int confirmations) {
|
||||||
|
this.confirmations = confirmations;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo;
|
||||||
|
import android.arch.persistence.room.Embedded;
|
||||||
|
import android.arch.persistence.room.Entity;
|
||||||
|
import android.arch.persistence.room.ForeignKey;
|
||||||
|
import android.arch.persistence.room.Relation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Bitcoin alike Transaction
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/2/2018.
|
||||||
|
*/
|
||||||
|
public class BitcoinTransactionExtended {
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
public CryptoCoinTransaction cryptoCoinTransaction;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
public BitcoinTransaction bitcoinTransaction;
|
||||||
|
|
||||||
|
@Relation(parentColumn = "id", entityColumn = "bitcoin_transaction_id", entity = BitcoinTransactionGTxIO.class)
|
||||||
|
public List<BitcoinTransactionGTxIO> bitcoinTransactionGTxIOList;
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo;
|
||||||
|
import android.arch.persistence.room.Entity;
|
||||||
|
import android.arch.persistence.room.ForeignKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Bitcoin alike Transaction Inputs and Outputs
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/2/2018.
|
||||||
|
*/
|
||||||
|
@Entity(
|
||||||
|
tableName="bitcoin_transaction_gt_io",
|
||||||
|
primaryKeys = {"bitcoin_transaction_id", "io_index", "is_output"},
|
||||||
|
foreignKeys = {
|
||||||
|
@ForeignKey(
|
||||||
|
entity = BitcoinTransaction.class,
|
||||||
|
parentColumns = "crypto_coin_transaction_id",
|
||||||
|
childColumns = "bitcoin_transaction_id",
|
||||||
|
onDelete = ForeignKey.CASCADE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class BitcoinTransactionGTxIO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the bitcoin transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="bitcoin_transaction_id")
|
||||||
|
protected long bitcoinTransactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index in the transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="io_index")
|
||||||
|
protected int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The address of the input or output
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="address")
|
||||||
|
protected String address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines if this is an input or output
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="is_output")
|
||||||
|
protected boolean isOutput;
|
||||||
|
|
||||||
|
public BitcoinTransactionGTxIO(long bitcoinTransactionId, int index, String address, boolean isOutput) {
|
||||||
|
this.bitcoinTransactionId = bitcoinTransactionId;
|
||||||
|
this.index = index;
|
||||||
|
this.address = address;
|
||||||
|
this.isOutput = isOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBitcoinTransactionId() {
|
||||||
|
return bitcoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitcoinTransactionId(long bitcoinTransactionId) {
|
||||||
|
this.bitcoinTransactionId = bitcoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOutput() {
|
||||||
|
return isOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutput(boolean output) {
|
||||||
|
isOutput = output;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,13 +21,6 @@ public abstract class CryptoNetInfoRequest {
|
||||||
*/
|
*/
|
||||||
protected CryptoNetInfoRequestListener listener;
|
protected CryptoNetInfoRequestListener listener;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected CryptoNetInfoRequest(CryptoCoin coin){
|
protected CryptoNetInfoRequest(CryptoCoin coin){
|
||||||
this.coin = coin;
|
this.coin = coin;
|
||||||
}
|
}
|
||||||
|
@ -43,4 +36,7 @@ public abstract class CryptoNetInfoRequest {
|
||||||
CryptoNetInfoRequests.getInstance().removeRequest(this);
|
CryptoNetInfoRequests.getInstance().removeRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CryptoCoin getCoin() {
|
||||||
|
return coin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,12 +105,19 @@ public class CryptoCoinBalanceViewHolder extends RecyclerView.ViewHolder {
|
||||||
public void onChanged(@Nullable CryptoCurrencyEquivalence cryptoCurrencyEquivalence) {
|
public void onChanged(@Nullable CryptoCurrencyEquivalence cryptoCurrencyEquivalence) {
|
||||||
if (cryptoCurrencyEquivalence != null) {
|
if (cryptoCurrencyEquivalence != null) {
|
||||||
CryptoCurrency toCurrency = CrystalDatabase.getAppDatabase(context).cryptoCurrencyDao().getById(cryptoCurrencyEquivalence.getFromCurrencyId());
|
CryptoCurrency toCurrency = CrystalDatabase.getAppDatabase(context).cryptoCurrencyDao().getById(cryptoCurrencyEquivalence.getFromCurrencyId());
|
||||||
double equivalentValue = (balance.getBalance() / Math.pow(10, currencyFrom.getPrecision())) /
|
double equivalentValue = 0;
|
||||||
|
String equivalenceString = "";
|
||||||
|
if (cryptoCurrencyEquivalence.getValue() > 0) {
|
||||||
|
equivalentValue = (balance.getBalance() / Math.pow(10, currencyFrom.getPrecision())) /
|
||||||
(cryptoCurrencyEquivalence.getValue() / Math.pow(10, toCurrency.getPrecision()));
|
(cryptoCurrencyEquivalence.getValue() / Math.pow(10, toCurrency.getPrecision()));
|
||||||
String equivalenceString = String.format(
|
equivalenceString = String.format(
|
||||||
"%.2f",
|
"%.2f",
|
||||||
equivalentValue
|
equivalentValue
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
equivalentValue = 0;
|
||||||
|
equivalenceString = "0";
|
||||||
|
}
|
||||||
|
|
||||||
cryptoNetBalanceViewHolder.setEquivalentBalance(balance,equivalentValue);
|
cryptoNetBalanceViewHolder.setEquivalentBalance(balance,equivalentValue);
|
||||||
cryptoCoinBalanceEquivalence.setText(
|
cryptoCoinBalanceEquivalence.setText(
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cy.agorise.crystalwallet.views;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.arch.lifecycle.LifecycleOwner;
|
import android.arch.lifecycle.LifecycleOwner;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
|
@ -24,12 +25,14 @@ import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.activities.SendTransactionActivity;
|
import cy.agorise.crystalwallet.activities.SendTransactionActivity;
|
||||||
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
import cy.agorise.crystalwallet.fragments.ReceiveTransactionFragment;
|
import cy.agorise.crystalwallet.fragments.ReceiveTransactionFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.SendTransactionFragment;
|
import cy.agorise.crystalwallet.fragments.SendTransactionFragment;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
|
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
|
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
|
||||||
import cy.agorise.crystalwallet.models.CryptoNetBalance;
|
import cy.agorise.crystalwallet.models.CryptoNetBalance;
|
||||||
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoCoinBalanceListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.CryptoCoinBalanceListViewModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,6 +89,8 @@ public class CryptoNetBalanceViewHolder extends RecyclerView.ViewHolder {
|
||||||
*/
|
*/
|
||||||
private Fragment fragment;
|
private Fragment fragment;
|
||||||
|
|
||||||
|
String preferredCurrency = "";
|
||||||
|
|
||||||
public CryptoNetBalanceViewHolder(View itemView, Fragment fragment) {
|
public CryptoNetBalanceViewHolder(View itemView, Fragment fragment) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
//-1 represents a crypto net account not loaded yet
|
//-1 represents a crypto net account not loaded yet
|
||||||
|
@ -114,6 +119,18 @@ public class CryptoNetBalanceViewHolder extends RecyclerView.ViewHolder {
|
||||||
});
|
});
|
||||||
this.fragment = fragment;
|
this.fragment = fragment;
|
||||||
this.context = itemView.getContext();
|
this.context = itemView.getContext();
|
||||||
|
|
||||||
|
LiveData<GeneralSetting> preferedCurrencySetting = CrystalDatabase.getAppDatabase(this.context).generalSettingDao().getByName(GeneralSetting.SETTING_NAME_PREFERRED_CURRENCY);
|
||||||
|
|
||||||
|
preferedCurrencySetting.observe((LifecycleOwner)this.itemView.getContext(), new Observer<GeneralSetting>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable GeneralSetting generalSetting) {
|
||||||
|
if(generalSetting != null){
|
||||||
|
preferredCurrency = generalSetting.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear(){
|
public void clear(){
|
||||||
|
@ -179,7 +196,7 @@ public class CryptoNetBalanceViewHolder extends RecyclerView.ViewHolder {
|
||||||
totalEquivalent += nextEquivalent;
|
totalEquivalent += nextEquivalent;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cryptoNetEquivalentTotal.setText(""+totalEquivalent);
|
this.cryptoNetEquivalentTotal.setText(""+totalEquivalent+" "+preferredCurrency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:text="Account Settings"
|
android:text="@string/Account_Settings"
|
||||||
android:textColor="@color/gray"
|
android:textColor="@color/semiTransparentWhite"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
|
|
@ -1,32 +1,67 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingBottom="0dp"
|
android:paddingBottom="0dp"
|
||||||
android:paddingLeft="0dp"
|
android:paddingLeft="25dp"
|
||||||
android:paddingRight="0dp"
|
android:background="@color/white"
|
||||||
|
android:paddingRight="25dp"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin">
|
android:paddingTop="@dimen/activity_vertical_margin">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvMnemonicTitle"
|
android:id="@+id/tvMnemonicTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
|
android:text="@string/Seed"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="20dp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearlayout1"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
android:layout_below="@+id/tvMnemonicTitle"
|
||||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
android:layout_marginTop="15dp"
|
||||||
android:layout_marginTop="10dp"
|
android:background="@drawable/square"
|
||||||
android:text="@string/seed_words"
|
android:padding="10dp">
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvMnemonic"
|
android:id="@+id/tvMnemonic"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="40dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
||||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
||||||
android:background="@drawable/edittext_bg"
|
android:gravity="center"
|
||||||
android:inputType="number"
|
android:text=""
|
||||||
android:maxLines="1"
|
android:background="#00000000"
|
||||||
android:textColor="@color/black" />
|
android:textColor="@color/gray" />
|
||||||
</LinearLayout>
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnCopy"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/linearlayout1"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:text="@string/window_seed_copy"
|
||||||
|
android:textColor="#0099ff"
|
||||||
|
android:background="?android:attr/selectableItemBackground"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
|
@ -32,9 +32,10 @@
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvDescription"
|
app:layout_constraintEnd_toEndOf="@id/tvDescription"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
app:layout_constraintStart_toStartOf="@id/tvDescription"
|
app:layout_constraintStart_toStartOf="@id/tvDescription"
|
||||||
app:layout_constraintEnd_toEndOf="@id/tvDescription"/>
|
app:layout_constraintTop_toBottomOf="@id/tvDescription" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnImportSeed"
|
android:id="@+id/btnImportSeed"
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<RelativeLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/lightGray">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvPatternText"
|
android:id="@+id/tvPatternText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="15dp"/>
|
||||||
|
|
||||||
<com.andrognito.patternlockview.PatternLockView
|
<com.andrognito.patternlockview.PatternLockView
|
||||||
android:id="@+id/patternLockView"
|
android:id="@+id/patternLockView"
|
||||||
android:layout_width="280dp"
|
android:layout_width="280dp"
|
||||||
android:layout_height="280dp"/>
|
android:layout_height="280dp"
|
||||||
</android.support.constraint.ConstraintLayout>
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_below="@+id/tvPatternText"/>
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
|
@ -1,44 +1,39 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<RelativeLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/etNewPin"
|
android:id="@+id/etNewPin"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="26dp"
|
||||||
android:hint="@string/new_pin"
|
android:hint="@string/new_pin"
|
||||||
android:inputType="numberPassword"
|
android:inputType="numberPassword" />
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvNewPinError"
|
android:id="@+id/tvNewPinError"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/red"
|
android:textColor="@color/red"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/etNewPin" />
|
android:layout_below="@+id/etNewPin"/>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/etConfirmPin"
|
android:id="@+id/etConfirmPin"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/tvNewPinError"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:hint="@string/confirm_pin"
|
android:hint="@string/confirm_pin"
|
||||||
android:inputType="numberPassword"
|
android:inputType="numberPassword" />
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tvNewPinError" />
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvConfirmPinError"
|
android:id="@+id/tvConfirmPinError"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/red"
|
android:textColor="@color/red"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/etConfirmPin" />
|
android:layout_below="@+id/etConfirmPin" />
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
|
</RelativeLayout>
|
|
@ -8,19 +8,20 @@
|
||||||
tools:context=".activities.CreateSeedActivity">
|
tools:context=".activities.CreateSeedActivity">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_centerInParent="true">
|
android:layout_centerInParent="true">
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/tilPin"
|
android:id="@+id/tilPin"
|
||||||
android:layout_width="290dp"
|
android:layout_width="330dp"
|
||||||
|
android:layout_marginTop="40dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerHorizontal="true">
|
android:layout_centerHorizontal="true">
|
||||||
|
|
||||||
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
||||||
android:id="@+id/etPin"
|
android:id="@+id/etPin"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="330dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/txt_6_digits_pin"
|
android:hint="@string/txt_6_digits_pin"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/tilPinConfirmation"
|
android:id="@+id/tilPinConfirmation"
|
||||||
android:layout_width="290dp"
|
android:layout_width="330dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/tilPin"
|
android:layout_below="@+id/tilPin"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
@ -39,7 +40,7 @@
|
||||||
|
|
||||||
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
||||||
android:id="@+id/etPinConfirmation"
|
android:id="@+id/etPinConfirmation"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="330dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/txt_6_digits_pin_confirm"
|
android:hint="@string/txt_6_digits_pin_confirm"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
|
@ -48,10 +49,9 @@
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/etSeedWordsLayout"
|
android:id="@+id/etSeedWordsLayout"
|
||||||
android:layout_width="290dp"
|
android:layout_width="330dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/tilPinConfirmation"
|
android:layout_below="@+id/tilPinConfirmation"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
@ -59,16 +59,17 @@
|
||||||
|
|
||||||
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
||||||
android:id="@+id/etSeedWords"
|
android:id="@+id/etSeedWords"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="330dp"
|
||||||
android:layout_height="120dp"
|
android:layout_height="120dp"
|
||||||
android:hint="@string/Seed"
|
android:hint="@string/Seed"
|
||||||
|
android:maxLength="255"
|
||||||
android:inputType="textMultiLine" />
|
android:inputType="textMultiLine" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/tilAccountName"
|
android:id="@+id/tilAccountName"
|
||||||
android:layout_width="290dp"
|
android:layout_width="330dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/etSeedWordsLayout"
|
android:layout_below="@+id/etSeedWordsLayout"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
@ -76,7 +77,7 @@
|
||||||
|
|
||||||
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
|
||||||
android:id="@+id/etAccountName"
|
android:id="@+id/etAccountName"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="330dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:digits="abcdefghijklmnopqrstuvwxyz1234567890 -"
|
android:digits="abcdefghijklmnopqrstuvwxyz1234567890 -"
|
||||||
android:hint="@string/txt_account_name"
|
android:hint="@string/txt_account_name"
|
||||||
|
@ -91,8 +92,9 @@
|
||||||
android:id="@+id/linearlayoutButtons"
|
android:id="@+id/linearlayoutButtons"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_below="@+id/tilAccountName"
|
android:layout_below="@+id/tilAccountName"
|
||||||
android:layout_marginTop="20dp">
|
android:layout_marginTop="40dp">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnCancel"
|
android:id="@+id/btnCancel"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<ScrollView
|
<ScrollView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/white">
|
android:background="@color/white">
|
||||||
|
@ -186,29 +187,43 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvMemoError" />
|
app:layout_constraintTop_toBottomOf="@id/tvMemoError" />
|
||||||
|
|
||||||
<ImageView
|
<View
|
||||||
android:id="@+id/ivCamera"
|
android:id="@+id/viewCamera"
|
||||||
|
android:background="@color/black"
|
||||||
android:layout_width="180dp"
|
android:layout_width="180dp"
|
||||||
android:layout_height="180dp"
|
android:layout_height="180dp"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:layout_marginStart="24dp"
|
android:layout_marginStart="24dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:visibility="gone"
|
||||||
android:src="#666"
|
android:src="#666"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tvScan"
|
app:layout_constraintTop_toBottomOf="@id/tvScan">
|
||||||
android:contentDescription="@string/camera_feed_to_scan_qr" />
|
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<me.dm7.barcodescanner.zxing.ZXingScannerView
|
||||||
|
android:id="@+id/ivCamera"
|
||||||
|
android:layout_width="183dp"
|
||||||
|
android:layout_height="176dp"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:contentDescription="@string/camera_feed_to_scan_qr"
|
||||||
|
android:src="#666"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvScan" />
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fabCloseCamera"
|
android:id="@+id/fabCloseCamera"
|
||||||
android:layout_width="30dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="30dp"
|
android:layout_height="30dp"
|
||||||
app:fabSize="mini"
|
|
||||||
android:layout_marginBottom="165dp"
|
|
||||||
android:layout_marginStart="165dp"
|
android:layout_marginStart="165dp"
|
||||||
|
android:layout_marginBottom="165dp"
|
||||||
app:backgroundTint="@color/send_strong_orange"
|
app:backgroundTint="@color/send_strong_orange"
|
||||||
app:srcCompat="@drawable/ic_close"
|
app:fabSize="mini"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/ivCamera"
|
app:layout_constraintBottom_toBottomOf="@+id/ivCamera"
|
||||||
app:layout_constraintStart_toStartOf="@+id/ivCamera" />
|
app:layout_constraintStart_toStartOf="@+id/ivCamera"
|
||||||
|
app:srcCompat="@drawable/ic_close" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/viewSend"
|
android:id="@+id/viewSend"
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
<string name="You_dont_have_transactions">You dont have transactions</string>
|
<string name="You_dont_have_transactions">You dont have transactions</string>
|
||||||
<string name="You_dont_have_contacts">You dont have contacts</string>
|
<string name="You_dont_have_contacts">You dont have contacts</string>
|
||||||
|
|
||||||
|
<string name="Permission_Denied_WRITE_EXTERNAL_STORAGE">Permission Denied, You cannot use local drive.</string>
|
||||||
|
|
||||||
<string name="account_create_register_or_import">ACCOUNT CREATE/REGISTER OR IMPORT</string>
|
<string name="account_create_register_or_import">ACCOUNT CREATE/REGISTER OR IMPORT</string>
|
||||||
<string name="txt_account_name">Account Name</string>
|
<string name="txt_account_name">Account Name</string>
|
||||||
<string name="time_stamp">Time stamp</string>
|
<string name="time_stamp">Time stamp</string>
|
||||||
|
@ -362,6 +364,9 @@
|
||||||
<string name="email_name">To display a photo for this Contact, enter its Gravatar e-mail here</string>
|
<string name="email_name">To display a photo for this Contact, enter its Gravatar e-mail here</string>
|
||||||
<string name="copied_to_clipboard">Copied to Clipboard</string>
|
<string name="copied_to_clipboard">Copied to Clipboard</string>
|
||||||
|
|
||||||
|
<string name="permission_denied_camera">Permission Denied. You cannot use the QR camera. Please allow this permission in App Settings.</string>
|
||||||
|
<string name="permission_granted_camera">Great!! Now you can use the QR camera.</string>
|
||||||
|
|
||||||
<string name="select">"Select</string>
|
<string name="select">"Select</string>
|
||||||
<string name="are_you_sure">"Are you sure?</string>
|
<string name="are_you_sure">"Are you sure?</string>
|
||||||
<string name="is_already_added">is already added</string>
|
<string name="is_already_added">is already added</string>
|
||||||
|
@ -523,6 +528,7 @@
|
||||||
<string name="Account_already_exists">Account already exists</string>
|
<string name="Account_already_exists">Account already exists</string>
|
||||||
<string name="connection_status">Connection status</string>
|
<string name="connection_status">Connection status</string>
|
||||||
<string name="people_icon">People icon</string>
|
<string name="people_icon">People icon</string>
|
||||||
|
<string name="Account_Settings">Account Settings</string>
|
||||||
<string name="camera_feed_to_scan_qr">Camera feed to scan QR</string>
|
<string name="camera_feed_to_scan_qr">Camera feed to scan QR</string>
|
||||||
<string name="create_account">Create Account</string>
|
<string name="create_account">Create Account</string>
|
||||||
<string name="import_account">Import Account</string>
|
<string name="import_account">Import Account</string>
|
||||||
|
|
|
@ -8,9 +8,9 @@ buildscript {
|
||||||
}
|
}
|
||||||
ext.kotlin_version = '1.2.51'
|
ext.kotlin_version = '1.2.51'
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.1.4'
|
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.60"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.51"
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||||
|
|
Loading…
Reference in a new issue