Compare commits

..

1 commit

Author SHA1 Message Date
Agorise
ba8769f266
Update LICENSE 2019-01-01 10:41:29 -06:00
185 changed files with 2598 additions and 7659 deletions

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2018 AGORISE, LTD. Copyright (c) 2019 AGORISE, LTD.
An International Business Company, Cyprus Reg# ΗΕ375959 An International Business Company, Cyprus Reg# ΗΕ375959
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy

View file

@ -1,8 +1,6 @@
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
@ -11,19 +9,14 @@ kapt {
} }
} }
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
}
android { android {
compileSdkVersion 28 compileSdkVersion 27
defaultConfig { defaultConfig {
applicationId "cy.agorise.crystalwallet" applicationId "cy.agorise.crystalwallet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 27
versionCode 5 versionCode 3
versionName "0.5M.alpha" versionName "0.3M.alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
useSupportLibrary true useSupportLibrary true
@ -35,9 +28,6 @@ android {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
debug {
resValue("string", "PORT_NUMBER", "8081")
}
} }
productFlavors { productFlavors {
@ -62,44 +52,51 @@ dependencies {
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', { androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
exclude group: 'com.android.support', module: 'support-annotations' exclude group: 'com.android.support', module: 'support-annotations'
}) })
implementation( 'com.github.thekhaeng:pushdown-anim-click:1.1.1' ){
exclude group: 'com.android.support'
}
implementation 'com.jaredrummler:material-spinner:1.2.5' implementation 'com.jaredrummler:material-spinner:1.2.5'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:1.1.60"
//testCompile 'com.android.support.test:runner:1.0.1' //testCompile 'com.android.support.test:runner:1.0.1'
implementation 'com.afollestad.material-dialogs:core:0.9.6.0' implementation 'com.afollestad.material-dialogs:core:0.9.6.0' //DTVV Thrusday 31 July 2018
implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:28.0.0' implementation 'com.github.bumptech.glide:glide:4.7.1'
implementation 'com.android.support:design:28.0.0' // Glide v4 uses this new annotation processor -- see https://bumptech.github.io/glide/doc/generatedapi.html
implementation 'com.android.support:cardview-v7:28.0.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'android.arch.lifecycle:runtime:1.1.1' implementation 'android.arch.lifecycle:runtime:1.1.1'
implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'android.arch.paging:runtime:1.0.1' implementation 'android.arch.paging:runtime:1.0.0'
implementation 'com.idescout.sql:sqlscout-server:2.0' implementation 'com.idescout.sql:sqlscout-server:2.0'
implementation 'com.google.code.gson:gson:2.8.4' implementation 'com.google.code.gson:gson:2.8.0'
implementation 'com.squareup.retrofit2:retrofit:2.2.0' implementation 'com.squareup.retrofit2:retrofit:2.2.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0' implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'org.bitcoinj:bitcoinj-core:0.14.3' implementation 'org.bitcoinj:bitcoinj-core:0.14.3'
implementation 'com.neovisionaries:nv-websocket-client:1.30' implementation 'com.neovisionaries:nv-websocket-client:1.30'
implementation 'org.tukaani:xz:1.6'
implementation 'com.jakewharton:butterknife:8.8.1' implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.github.bilthon:graphenej:0.4.6' implementation 'com.github.bilthon:graphenej:0.4.6'
implementation 'com.google.zxing:core:3.3.1'
implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'com.github.sjaramillo10:AnimatedTabLayout:1.0.3'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
implementation 'de.hdodenhof:circleimageview:2.2.0' implementation 'de.hdodenhof:circleimageview:2.2.0'
//testCompile 'junit:junit: 4.12' //testCompile 'junit:junit: 4.12'
testImplementation 'org.mockito:mockito-core:2.19.0' testImplementation 'org.mockito:mockito-core:1.10.19'
implementation 'android.arch.persistence.room:runtime:1.1.1' implementation 'android.arch.persistence.room:runtime:1.1.0'
kapt 'android.arch.persistence.room:runtime:1.1.1'
kapt 'android.arch.persistence.room:compiler:1.1.1'
kapt 'android.arch.persistence.room:runtime:1.1.0'
annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
kapt 'android.arch.lifecycle:compiler:1.1.1' kapt 'android.arch.lifecycle:compiler:1.1.1'
annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
kapt 'android.arch.persistence.room:compiler:1.1.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.1.0'
kapt 'com.jakewharton:butterknife-compiler:8.8.1' kapt 'com.jakewharton:butterknife-compiler:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.github.esafirm.android-image-picker:imagepicker:1.11.1' implementation 'com.github.esafirm.android-image-picker:imagepicker:1.11.1'
implementation 'id.zelory:compressor:2.1.0' implementation 'id.zelory:compressor:2.1.0'
implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.7' implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.7'
@ -111,14 +108,6 @@ dependencies {
exclude group: 'org.json', module: 'json' exclude group: 'org.json', module: 'json'
} }
// Glide dependencies kapt "android.arch.lifecycle:compiler:1.1.1"
implementation 'com.github.bumptech.glide:glide:4.8.0' kapt "android.arch.persistence.room:compiler:1.1.0"
kapt 'com.github.bumptech.glide:compiler:4.8.0'
// Android Debug Database
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
implementation 'com.google.zxing:core:3.3.1'
implementation 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
testImplementation 'org.testng:testng:6.9.6'
} }

View file

@ -23,10 +23,3 @@
# If you keep the line number information, uncomment this to # If you keep the line number information, uncomment this to
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

View file

@ -7,7 +7,6 @@
<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"
@ -40,10 +39,6 @@
</activity> </activity>
<activity android:name=".activities.AccountSeedsManagementActivity" > <activity android:name=".activities.AccountSeedsManagementActivity" >
</activity> </activity>
<activity android:name=".activities.AccountSeedSettingsActivity"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan">
</activity>
<activity android:name=".activities.ImportSeedActivity" > <activity android:name=".activities.ImportSeedActivity" >
</activity> </activity>
<activity android:name=".activities.SendTransactionActivity" > <activity android:name=".activities.SendTransactionActivity" >

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View file

@ -1,134 +0,0 @@
package cy.agorise.crystalwallet.activities;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.fragments.BitsharesSettingsFragment;
import cy.agorise.crystalwallet.fragments.GeneralAccountSeedCoinSettingsFragment;
import cy.agorise.crystalwallet.fragments.GeneralAccountSeedFragment;
import cy.agorise.crystalwallet.fragments.GeneralCryptoNetAccountSettingsFragment;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
/**
* Created by henry varona on 10/29/18.
*
*/
public class AccountSeedSettingsActivity extends AppCompatActivity{
@BindView(R.id.ivGoBack)
public ImageView ivGoBack;
@BindView(R.id.pager)
public ViewPager mPager;
public SettingsPagerAdapter settingsPagerAdapter;
@BindView(R.id.tvBuildVersion)
public TextView tvBuildVersion;
@BindView(R.id.tabs)
public TabLayout tabs;
private AccountSeed accountSeed;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.account_seed_activity_settings);
ButterKnife.bind(this);
final AccountSeedSettingsActivity thisActivity = this;
long accountSeedId = getIntent().getLongExtra("SEED_ID",-1);
if (accountSeedId > -1) {
AccountSeedViewModel accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class);
accountSeedViewModel.loadSeed(accountSeedId);
LiveData<AccountSeed> accountSeedLiveData = accountSeedViewModel.getAccountSeed();
accountSeedLiveData.observe(this, new Observer<AccountSeed>() {
@Override
public void onChanged(@Nullable AccountSeed accountSeed) {
thisActivity.accountSeed = accountSeed;
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(settingsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager));
}
});
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Sets AppBar animation
Glide.with(this)
.load(R.drawable.appbar_background)
.apply(new RequestOptions().centerCrop())
.into(ivAppBarAnimation);
} else {
this.finish();
}
}
private class SettingsPagerAdapter extends FragmentStatePagerAdapter {
SettingsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return GeneralAccountSeedFragment.newInstance(accountSeed.getId());
case 1:
return GeneralAccountSeedCoinSettingsFragment.newInstance(accountSeed.getId());
}
return null;
}
@Override
public int getCount() {
int tabCount = 2;
return tabCount;
}
}
@OnClick(R.id.ivGoBack)
public void goBack(){
onBackPressed();
}
}

View file

@ -14,9 +14,6 @@ import android.view.SurfaceView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
@ -40,13 +37,12 @@ public class AccountSettingsActivity extends AppCompatActivity{
public SettingsPagerAdapter settingsPagerAdapter; public SettingsPagerAdapter settingsPagerAdapter;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.tvBuildVersion) @BindView(R.id.tvBuildVersion)
public TextView tvBuildVersion; public TextView tvBuildVersion;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -56,11 +52,27 @@ public class AccountSettingsActivity extends AppCompatActivity{
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
// Sets AppBar animation // Appbar animation
Glide.with(this) mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
.load(R.drawable.appbar_background) @Override
.apply(new RequestOptions().centerCrop()) public void surfaceCreated(SurfaceHolder surfaceHolder) {
.into(ivAppBarAnimation); //Log.d(TAG,"surfaceCreated");
MediaPlayer mediaPlayer = MediaPlayer.create(AccountSettingsActivity.this, R.raw.appbar_background);
mediaPlayer.setDisplay(mSurfaceView.getHolder());
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//Log.d(TAG,"surfaceChanged");
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//Log.d(TAG,"surfaceDestroyed");
}
});
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager()); settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(settingsPagerAdapter); mPager.setAdapter(settingsPagerAdapter);

View file

@ -18,12 +18,10 @@ import android.provider.MediaStore;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import com.esafirm.imagepicker.features.ImagePicker; import com.esafirm.imagepicker.features.ImagePicker;
import com.esafirm.imagepicker.model.Image; import com.esafirm.imagepicker.model.Image;
import com.thekhaeng.pushdownanim.PushDownAnim;
//import com.nicdahlquist.pngquant.LibPngQuant; //import com.nicdahlquist.pngquant.LibPngQuant;
import java.io.File; import java.io.File;
@ -57,11 +55,8 @@ public class AccountsActivity extends AppCompatActivity {
@BindView(R.id.tvClose) @BindView(R.id.tvClose)
TextView tvClose; TextView tvClose;
//@BindView(R.id.vAccountList) @BindView(R.id.vAccountList)
//CryptoNetAccountListView vAccountList; CryptoNetAccountListView vAccountList;
@BindView(R.id.vAccountSeedList)
AccountSeedListView vAccountSeedList;
@BindView(R.id.user_img) @BindView(R.id.user_img)
CircleImageView userImg; CircleImageView userImg;
@ -79,29 +74,14 @@ public class AccountsActivity extends AppCompatActivity {
setContentView(R.layout.activity_accounts); setContentView(R.layout.activity_accounts);
ButterKnife.bind(this); ButterKnife.bind(this);
/* CryptoNetAccountListViewModel crytpoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
* Integration of library with button efects LiveData<List<CryptoNetAccount>> accountData = crytpoNetAccountListViewModel.getCryptoNetAccounts();
* */ vAccountList.setData(null);
PushDownAnim.setPushDownAnimTo(fabAddAccount)
.setOnClickListener( new View.OnClickListener(){ accountData.observe(this, new Observer<List<CryptoNetAccount>>() {
@Override @Override
public void onClick( View view ){ public void onChanged(List<CryptoNetAccount> cryptoNetAccounts) {
goToAddAccount(); vAccountList.setData(cryptoNetAccounts);
}
} );
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);
LiveData<List<AccountSeed>> accountSeedLD = accountSeedListViewModel.getAccountSeedList();
//CryptoNetAccountListViewModel crytpoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
//LiveData<List<CryptoNetAccount>> accountData = crytpoNetAccountListViewModel.getCryptoNetAccounts();
vAccountSeedList.setData(null);
accountSeedLD.observe(this, new Observer<List<AccountSeed>>() {
@Override
public void onChanged(List<AccountSeed> accountsSeeds) {
vAccountSeedList.setData(accountsSeeds);
} }
}); });

View file

@ -10,14 +10,10 @@ 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.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
@ -33,12 +29,10 @@ public class BackupSeedActivity extends AppCompatActivity {
@BindView(R.id.tvBrainKey) @BindView(R.id.tvBrainKey)
TextView textfieldBrainkey; TextView textfieldBrainkey;
@BindView(R.id.btnOK) @BindView(R.id.btnCancel)
Button btnOk; Button btnOk;
@BindView(R.id.btnCopy) @BindView(R.id.btnCopy)
Button btnCopy; Button btnCopy;
@BindView(R.id.btnCancel)
Button btnCancel;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -47,42 +41,6 @@ public class BackupSeedActivity extends AppCompatActivity {
ButterKnife.bind(this); ButterKnife.bind(this);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnCancel)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
btnCancelClick();
}
} );
PushDownAnim.setPushDownAnimTo(btnOk)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
btnOkClick();
}
} );
PushDownAnim.setPushDownAnimTo(btnCopy)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
btnCopyClick();
}
} );
/*
* If comes from new account creation hide the cancel button
* */
Bundle b = getIntent().getExtras();
boolean newAccount = b.getBoolean("newAccount");
if(newAccount ){
ViewGroup layout = (ViewGroup) btnOk.getParent();
if(null!=layout) //for safety only as you are doing onClick
layout.removeView(btnOk);
//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,14 +56,6 @@ public class BackupSeedActivity extends AppCompatActivity {
accountSeedViewModel.loadSeed(seedId); accountSeedViewModel.loadSeed(seedId);
} else { } else {
/*
*
* The first time you create the account, the "seed" is showed propertly in this window,
* but when you want to check it again the "seed" does not exist anymore and
* for this cause the program gets into this point and finish the window
*
* */
finish(); finish();
} }
} }

View file

@ -8,6 +8,9 @@ import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface;
import android.media.MediaPlayer;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
@ -17,10 +20,18 @@ import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.util.Pair; import android.util.Pair;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator; import android.view.animation.LinearInterpolator;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
@ -37,6 +48,7 @@ import cy.agorise.crystalwallet.fragments.MerchantsFragment;
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.fragments.TransactionsFragment; import cy.agorise.crystalwallet.fragments.TransactionsFragment;
import cy.agorise.crystalwallet.views.natives.GIFView;
import de.hdodenhof.circleimageview.CircleImageView; import de.hdodenhof.circleimageview.CircleImageView;
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel; import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
@ -61,8 +73,8 @@ public class BoardActivity extends CustomActivity {
@BindView(R.id.fabAddContact) @BindView(R.id.fabAddContact)
public FloatingActionButton fabAddContact; public FloatingActionButton fabAddContact;
@BindView(R.id.ivAppBarAnimation) @BindView(R.id.imagevieGIF)
ImageView ivAppBarAnimation; public GIFView imagevieGIF;
public BoardPagerAdapter boardAdapter; public BoardPagerAdapter boardAdapter;
@ -72,6 +84,9 @@ public class BoardActivity extends CustomActivity {
*/ */
long cryptoNetAccountId; long cryptoNetAccountId;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.toolbar_user_img) @BindView(R.id.toolbar_user_img)
public CircleImageView userImage; public CircleImageView userImage;
@ -95,11 +110,82 @@ public class BoardActivity extends CustomActivity {
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
// Sets AppBar animation /*
Glide.with(this) * Set the bubbles animation
.load(R.drawable.appbar_background) * */
.apply(new RequestOptions().centerCrop()) //imagevieGIF.centerCrop();
.into(ivAppBarAnimation); //imagevieGIF.load(R.raw.burbujas);
/*
* Listener tabLayout to resalt text when clicked
* */
final TabLayout tabLayoutFinal = tabLayout;
// tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
// @Override
// public void onTabSelected(final TabLayout.Tab tab) {
//
// globalActivity.runOnUiThread(new Runnable() {
// @Override
// public void run() {
//
// LinearLayout tabLayout = (LinearLayout)((ViewGroup) tabLayoutFinal.getChildAt(0)).getChildAt(tab.getPosition());
// tabLayout.setBackgroundColor(Color.TRANSPARENT);
// TextView tabTextView = (TextView) tabLayout.getChildAt(1);
// //tabTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP ,50);
// Spannable WordtoSpan = new SpannableString(tabTextView.getText());
// WordtoSpan.setSpan(new ForegroundColorSpan(Color.WHITE), 0, tabTextView.getText().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// tabTextView.setText(WordtoSpan);
// tabTextView.setTypeface(tabTextView.getTypeface(), Typeface.BOLD);
// }
// });
// }
//
// @Override
// public void onTabUnselected(final TabLayout.Tab tab) {
//
// globalActivity.runOnUiThread(new Runnable() {
// @Override
// public void run() {
//
// LinearLayout tabLayout = (LinearLayout)((ViewGroup) tabLayoutFinal.getChildAt(0)).getChildAt(tab.getPosition());
// TextView tabTextView = (TextView) tabLayout.getChildAt(1);
// //tabTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP ,50);
// Spannable WordtoSpan = new SpannableString(tabTextView.getText());
// WordtoSpan.setSpan(new ForegroundColorSpan(globalActivity.getResources().getColor(R.color.lightGrayClear)), 0, tabTextView.getText().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// tabTextView.setText(WordtoSpan);
// tabTextView.setTypeface(tabTextView.getTypeface(), Typeface.NORMAL);
// }
// });
// }
//
// @Override
// public void onTabReselected(TabLayout.Tab tab) {
//
//
// }
// });
// Appbar animation
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//Log.d(TAG,"surfaceCreated");
MediaPlayer mediaPlayer = MediaPlayer.create(BoardActivity.this, R.raw.appbar_background);
mediaPlayer.setDisplay(mSurfaceView.getHolder());
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//Log.d(TAG,"surfaceChanged");
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//Log.d(TAG,"surfaceDestroyed");
}
});
boardAdapter = new BoardPagerAdapter(getSupportFragmentManager()); boardAdapter = new BoardPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(boardAdapter); mPager.setAdapter(boardAdapter);

View file

@ -3,17 +3,18 @@ package cy.agorise.crystalwallet.activities
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.support.design.widget.TextInputEditText
import android.text.Editable import android.text.Editable
import android.text.TextWatcher
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import com.thekhaeng.pushdownanim.PushDownAnim import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.OnTextChanged
import com.vincent.filepicker.ToastUtil import com.vincent.filepicker.ToastUtil
import cy.agorise.crystalwallet.R import cy.agorise.crystalwallet.R
import cy.agorise.crystalwallet.dialogs.material.* import cy.agorise.crystalwallet.dialogs.material.*
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests
import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest
import cy.agorise.crystalwallet.requestmanagers.ValidateExistBitsharesAccountRequest
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.interfaces.UIValidatorListener import cy.agorise.crystalwallet.viewmodels.validators.customImpl.interfaces.UIValidatorListener
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation.OnAccountExist import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation.OnAccountExist
@ -38,6 +39,11 @@ class CreateSeedActivity : CustomActivity() {
* */ * */
setContentView(R.layout.create_seed) setContentView(R.layout.create_seed)
/*
* Initialice butterknife MVC
* */
ButterKnife.bind(this)
/* /*
* Add the controls to the validator * Add the controls to the validator
* */ * */
@ -45,14 +51,6 @@ class CreateSeedActivity : CustomActivity() {
this.fieldsValidator.add(tietPinConfirmation) this.fieldsValidator.add(tietPinConfirmation)
this.fieldsValidator.add(tietAccountName) this.fieldsValidator.add(tietAccountName)
/*
* Integration of library with button effects
* */
PushDownAnim.setPushDownAnimTo(btnCancel)
.setOnClickListener { finish() }
PushDownAnim.setPushDownAnimTo(btnCreate)
.setOnClickListener { createSeed() }
/* /*
* Validations listener * Validations listener
* */ * */
@ -89,14 +87,20 @@ class CreateSeedActivity : CustomActivity() {
} }
} }
//Create the pin double validation /*
* Create the pin double validation
* */
val pinDoubleConfirmationValidationField = PinDoubleConfirmationValidationField(this, tietPin, tietPinConfirmation, uiValidatorListener) val pinDoubleConfirmationValidationField = PinDoubleConfirmationValidationField(this, tietPin, tietPinConfirmation, uiValidatorListener)
// Listener for the validation for success or fail /*
* Listener for the validation for success or fail
* */
tietPin?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field tietPin?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field
tietPinConfirmation?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field tietPinConfirmation?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field
// Account name validator /*
* Account name validator
* */
val bitsharesAccountNameValidation = BitsharesAccountNameValidation(this, tietAccountName, uiValidatorListener) val bitsharesAccountNameValidation = BitsharesAccountNameValidation(this, tietAccountName, uiValidatorListener)
val onAccountExist = object : OnAccountExist { val onAccountExist = object : OnAccountExist {
override fun onAccountExists() { override fun onAccountExists() {
@ -110,49 +114,58 @@ class CreateSeedActivity : CustomActivity() {
tietAccountName?.setUiValidator(bitsharesAccountNameValidation) tietAccountName?.setUiValidator(bitsharesAccountNameValidation)
/*This button should not be enabled till all the fields be correctly filled*/ /*This button should not be enabled till all the fields be correctly filled*/
btnCreate.isEnabled = false disableCreate()
// Set the focus on the first field and show keyboard /*
* Set the focus on the fisrt field and show keyboard
* */
tilPin?.requestFocus() tilPin?.requestFocus()
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(tilPin, InputMethodManager.SHOW_IMPLICIT) imm.showSoftInput(tilPin, InputMethodManager.SHOW_IMPLICIT)
}
tietPin.afterTextChanged { @OnTextChanged(value = R.id.tietPin, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
internal fun afterPinChanged(editable: Editable) {
this.fieldsValidator.validate() this.fieldsValidator.validate()
/*
* Validate continue to create account
* */
validateFieldsToContinue()
}
@OnTextChanged(value = R.id.tietPinConfirmation, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
internal fun afterPinConfirmationChanged(editable: Editable) {
this.fieldsValidator.validate()
/*
* Validate continue to create account
* */
validateFieldsToContinue() validateFieldsToContinue()
} }
tietPinConfirmation.afterTextChanged { @OnTextChanged(value = R.id.tietAccountName, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
internal fun afterAccountNameChanged(editable: Editable) {
this.fieldsValidator.validate() this.fieldsValidator.validate()
/*
* Validate continue to create account
* */
validateFieldsToContinue() validateFieldsToContinue()
} }
tietAccountName.afterTextChanged { @OnClick(R.id.btnCancel)
this.fieldsValidator.validate() fun cancel() {
validateFieldsToContinue()
} /*
* Exit of the activity
btnCancel.setOnClickListener { finish() } * */
btnCreate.setOnClickListener { createSeed() } this.finish()
}
/**
* Extension function to easily add a text watcher
*/
fun TextInputEditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object :TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
})
} }
@OnClick(R.id.btnCreate)
fun createSeed() { fun createSeed() {
/* /*
@ -168,10 +181,11 @@ class CreateSeedActivity : CustomActivity() {
questionDialog.setOnPositive(object : PositiveResponse{ questionDialog.setOnPositive(object : PositiveResponse{
override fun onPositive() { override fun onPositive() {
// Make request to create a bitshares account // Make request to create a bitshare account
var accountName:String = tietAccountName?.getText().toString().trim() var accountName:String = tietAccountName?.getText().toString().trim()
val request = ValidateCreateBitsharesAccountRequest(accountName, applicationContext) val request = ValidateCreateBitsharesAccountRequest(accountName, applicationContext)
//DTVV: Friday 27 July 2018
//Makes dialog to tell the user that the account is been created //Makes dialog to tell the user that the account is been created
val creatingAccountMaterialDialog = CrystalDialog(globalActivity) val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_DialogMessage)) creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_DialogMessage))
@ -186,12 +200,11 @@ 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) {
ToastUtil.getInstance(globalActivity).showToast(globalActivity.getString(R.string.Account_already_exists)) ToastUtil.getInstance(globalActivity).showToast(globalActivity.getString(R.string.Account_already_exists))
btnCreate.isEnabled = false disableCreate()
} }
else { else {
fieldsValidator.validate() fieldsValidator.validate()
@ -200,7 +213,10 @@ class CreateSeedActivity : CustomActivity() {
(object : Thread() { (object : Thread() {
override fun run() { override fun run() {
/* Run thread*/
/*
*
* Run thread*/
CryptoNetInfoRequests.getInstance().addRequest(request) CryptoNetInfoRequests.getInstance().addRequest(request)
} }
}).start() }).start()
@ -226,7 +242,85 @@ class CreateSeedActivity : CustomActivity() {
result = true //Validation is correct result = true //Validation is correct
} }
// If the result is true so the user can continue to the creation of the account
btnCreate.isEnabled = result /*
* If the result is true so the user can continue to the creation of the account
* */
if (result) {
/*
* Show the dialog for connection with the server
* */
val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_Server_validation))
creatingAccountMaterialDialog.progress()
creatingAccountMaterialDialog.show()
/*
* Validate the account does not exists
* */
val request = ValidateExistBitsharesAccountRequest(tietAccountName?.text.toString())
request.setListener {
/*
* Dismiss the dialog of loading
* */
creatingAccountMaterialDialog.dismiss()
if (request.accountExists) {
/*
* The account exists and is not valid
* */
tietAccountName.fieldValidatorModel.setInvalid()
tietAccountName.fieldValidatorModel.message = tietAccountName.resources.getString(R.string.account_name_already_exist)
/*
* Disaible button create
* */
disableCreate()
} else {
/*
* Passed all validations
* */
tietAccountName.fieldValidatorModel.setValid()
/*
* Enable button create
* */
enableCreate()
}
}
CryptoNetInfoRequests.getInstance().addRequest(request)
} else {
/*
* Disaible button create
* */
disableCreate()
}
}
/*
* Enable create button
* */
private fun enableCreate() {
runOnUiThread(Runnable {
btnCreate?.setBackgroundColor(resources.getColor(R.color.colorPrimary))
btnCreate?.setEnabled(true)
})
}
/*
* Disable create button
* */
private fun disableCreate() {
runOnUiThread(Runnable {
btnCreate?.setEnabled(false)
btnCreate?.setBackground(resources.getDrawable(R.drawable.disable_style))
})
} }
} }

View file

@ -2,11 +2,15 @@ package cy.agorise.crystalwallet.activities;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.content.Context;
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.widget.TextView; import android.widget.TextView;
import org.w3c.dom.Text;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import butterknife.BindView; import butterknife.BindView;
@ -43,7 +47,7 @@ public class CryptoCoinTransactionReceiptActivity extends AppCompatActivity {
if (this.cryptoCoinTransactionId != -1) { if (this.cryptoCoinTransactionId != -1) {
db = CrystalDatabase.getAppDatabase(this); db = CrystalDatabase.getAppDatabase(this);
this.cryptoCoinTransactionLiveData = db.transactionDao().getByIdLiveData(this.cryptoCoinTransactionId); this.cryptoCoinTransactionLiveData = db.transactionDao().getById(this.cryptoCoinTransactionId);
this.cryptoCoinTransactionLiveData.observe(this, new Observer<CryptoCoinTransaction>() { this.cryptoCoinTransactionLiveData.observe(this, new Observer<CryptoCoinTransaction>() {
@Override @Override

View file

@ -18,16 +18,12 @@ import android.view.SurfaceView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.fragments.BackupsSettingsFragment; import cy.agorise.crystalwallet.fragments.BackupsSettingsFragment;
import cy.agorise.crystalwallet.fragments.BitsharesSettingsFragment; import cy.agorise.crystalwallet.fragments.BitsharesSettingsFragment;
import cy.agorise.crystalwallet.fragments.CryptoNetAccountActivationSettingsFragment;
import cy.agorise.crystalwallet.fragments.GeneralCryptoNetAccountSettingsFragment; import cy.agorise.crystalwallet.fragments.GeneralCryptoNetAccountSettingsFragment;
import cy.agorise.crystalwallet.fragments.GeneralSettingsFragment; import cy.agorise.crystalwallet.fragments.GeneralSettingsFragment;
import cy.agorise.crystalwallet.fragments.SecuritySettingsFragment; import cy.agorise.crystalwallet.fragments.SecuritySettingsFragment;
@ -49,6 +45,8 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
public SettingsPagerAdapter settingsPagerAdapter; public SettingsPagerAdapter settingsPagerAdapter;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.tvBuildVersion) @BindView(R.id.tvBuildVersion)
public TextView tvBuildVersion; public TextView tvBuildVersion;
@ -58,9 +56,6 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
private CryptoNetAccount cryptoNetAccount; private CryptoNetAccount cryptoNetAccount;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -98,11 +93,27 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
// Sets AppBar animation // Appbar animation
Glide.with(this) mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
.load(R.drawable.appbar_background) @Override
.apply(new RequestOptions().centerCrop()) public void surfaceCreated(SurfaceHolder surfaceHolder) {
.into(ivAppBarAnimation); //Log.d(TAG,"surfaceCreated");
MediaPlayer mediaPlayer = MediaPlayer.create(CryptoNetAccountSettingsActivity.this, R.raw.appbar_background);
mediaPlayer.setDisplay(mSurfaceView.getHolder());
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//Log.d(TAG,"surfaceChanged");
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//Log.d(TAG,"surfaceDestroyed");
}
});
} else { } else {

View file

@ -1,35 +1,34 @@
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.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import org.jetbrains.annotations.NotNull;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; 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.enums.CryptoNet;
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial; import cy.agorise.crystalwallet.enums.SeedType;
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse; import cy.agorise.crystalwallet.manager.BitsharesAccountManager;
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse; import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog; import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount;
import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
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.ImportBitsharesAccountRequest; import cy.agorise.crystalwallet.requestmanagers.ImportBackupRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel; import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
import cy.agorise.crystalwallet.viewmodels.GrapheneAccountInfoViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator; import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator;
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener; import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField; import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
@ -41,30 +40,23 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@BindView(R.id.etPin) @BindView(R.id.etPin)
EditText etPin; EditText etPin;
@BindView(R.id.tvPinError)
@BindView(R.id.txtErrorPIN) TextView tvPinError;
TextView txtErrorPIN;
@BindView(R.id.txtErrorAccount)
TextView txtErrorAccount;
//@BindView(R.id.tvPinError)
//TextView tvPinError;
@BindView(R.id.etPinConfirmation) @BindView(R.id.etPinConfirmation)
EditText etPinConfirmation; EditText etPinConfirmation;
//@BindView(R.id.tvPinConfirmationError) @BindView(R.id.tvPinConfirmationError)
//TextView tvPinConfirmationError; TextView tvPinConfirmationError;
@BindView(R.id.etSeedWords) @BindView(R.id.etSeedWords)
EditText etSeedWords; EditText etSeedWords;
//@BindView(R.id.tvSeedWordsError) @BindView(R.id.tvSeedWordsError)
//TextView tvSeedWordsError; TextView tvSeedWordsError;
@BindView (R.id.etAccountName) @BindView (R.id.etAccountName)
EditText etAccountName; EditText etAccountName;
//@BindView(R.id.tvAccountNameError) @BindView(R.id.tvAccountNameError)
//TextView tvAccountNameError; TextView tvAccountNameError;
@BindView(R.id.btnImport) @BindView(R.id.btnImport)
Button btnImport; Button btnImport;
@ -72,16 +64,6 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@BindView(R.id.btnCancel) @BindView(R.id.btnCancel)
Button btnCancel; Button btnCancel;
final Activity activity = this;
/*
* Flag to check correct PIN equality
* */
private boolean pinsOK = false;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -89,213 +71,12 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
ButterKnife.bind(this); ButterKnife.bind(this);
/* btnImport.setEnabled(false);
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnCancel)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
cancel();
}
} );
PushDownAnim.setPushDownAnimTo(btnImport)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
importSeed();
}
} );
/*
* 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) {
/*
* Validate that PINs are equals
* */
validatePINS();
/*
* If all is ready to continue enable the button, contrarie case disable it
* */
if(allFieldsAreOK()){
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) {
/*
* Validate that PINs are equals
* */
validatePINS();
/*
* If all is ready to continue enable the button, contrarie case disable it
* */
if(allFieldsAreOK()){
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) {
/*
* Validate that PINs are equals
* */
validatePINS();
/*
* If all is ready to continue enable the button, contrarie case disable it
* */
if(allFieldsAreOK()){
enableCreate();
}
else{
disableCreate();
}
/*
* Hide error field
* */
clearErrors();
}
});
/*
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) {
//
// Validate that PINs are equals
//
validatePINS();
//
// If all is ready to continue enable the button, contrarie case disable it
//
if(allFieldsAreOK()){
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);
} }
private void clearErrors(){
txtErrorPIN.setVisibility(View.INVISIBLE);
txtErrorAccount.setVisibility(View.INVISIBLE);
}
/*
* Validate that PINs are equals
* */
private void validatePINS(){
final String pin = etPin.getText().toString().trim();
final String confirmoPIN = etPinConfirmation.getText().toString().trim();
if(!pin.isEmpty() && !confirmoPIN.isEmpty()){
if(pin.compareTo(confirmoPIN)!=0){
pinsOK = false;
txtErrorPIN.setVisibility(View.VISIBLE);
}
else{
pinsOK = true;
clearErrors();
}
}
else{
pinsOK = false;
clearErrors();
}
}
/*
* Method to validate if all the fields are fill and correctly
* */
private boolean allFieldsAreOK(){
boolean complete = false;
if( etPin.getText().toString().trim().compareTo("")!=0 &&
etPinConfirmation.getText().toString().trim().compareTo("")!=0 &&
etSeedWords.getText().toString().trim().compareTo("")!=0 /*&&
etAccountName.getText().toString().trim().compareTo("")!=0*/){
if(pinsOK){
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) {
@ -313,11 +94,13 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
void afterSeedWordsChanged(Editable editable) { void afterSeedWordsChanged(Editable editable) {
this.importSeedValidator.validate(); this.importSeedValidator.validate();
} }
/*@OnTextChanged(value = R.id.etAccountName,
@OnTextChanged(value = R.id.etAccountName,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterAccountNameChanged(Editable editable) { void afterAccountNameChanged(Editable editable) {
this.importSeedValidator.validate(); this.importSeedValidator.validate();
}*/ }
@OnClick(R.id.btnCancel) @OnClick(R.id.btnCancel)
public void cancel(){ public void cancel(){
@ -330,133 +113,33 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
if (this.importSeedValidator.isValid()) { if (this.importSeedValidator.isValid()) {
/* final ValidateImportBitsharesAccountRequest validatorRequest =
* Question if continue new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
* */
final QuestionDialog questionDialog = new QuestionDialog(activity);
questionDialog.setText(activity.getString(R.string.question_continue));
questionDialog.setOnNegative(new NegativeResponse() {
@Override
public void onNegative(@NotNull DialogMaterial dialogMaterial) {
}
});
questionDialog.setOnPositive(new PositiveResponse() {
@Override
public void onPositive() {
/*
* Loading dialog
* */
final CrystalLoading crystalLoading = new CrystalLoading(activity);
crystalLoading.show();
/*
* Final service connection
* */
finalStep(crystalLoading);
/*
* Validate mnemonic with the server
* */
/*final ImportBitsharesAccountRequest request = new ImportBitsharesAccountRequest(etSeedWords.getText().toString().trim(),activity);
request.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if(request.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED)){
//Correct
finalStep(crystalLoading);
}
else{
crystalLoading.dismiss();
txtErrorAccount.setVisibility(View.VISIBLE);
txtErrorAccount.setText(activity.getResources().getString(R.string.error_invalid_account));
}
}
});
CryptoNetInfoRequests.getInstance().addRequest(request);*/
}
});
questionDialog.show();
}
}
private void finalStep(final CrystalLoading crystalLoading){
final ImportSeedActivity thisActivity = this;
final ImportBitsharesAccountRequest validatorRequest =
new ImportBitsharesAccountRequest(etSeedWords.getText().toString(), getApplicationContext(), true);
validatorRequest.setListener(new CryptoNetInfoRequestListener() { validatorRequest.setListener(new CryptoNetInfoRequestListener() {
@Override @Override
public void onCarryOut() { public void onCarryOut() {
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
/* String errorText = "An error ocurred attempting to import the account";
* Hide the loading dialog
* */
crystalLoading.dismiss();
if (!validatorRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
switch (validatorRequest.getStatus()){ switch (validatorRequest.getStatus()){
case PETITION_FAILED: case PETITION_FAILED:
case NO_INTERNET: case NO_INTERNET:
case NO_SERVER_CONNECTION: case NO_SERVER_CONNECTION:
activity.runOnUiThread(new Runnable() { errorText = "There was an error with the connection. Try again later";
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.NO_SERVER_CONNECTION));
}
});
break; break;
case ACCOUNT_DOESNT_EXIST: case ACCOUNT_DOESNT_EXIST:
activity.runOnUiThread(new Runnable() { errorText = "The account doesn't exists";
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.ACCOUNT_DOESNT_EXIST));
}
});
break; break;
case BAD_SEED: case BAD_SEED:
activity.runOnUiThread(new Runnable() { errorText = "The seed is not valid";
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.BAD_SEED));
}
});
break; break;
case NO_ACCOUNT_DATA: case NO_ACCOUNT_DATA:
activity.runOnUiThread(new Runnable() { errorText = "The account doesn't have any data";
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.NO_ACCOUNT_DATA));
}
});
break; break;
default:
txtErrorAccount.setText(activity.getResources().getString(R.string.ERROR_UNRECOGNIZABLE));
} }
activity.runOnUiThread(new Runnable() { Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
@Override
public void run() {
txtErrorAccount.setVisibility(View.VISIBLE);
}
});
//Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
} else { } else {
Intent intent = new Intent(thisActivity, BoardActivity.class); Intent intent = new Intent(thisActivity, BoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
@ -464,9 +147,33 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
} }
} }
}); });
/*CryptoNetInfoRequests.getInstance().addRequest(validatorRequest);
AccountSeed seed = new AccountSeed();
//TODO verify if words are already in the db
//TODO check if name has been asigned to other seed
seed.setMasterSeed(etSeedWords.getText().toString());
seed.setName(etAccountName.getText().toString());
seed.setType(SeedType.BRAINKEY);
accountSeedViewModel.addSeed(seed);
CryptoNetAccountViewModel cryptoNetAccountViewModel = ViewModelProviders.of(this).get(CryptoNetAccountViewModel.class);
GrapheneAccountInfoViewModel grapheneAccountInfoViewModel = ViewModelProviders.of(this).get(GrapheneAccountInfoViewModel.class);
CryptoNetAccount cryptoNetAccount = new CryptoNetAccount();
cryptoNetAccount.setSeedId(seed.getId());
cryptoNetAccount.setAccountIndex(0);
cryptoNetAccount.setCryptoNet(cy.agorise.crystalwallet.enums.CryptoNet.BITSHARES);
cryptoNetAccountViewModel.addCryptoNetAccount(cryptoNetAccount);
GrapheneAccountInfo grapheneAccountInfo = new GrapheneAccountInfo(cryptoNetAccount.getId());
grapheneAccountInfo.setName(etAccountName.getText().toString());
grapheneAccountInfoViewModel.addGrapheneAccountInfo(grapheneAccountInfo);
this.finish();*/
CryptoNetInfoRequests.getInstance().addRequest(validatorRequest); CryptoNetInfoRequests.getInstance().addRequest(validatorRequest);
} }
}
@Override @Override
public void onValidationSucceeded(final ValidationField field) { public void onValidationSucceeded(final ValidationField field) {
@ -476,19 +183,19 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
public void run() { public void run() {
if (field.getView() == etPin) { if (field.getView() == etPin) {
//tvPinError.setText(""); tvPinError.setText("");
} else if (field.getView() == etPinConfirmation){ } else if (field.getView() == etPinConfirmation){
//tvPinConfirmationError.setText(""); tvPinConfirmationError.setText("");
} else if (field.getView() == etAccountName){ } else if (field.getView() == etAccountName){
//tvAccountNameError.setText(""); tvAccountNameError.setText("");
} else if (field.getView() == etSeedWords){ } else if (field.getView() == etSeedWords){
//tvSeedWordsError.setText(""); tvSeedWordsError.setText("");
} }
if (activity.importSeedValidator.isValid()){ if (activity.importSeedValidator.isValid()){
enableCreate(); btnImport.setEnabled(true);
} else { } else {
disableCreate(); btnImport.setEnabled(false);
} }
} }
@ -498,40 +205,13 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@Override @Override
public void onValidationFailed(ValidationField field) { public void onValidationFailed(ValidationField field) {
if (field.getView() == etPin) { if (field.getView() == etPin) {
//tvPinError.setText(field.getMessage()); tvPinError.setText(field.getMessage());
} else if (field.getView() == etPinConfirmation){ } else if (field.getView() == etPinConfirmation){
//tvPinConfirmationError.setText(field.getMessage()); tvPinConfirmationError.setText(field.getMessage());
} else if (field.getView() == etAccountName){ } else if (field.getView() == etAccountName){
//tvAccountNameError.setText(field.getMessage()); tvAccountNameError.setText(field.getMessage());
} else if (field.getView() == etSeedWords){ } else if (field.getView() == etSeedWords){
//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));
}
});
}
} }

View file

@ -2,43 +2,55 @@ 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.media.MediaPlayer;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
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.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.Toast;
import com.bumptech.glide.Glide; import java.util.List;
import com.bumptech.glide.request.RequestOptions;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor; import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
import cy.agorise.crystalwallet.application.CrystalApplication;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.dialogs.material.ToastIt;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.fragments.ImportAccountOptionsFragment; import cy.agorise.crystalwallet.fragments.ImportAccountOptionsFragment;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.network.CryptoNetManager;
import cy.agorise.crystalwallet.randomdatagenerators.RandomCryptoCoinBalanceGenerator;
import cy.agorise.crystalwallet.randomdatagenerators.RandomCryptoNetAccountGenerator;
import cy.agorise.crystalwallet.randomdatagenerators.RandomSeedGenerator;
import cy.agorise.crystalwallet.randomdatagenerators.RandomTransactionsGenerator;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel; import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel;
import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel;
import cy.agorise.crystalwallet.views.TransactionListView;
public class IntroActivity extends CustomActivity { public class IntroActivity extends CustomActivity {
@BindView(R.id.ivAnimation) @BindView(R.id.surface_view)
ImageView ivAnimation; public SurfaceView mSurfaceView;
@BindView(R.id.btnCreateAccount) @BindView(R.id.btnCreateAccount)
Button btnCreateAccount; public Button btnCreateAccount;
@BindView(R.id.btnImportAccount) @BindView(R.id.btnImportAccount)
Button btnImportAccount; public Button btnImportAccount;
/*
* For the window animation
* */
// private MediaPlayer mediaPlayer;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -47,32 +59,33 @@ public class IntroActivity extends CustomActivity {
ButterKnife.bind(this); ButterKnife.bind(this);
Glide.with(this) // Appbar animation
.load(R.drawable.appbar_background) mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
.apply(new RequestOptions().centerCrop())
.into(ivAnimation);
/*
* Integration of library with button effects
* */
PushDownAnim.setPushDownAnimTo(btnCreateAccount)
.setOnClickListener( new View.OnClickListener(){
@Override @Override
public void onClick( View view ){ public void surfaceCreated(SurfaceHolder surfaceHolder) {
createAccount(); //Log.d(TAG,"surfaceCreated");
MediaPlayer mediaPlayer = MediaPlayer.create(IntroActivity.this, R.raw.appbar_background);
mediaPlayer.setDisplay(mSurfaceView.getHolder());
mediaPlayer.setLooping(true);
mediaPlayer.start();
} }
} );
PushDownAnim.setPushDownAnimTo(btnImportAccount)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
importAccount();
}
} );
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//Log.d(TAG,"surfaceChanged");
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//Log.d(TAG,"surfaceDestroyed");
}
});
this.getApplication().registerActivityLifecycleCallbacks(CrystalSecurityMonitor.getInstance(this)); this.getApplication().registerActivityLifecycleCallbacks(CrystalSecurityMonitor.getInstance(this));
//Checks if the user has any seed created //Checks if the user has any seed created
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class); AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);

View file

@ -4,11 +4,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.webkit.WebView; import android.webkit.WebView;
import android.widget.Button;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -24,17 +20,8 @@ public class LicenseActivity extends AppCompatActivity {
@BindView(R.id.wvEULA) WebView wvEULA; @BindView(R.id.wvEULA) WebView wvEULA;
@BindView(R.id.btnDisAgree)
Button btnDisAgree;
@BindView(R.id.btnAgree)
Button btnAgree;
CrystalDatabase db; CrystalDatabase db;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -42,23 +29,10 @@ public class LicenseActivity extends AppCompatActivity {
ButterKnife.bind(this); ButterKnife.bind(this);
/* // TODO check if license has been agreed
* Integration of library with button efects
* */ String html = getString(R.string.licence_html);
PushDownAnim.setPushDownAnimTo(btnDisAgree) wvEULA.loadData(html, "text/html", "UTF-8");
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
onDisagree();
}
} );
PushDownAnim.setPushDownAnimTo(btnAgree)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
onAgree();
}
} );
db = CrystalDatabase.getAppDatabase(this.getApplicationContext()); db = CrystalDatabase.getAppDatabase(this.getApplicationContext());
int licenseVersion = getResources().getInteger(R.integer.license_version); int licenseVersion = getResources().getInteger(R.integer.license_version);
@ -69,9 +43,6 @@ public class LicenseActivity extends AppCompatActivity {
startActivity(intent); startActivity(intent);
finish(); finish();
} }
else{
wvEULA.loadUrl("file:///android_asset/crystal_eula.html");
}
} }
@OnClick(R.id.btnAgree) @OnClick(R.id.btnAgree)

View file

@ -1,64 +1,31 @@
package cy.agorise.crystalwallet.activities; package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.graphics.Color;
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.text.Editable; import android.text.Editable;
import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import com.andrognito.patternlockview.PatternLockView; import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener; import com.andrognito.patternlockview.listener.PatternLockViewListener;
import java.util.List; import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnTextChanged; import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor; import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
//import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.PasswordManager; import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel; import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
public class PatternRequestActivity extends AppCompatActivity { public class PatternRequestActivity extends AppCompatActivity {
private String patternEncrypted; private String patternEncrypted;
@BindView(R.id.tvPatternText)
TextView tvPatternText;
@BindView(R.id.txtBadtry)
TextView txtBadtry;
/*
* External listener for success or fail
* */
private static OnResponse onResponse;
/*
* Contains the bad tries
* */
private int tries = 0;
/*
* Seconds counter
* */
private int seconds = 15;
@Override @Override
public void onBackPressed() { public void onBackPressed() {
//Do nothing to prevent the user to use the back button //Do nothing to prevent the user to use the back button
@ -67,15 +34,12 @@ public class PatternRequestActivity extends AppCompatActivity {
@BindView(R.id.patternLockView) @BindView(R.id.patternLockView)
PatternLockView patternLockView; PatternLockView patternLockView;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pattern_request); setContentView(R.layout.activity_pattern_request);
ButterKnife.bind(this); ButterKnife.bind(this);
//onResponse = null;
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class); GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList(); LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
@ -107,26 +71,13 @@ 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();
/*if(onResponse != null){
onResponse.onSuccess();
}*/
} else { } else {
thisActivity.finish(); thisActivity.finish();
/*if(onResponse != null){
onResponse.onSuccess();
}*/
} }
} else { } else {
incorrect(); patternLockView.clearPattern();
patternLockView.requestFocus();
/*if(onResponse != null){
onResponse.onFailed();
}*/
} }
} }
@ -144,104 +95,6 @@ public class PatternRequestActivity extends AppCompatActivity {
}); });
} }
public static void setOnResponse(OnResponse onResponse) {
PatternRequestActivity.onResponse = onResponse;
}
private void incorrect(){
/*
* One more bad try
* */
++tries;
final Activity activity = this;
/*
* User can not go more up to 5 bad tries
* */
if(tries==4) {
tries = 0;
patternLockView.setEnabled(false);
txtBadtry.setVisibility(View.VISIBLE);
txtBadtry.setText(txtBadtry.getText().toString().replace("%%",String.valueOf(seconds)));
final Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
--seconds;
if(seconds==0){
t.cancel();
seconds = 15;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
patternLockView.setEnabled(true);
txtBadtry.setVisibility(View.INVISIBLE);
patternLockView.clearPattern();
patternLockView.requestFocus();
}
});
}
else{
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtBadtry.setText(activity.getResources().getString(R.string.wrong_pin_wait).replace("%%",String.valueOf(seconds)));
}
});
}
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
return;
}
/*
* Show error
* */
tvPatternText.setText(activity.getResources().getString(R.string.Incorrect_pattern));
tvPatternText.setTextColor(Color.RED);
tvPatternText.setVisibility(View.VISIBLE);
final Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
t.cancel();
tvPatternText.setVisibility(View.INVISIBLE);
patternLockView.clearPattern();
patternLockView.requestFocus();
}
});
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
}
public String patternToString(List<PatternLockView.Dot> pattern){ public String patternToString(List<PatternLockView.Dot> pattern){
String patternString = ""; String patternString = "";
for (PatternLockView.Dot nextDot : pattern){ for (PatternLockView.Dot nextDot : pattern){

View file

@ -1,37 +1,21 @@
package cy.agorise.crystalwallet.activities; package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.graphics.Color;
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.text.Editable; import android.text.Editable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnTextChanged; import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor; import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.models.AccountSeed; import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.PasswordManager; import cy.agorise.crystalwallet.util.PasswordManager;
@ -40,29 +24,6 @@ import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
public class PinRequestActivity extends AppCompatActivity { public class PinRequestActivity extends AppCompatActivity {
private String passwordEncrypted; private String passwordEncrypted;
@BindView(R.id.btnOK)
Button btnOK;
@BindView(R.id.txtBadtry)
TextView txtBadtry;
/*
* Contains the bad tries
* */
private int tries = 0;
/*
* Seconds counter
* */
private int seconds = 15;
/*
* External listener for success or fail
* */
private static OnResponse onResponse;
@Override @Override
public void onBackPressed() { public void onBackPressed() {
//Do nothing to prevent the user to use the back button //Do nothing to prevent the user to use the back button
@ -77,13 +38,6 @@ public class PinRequestActivity extends AppCompatActivity {
setContentView(R.layout.activity_pin_request); setContentView(R.layout.activity_pin_request);
ButterKnife.bind(this); ButterKnife.bind(this);
//onResponse = null;
/*
* Initially the button is disabled till the user type a valid PIN
* */
btnOK.setEnabled(false);
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class); GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList(); LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
generalSettingsLiveData.observe(this, new Observer<List<GeneralSetting>>() { generalSettingsLiveData.observe(this, new Observer<List<GeneralSetting>>() {
@ -105,139 +59,17 @@ public class PinRequestActivity extends AppCompatActivity {
}); });
} }
@OnClick(R.id.btnOK)
void okClic(final View view) {
if (PasswordManager.checkPassword(passwordEncrypted, etPassword.getText().toString())) {
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
CrystalSecurityMonitor.getInstance(null).call2ndFactor(this);
if(onResponse != null){
onResponse.onSuccess();
}
} else {
this.finish();
if(onResponse != null){
onResponse.onFailed();
}
}
}
else{
/*
* One more bad try
* */
++tries;
final Activity activity = this;
etPassword.setTextColor(Color.RED);
/*
* User can not go more up to 5 bad tries
* */
if(tries==4){
tries = 0;
btnOK.setEnabled(false);
etPassword.setEnabled(false);
txtBadtry.setVisibility(View.VISIBLE);
txtBadtry.setText(txtBadtry.getText().toString().replace("%%",String.valueOf(seconds)));
final Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
--seconds;
if(seconds==0){
t.cancel();
seconds = 15;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
btnOK.setEnabled(true);
etPassword.setEnabled(true);
txtBadtry.setVisibility(View.INVISIBLE);
etPassword.setText("");
etPassword.setTextColor(Color.WHITE);
}
});
}
else{
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtBadtry.setText(activity.getResources().getString(R.string.wrong_pin_wait).replace("%%",String.valueOf(seconds)));
}
});
}
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
return;
}
/*
* Set in red the rext and reset the password after a period of time
* */
final Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
etPassword.setText("");
etPassword.setTextColor(Color.WHITE);
t.cancel();
}
});
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
500,
//Set the amount of time between each execution (in milliseconds)
500);
}
}
public static void setOnResponse(OnResponse onResponse) {
PinRequestActivity.onResponse = onResponse;
}
@OnTextChanged(value = R.id.etPassword, @OnTextChanged(value = R.id.etPassword,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterPasswordChanged(Editable editable) { void afterPasswordChanged(Editable editable) {
if (PasswordManager.checkPassword(passwordEncrypted, etPassword.getText().toString())) {
/* if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
* If it is valid length enable button CrystalSecurityMonitor.getInstance(null).call2ndFactor(this);
* */ } else {
if(etPassword.getText().length()>=6){ this.finish();
btnOK.setEnabled(true);
} }
else{
btnOK.setEnabled(false);
} }
} }
} }

View file

@ -1,18 +1,15 @@
package cy.agorise.crystalwallet.activities; package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import android.arch.lifecycle.LiveData; 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;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.jaredrummler.materialspinner.MaterialSpinner; import com.jaredrummler.materialspinner.MaterialSpinner;
@ -41,7 +38,7 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
SendTransactionValidator sendTransactionValidator; SendTransactionValidator sendTransactionValidator;
@BindView(R.id.spFrom) @BindView(R.id.spFrom)
Spinner spFrom; MaterialSpinner spFrom;
@BindView(R.id.tvFromError) @BindView(R.id.tvFromError)
TextView tvFromError; TextView tvFromError;
@BindView(R.id.etTo) @BindView(R.id.etTo)
@ -65,9 +62,6 @@ 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;
@ -152,15 +146,6 @@ 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()) {

View file

@ -1,19 +1,20 @@
package cy.agorise.crystalwallet.activities; package cy.agorise.crystalwallet.activities;
import android.content.Intent; import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.bumptech.glide.Glide; import com.sjaramillo10.animatedtablayout.AnimatedTabLayout;
import com.bumptech.glide.request.RequestOptions;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -34,22 +35,21 @@ public class SettingsActivity extends AppCompatActivity{
public ImageView ivGoBack; public ImageView ivGoBack;
@BindView(R.id.tabLayout) @BindView(R.id.tabLayout)
public TabLayout tabLayout; public AnimatedTabLayout tabLayout;
@BindView(R.id.pager) @BindView(R.id.pager)
public ViewPager mPager; public ViewPager mPager;
public SettingsPagerAdapter settingsPagerAdapter; public SettingsPagerAdapter settingsPagerAdapter;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.tvBuildVersion) @BindView(R.id.tvBuildVersion)
public TextView tvBuildVersion; public TextView tvBuildVersion;
private SecuritySettingsFragment securitySettingsFragment; private SecuritySettingsFragment securitySettingsFragment;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -59,11 +59,27 @@ public class SettingsActivity extends AppCompatActivity{
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
// Sets AppBar animation // Appbar animation
Glide.with(this) mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
.load(R.drawable.appbar_background) @Override
.apply(new RequestOptions().centerCrop()) public void surfaceCreated(SurfaceHolder surfaceHolder) {
.into(ivAppBarAnimation); //Log.d(TAG,"surfaceCreated");
MediaPlayer mediaPlayer = MediaPlayer.create(SettingsActivity.this, R.raw.appbar_background);
mediaPlayer.setDisplay(mSurfaceView.getHolder());
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//Log.d(TAG,"surfaceChanged");
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//Log.d(TAG,"surfaceDestroyed");
}
});
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager()); settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(settingsPagerAdapter); mPager.setAdapter(settingsPagerAdapter);

View file

@ -1,6 +1,7 @@
package cy.agorise.crystalwallet.apigenerator; package cy.agorise.crystalwallet.apigenerator;
import android.content.Context; import android.content.Context;
import android.util.Log;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -8,6 +9,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
import cy.agorise.crystalwallet.dao.BitsharesAssetDao; import cy.agorise.crystalwallet.dao.BitsharesAssetDao;
import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao; import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao;
import cy.agorise.crystalwallet.dao.CryptoCurrencyDao; import cy.agorise.crystalwallet.dao.CryptoCurrencyDao;
@ -80,32 +82,13 @@ public abstract class GrapheneApiGenerator {
*/ */
private static HashMap<Long,SubscriptionListener> currentBitsharesListener = new HashMap<>(); private static HashMap<Long,SubscriptionListener> currentBitsharesListener = new HashMap<>();
// The message broker for Steem
private static SubscriptionMessagesHub steemSubscriptionHub = new SubscriptionMessagesHub("", "", true, new NodeErrorListener() {
@Override
public void onError(BaseResponse.Error error) {
//TODO subcription hub error
System.out.println("GrapheneAPI error");
}
});
/**
* The Steem subscription thread for the real time updates
*/
private static WebSocketThread steemSubscriptionThread = new WebSocketThread(steemSubscriptionHub, CryptoNetManager.getURL(CryptoNet.STEEM));
/**
* This is used for manager each Steem listener in the subscription thread
*/
private static HashMap<Long,SubscriptionListener> currentSteemListener = new HashMap<>();
/** /**
* Retrieves the data of an account searching by it's id * Retrieves the data of an account searching by it's id
* *
* @param accountId The accountId to retrieve * @param accountId The accountId to retrieve
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountById(String accountId, CryptoNet cryptoNet, final ApiRequest request){ public static void getAccountById(String accountId, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetAccounts(accountId, WebSocketThread thread = new WebSocketThread(new GetAccounts(accountId,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
@ -126,7 +109,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -136,37 +119,25 @@ public abstract class GrapheneApiGenerator {
* @param address The address to retrieve * @param address The address to retrieve
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountByOwnerOrActiveAddress(Address address, CryptoNet cryptoNet, final ApiRequest request){ public static void getAccountByOwnerOrActiveAddress(Address address, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetKeyReferences(address, true, WebSocketThread thread = new WebSocketThread(new GetKeyReferences(address, true,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
try {
final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result; final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result;
if (resp.size() > 0) { if(resp.size() > 0){
List<UserAccount> accounts = resp.get(0); List<UserAccount> accounts = resp.get(0);
if (accounts.size() > 0) { if(accounts.size() > 0){
for (UserAccount account : accounts) { for(UserAccount account : accounts) {
request.getListener().success(account, request.getId()); request.getListener().success(account,request.getId());}}}
break;
}
}else{
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
} else {
request.getListener().fail(request.getId());
}
}catch(Exception e){
e.printStackTrace();
request.getListener().fail(request.getId());
}
}
@Override @Override
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -181,7 +152,7 @@ public abstract class GrapheneApiGenerator {
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountTransaction(String accountGrapheneId, int start, int stop, public static void getAccountTransaction(String accountGrapheneId, int start, int stop,
int limit, CryptoNet cryptoNet, final ApiRequest request){ int limit, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetRelativeAccountHistory(new UserAccount(accountGrapheneId), WebSocketThread thread = new WebSocketThread(new GetRelativeAccountHistory(new UserAccount(accountGrapheneId),
start, limit, stop, new WitnessResponseListener() { start, limit, stop, new WitnessResponseListener() {
@Override @Override
@ -193,7 +164,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -203,7 +174,7 @@ public abstract class GrapheneApiGenerator {
* @param accountName The account Name to find * @param accountName The account Name to find
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountByName(String accountName, CryptoNet cryptoNet,final ApiRequest request){ public static void getAccountByName(String accountName, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName, WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
@ -220,7 +191,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -230,7 +201,7 @@ public abstract class GrapheneApiGenerator {
* @param accountName The account Name to find * @param accountName The account Name to find
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountIdByName(String accountName, CryptoNet cryptoNet, final ApiRequest request){ public static void getAccountIdByName(String accountName, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName, WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
@ -247,7 +218,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -281,7 +252,7 @@ public abstract class GrapheneApiGenerator {
* @param assetNames The list of the names of the assets to be retrieve * @param assetNames The list of the names of the assets to be retrieve
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void getAssetByName(ArrayList<String> assetNames, CryptoNet cryptoNet,final ApiRequest request){ public static void getAssetByName(ArrayList<String> assetNames, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assetNames,true, WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assetNames,true,
new WitnessResponseListener() { new WitnessResponseListener() {
@ -316,7 +287,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -325,7 +296,7 @@ public abstract class GrapheneApiGenerator {
* @param assetIds The list of the ids to retrieve * @param assetIds The list of the ids to retrieve
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void getAssetById(ArrayList<String> assetIds, CryptoNet cryptoNet, final ApiRequest request){ public static void getAssetById(ArrayList<String> assetIds, final ApiRequest request){
ArrayList<Asset> assets = new ArrayList<>(); ArrayList<Asset> assets = new ArrayList<>();
for(String assetId : assetIds){ for(String assetId : assetIds){
Asset asset = new Asset(assetId); Asset asset = new Asset(assetId);
@ -364,7 +335,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -398,7 +369,7 @@ public abstract class GrapheneApiGenerator {
if(operation instanceof TransferOperation){ if(operation instanceof TransferOperation){
final TransferOperation tOperation = (TransferOperation) operation; final TransferOperation tOperation = (TransferOperation) operation;
if(tOperation.getFrom().getObjectId().equals(accountBitsharesId) || tOperation.getTo().getObjectId().equals(accountBitsharesId)){ if(tOperation.getFrom().getObjectId().equals(accountBitsharesId) || tOperation.getTo().getObjectId().equals(accountBitsharesId)){
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesId,CryptoNet.BITSHARES,context); GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesId,context);
final CryptoCoinTransaction transaction = new CryptoCoinTransaction(); final CryptoCoinTransaction transaction = new CryptoCoinTransaction();
transaction.setAccountId(accountId); transaction.setAccountId(accountId);
transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue()); transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue());
@ -436,7 +407,7 @@ public abstract class GrapheneApiGenerator {
}); });
ArrayList<String> assets = new ArrayList<>(); ArrayList<String> assets = new ArrayList<>();
assets.add(tOperation.getAssetAmount().getAsset().getObjectId()); assets.add(tOperation.getAssetAmount().getAsset().getObjectId());
GrapheneApiGenerator.getAssetById(assets,CryptoNet.BITSHARES,assetRequest); GrapheneApiGenerator.getAssetById(assets,assetRequest);
}else{ }else{
saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountBitsharesId,tOperation,context); saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountBitsharesId,tOperation,context);
} }
@ -461,99 +432,6 @@ public abstract class GrapheneApiGenerator {
} }
} }
/**
* Subscribe a steem account to receive real time updates
*
* @param accountId The id opf the database of the account
* @param accountSteemId The steem id of the account
* @param context The android context of this application
*/
public static void subscribeSteemAccount(final long accountId, final String accountSteemId,
final Context context){
if(!currentSteemListener.containsKey(accountId)){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
SubscriptionListener balanceListener = new SubscriptionListener() {
@Override
public ObjectType getInterestObjectType() {
return ObjectType.TRANSACTION_OBJECT;
}
@Override
public void onSubscriptionUpdate(SubscriptionResponse response) {
List<Serializable> updatedObjects = (List<Serializable>) response.params.get(1);
if(updatedObjects.size() > 0){
for(Serializable update : updatedObjects){
if(update instanceof BroadcastedTransaction){
BroadcastedTransaction transactionUpdate = (BroadcastedTransaction) update;
for(BaseOperation operation : transactionUpdate.getTransaction().getOperations()){
if(operation instanceof TransferOperation){
final TransferOperation tOperation = (TransferOperation) operation;
if(tOperation.getFrom().getObjectId().equals(accountSteemId) || tOperation.getTo().getObjectId().equals(accountSteemId)){
GrapheneApiGenerator.getAccountBalance(accountId,accountSteemId,CryptoNet.STEEM,context);
final CryptoCoinTransaction transaction = new CryptoCoinTransaction();
transaction.setAccountId(accountId);
transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue());
BitsharesAssetInfo info = bitsharesAssetDao.getBitsharesAssetInfoById(tOperation.getAssetAmount().getAsset().getObjectId());
if (info == null) {
//The cryptoCurrency is not in the database, queringfor its data
ApiRequest assetRequest = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
ArrayList<BitsharesAsset> assets = (ArrayList<BitsharesAsset>) answer;
for(BitsharesAsset asset : assets){
long currencyId = -1;
CryptoCurrency cryptoCurrencyDb = cryptoCurrencyDao.getByNameAndCryptoNet(((BitsharesAsset) answer).getName(),((BitsharesAsset) answer).getCryptoNet().name());
if (cryptoCurrencyDb != null){
currencyId = cryptoCurrencyDb.getId();
} else {
long idCryptoCurrency = cryptoCurrencyDao.insertCryptoCurrency(asset)[0];
currencyId = idCryptoCurrency;
}
BitsharesAssetInfo info = new BitsharesAssetInfo(asset);
info.setCryptoCurrencyId(currencyId);
asset.setId((int)currencyId);
bitsharesAssetDao.insertBitsharesAssetInfo(info);
saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountSteemId,tOperation,context);
}
}
@Override
public void fail(int idPetition) {
//TODO error retrieving asset
}
});
ArrayList<String> assets = new ArrayList<>();
assets.add(tOperation.getAssetAmount().getAsset().getObjectId());
GrapheneApiGenerator.getAssetById(assets,CryptoNet.STEEM,assetRequest);
}else{
saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountSteemId,tOperation,context);
}
}
}
}
}
}
}
}
};
currentSteemListener.put(accountId,balanceListener);
steemSubscriptionHub.addSubscriptionListener(balanceListener);
if(!steemSubscriptionThread.isConnected()){
steemSubscriptionThread.start();
}else if(!steemSubscriptionHub.isSubscribed()){
steemSubscriptionHub.resubscribe();
}
}
}
/** /**
* Function to save a transaction retrieved from the update * Function to save a transaction retrieved from the update
* @param transaction The transaction db object * @param transaction The transaction db object
@ -592,7 +470,7 @@ public abstract class GrapheneApiGenerator {
* @param context The android context of this application * @param context The android context of this application
*/ */
public static void getAccountBalance(final long accountId, final String accountGrapheneId, public static void getAccountBalance(final long accountId, final String accountGrapheneId,
final CryptoNet cryptoNet, final Context context){ final Context context){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final CryptoCoinBalanceDao balanceDao = db.cryptoCoinBalanceDao(); final CryptoCoinBalanceDao balanceDao = db.cryptoCoinBalanceDao();
@ -638,7 +516,7 @@ public abstract class GrapheneApiGenerator {
public void fail(int idPetition) { public void fail(int idPetition) {
} }
}); });
getAssetById(idAssets,cryptoNet,getAssetRequest); getAssetById(idAssets,getAssetRequest);
}else { }else {
@ -652,7 +530,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
@ -664,7 +542,7 @@ public abstract class GrapheneApiGenerator {
* @param blockHeader The block header to retrieve the date time * @param blockHeader The block header to retrieve the date time
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void getBlockHeaderTime(long blockHeader, CryptoNet cryptoNet,final ApiRequest request){ public static void getBlockHeaderTime(long blockHeader, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetBlockHeader(blockHeader, new WitnessResponseListener() { WebSocketThread thread = new WebSocketThread(new GetBlockHeader(blockHeader, new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
@ -679,7 +557,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}),CryptoNetManager.getURL(cryptoNet)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -747,7 +625,7 @@ public abstract class GrapheneApiGenerator {
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao(); final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao(); final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName,CryptoNet.BITSHARES.name()); CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName);
BitsharesAssetInfo info = null; BitsharesAssetInfo info = null;
if(baseCurrency != null){ if(baseCurrency != null){
info = db.bitsharesAssetDao().getBitsharesAssetInfo(baseCurrency.getId()); info = db.bitsharesAssetDao().getBitsharesAssetInfo(baseCurrency.getId());
@ -782,7 +660,7 @@ public abstract class GrapheneApiGenerator {
}); });
ArrayList<String> names = new ArrayList<>(); ArrayList<String> names = new ArrayList<>();
names.add(baseAssetName); names.add(baseAssetName);
GrapheneApiGenerator.getAssetByName(names,CryptoNet.BITSHARES,getAssetRequest); GrapheneApiGenerator.getAssetByName(names,getAssetRequest);
}else { }else {
BitsharesAsset baseAsset = new BitsharesAsset(baseCurrency); BitsharesAsset baseAsset = new BitsharesAsset(baseCurrency);

View file

@ -1,81 +1,49 @@
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.enums.CryptoCoin; import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionData;
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<CryptoCoin,GetTransactionByAddress> transactionGetters = new HashMap(); private static HashMap<CryptoNet,BroadcastTransaction> broadcaster = new HashMap();
private static HashMap<CryptoCoin,AddressesActivityWatcher> transactionFollowers = new HashMap(); private static HashMap<CryptoNet,GetTransactionByAddress> transactionGetters = new HashMap();
private static HashMap<CryptoNet,GetTransactionData> transacitonFollowers = new HashMap();
private static final String PATH = "api"; public static void getTransactionFromAddress(CryptoNet cryptoNet, String address,
ApiRequest request, Context context,
/** boolean subscribe){
* Fecth all the transaciton for a giving address if(!transactionGetters.containsKey(cryptoNet)){
* @param cryptoCoin the crypto net of the address //TODO change this line
* @param address The address String 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, boolean subscribe, HasTransactionListener listener){
/*if(!transactionGetters.containsKey(cryptoCoin)){
transactionGetters.put(cryptoCoin,new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH));
} }
transactionGetters.get(cryptoCoin).addAddress(address);
transactionGetters.get(cryptoCoin).start();*/
GetTransactionByAddress transByAddr = new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH,listener);
transByAddr.addAddress(address);
transByAddr.start();
if(subscribe){
if(!transactionFollowers.containsKey(cryptoCoin)){
transactionFollowers.put(cryptoCoin,new AddressesActivityWatcher(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH,cryptoCoin));
} }
transactionFollowers.get(cryptoCoin).addAddress(address);
transactionFollowers.get(cryptoCoin).connect(); public static void followTransaction(CryptoNet cryptoNet, String txid, Context context){
}
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){
* Broadcast an insight api transaction GetEstimateFee.getEstimateFee(CryptoNetManager.getURL(cryptoNet), new GetEstimateFee.estimateFeeListener() {
* @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()), PATH, new BroadcastTransaction.BroadCastTransactionListener() {
@Override @Override
public void onSuccess() { public void estimateFee(long value) {
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
public void estimateFee(double value) {
request.listener.success(value,request.getId()); request.listener.success(value,request.getId());
} }
@ -85,8 +53,4 @@ public class InsightApiGenerator {
} }
}); });
} }
public interface HasTransactionListener{
public void hasTransaction(boolean value);
}
} }

View file

@ -12,7 +12,6 @@ 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;
@ -25,9 +24,12 @@ import io.socket.emitter.Emitter;
* *
*/ */
public class AddressesActivityWatcher { public class AccountActivityWatcher {
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
*/ */
@ -36,9 +38,12 @@ public class AddressesActivityWatcher {
* 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;
private final String mPath;
/** /**
* Handles the address/transaction notification. * Handles the address/transaction notification.
@ -50,9 +55,9 @@ public class AddressesActivityWatcher {
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, mServerUrl, mPath, cryptoCoin).start(); new GetTransactionData(txid, mAccount, mServerUrl, mContext).start();
} catch (JSONException ex) { } catch (JSONException ex) {
Logger.getLogger(AddressesActivityWatcher.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(AccountActivityWatcher.class.getName()).log(Level.SEVERE, null, ex);
} }
} }
}; };
@ -79,9 +84,7 @@ public class AddressesActivityWatcher {
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) {
try { System.out.println("Disconnected to accountActivityWatcher");
Thread.sleep(60000);
} catch (InterruptedException ignore) {}
mSocket.connect(); mSocket.connect();
} }
}; };
@ -96,21 +99,19 @@ public class AddressesActivityWatcher {
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 AddressesActivityWatcher(String serverUrl, String path, CryptoCoin cryptoCoin) { public AccountActivityWatcher(String serverUrl, GeneralCoinAccount mAccount, Context mContext) {
this.mPath = path;
this.mServerUrl = serverUrl; this.mServerUrl = serverUrl;
this.cryptoCoin = cryptoCoin; this.mAccount = mAccount;
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);
@ -140,11 +141,13 @@ public class AddressesActivityWatcher {
* 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){
}catch(Exception ignore){ //TODO change exception handler
System.out.println("accountActivityWatcher exception " + e.getMessage());
} }
} }

View file

@ -22,21 +22,29 @@ 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 mPath; private String serverUrl;
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, String serverUrl, String path, BroadCastTransactionListener listener){ public BroadcastTransaction(String RawTx, GeneralCoinAccount account, String serverUrl, Context context){
this.serverUrl = serverUrl;
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl); this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
this.mContext = context;
this.mRawTx = RawTx; this.mRawTx = RawTx;
this.listener = listener; this.mAccount = account;
this.mPath = path;
} }
/** /**
@ -46,9 +54,13 @@ 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()) {
listener.onSuccess(); //TODO invalidated send
//TODO call getTransactionData
GetTransactionData trData = new GetTransactionData(response.body().txid,this.mAccount, this.serverUrl, this.mContext);
trData.start();
} else { } else {
listener.onFailure(response.message()); System.out.println("SENDTEST: not succesful " + response.message());
//TODO change how to handle invalid transaction
} }
} }
@ -57,7 +69,8 @@ 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) {
listener.onConnecitonFailure(); //TODO change how to handle invalid transaction
System.out.println("SENDTEST: sendError " + t.getMessage() );
} }
/** /**
@ -65,19 +78,8 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
*/ */
@Override @Override
public void run() { public void run() {
try {
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class); InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
Call<Txi> broadcastTransaction = service.broadcastTransaction(this.mPath, this.mRawTx); Call<Txi> broadcastTransaction = service.broadcastTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),this.mRawTx);
broadcastTransaction.enqueue(this); broadcastTransaction.enqueue(this);
}catch(Exception e){
e.printStackTrace();
}
}
public interface BroadCastTransactionListener{
void onSuccess();
void onFailure(String msg);
void onConnecitonFailure();
} }
} }

View file

@ -20,8 +20,6 @@ import retrofit2.Response;
public abstract class GetEstimateFee { public abstract class GetEstimateFee {
private static String PATH = "api";
/** /**
* The funciton to get the rate for the transaction be included in the next 2 blocks * The funciton to get the rate for the transaction be included in the next 2 blocks
* @param serverUrl The url of the insight server * @param serverUrl The url of the insight server
@ -31,32 +29,28 @@ public abstract class GetEstimateFee {
try { try {
InsightApiServiceGenerator serviceGenerator = new InsightApiServiceGenerator(serverUrl); InsightApiServiceGenerator serviceGenerator = new InsightApiServiceGenerator(serverUrl);
InsightApiService service = serviceGenerator.getService(InsightApiService.class); InsightApiService service = serviceGenerator.getService(InsightApiService.class);
Call<JsonObject> call = service.estimateFee(PATH); Call<JsonObject> call = service.estimateFee(serverUrl);
final JsonObject answer = new JsonObject();
call.enqueue(new Callback<JsonObject>() { call.enqueue(new Callback<JsonObject>() {
@Override @Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
try { listener.estimateFee((long) (answer.get("answer").getAsDouble()));
listener.estimateFee((double) (response.body().get("2").getAsDouble()));
}catch (Exception e){
e.printStackTrace();
listener.fail();
}
} }
@Override @Override
public void onFailure(Call<JsonObject> call, Throwable t) { public void onFailure(Call<JsonObject> call, Throwable t) {
listener.fail(); listener.fail();
listener.estimateFee(-1);
} }
}); });
}catch(Exception e){ }catch(Exception e){
e.printStackTrace();
listener.fail(); listener.fail();
} }
} }
public static interface estimateFeeListener{ public static interface estimateFeeListener{
public void estimateFee(double value); public void estimateFee(long value);
public void fail(); public void fail();
} }

View file

@ -1,43 +0,0 @@
package cy.agorise.crystalwallet.apigenerator.insightapi;
import com.google.gson.JsonObject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class GetGenesisBlock {
private static String PATH = "api";
public GetGenesisBlock(String serverUrl, final genesisBlockListener listener) {
try {
InsightApiServiceGenerator serviceGenerator = new InsightApiServiceGenerator(serverUrl);
InsightApiService service = serviceGenerator.getService(InsightApiService.class);
Call<JsonObject> call = service.genesisBlock(PATH);
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
try {
listener.genesisBlock(response.body().get("blockHash").getAsString());
}catch(Exception e){
e.printStackTrace();
listener.fail();
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
listener.fail();
}
});
}catch(Exception e){
listener.fail();
}
}
public interface genesisBlockListener{
void genesisBlock(String value);
void fail();
}
}

View file

@ -1,15 +1,20 @@
package cy.agorise.crystalwallet.apigenerator.insightapi; package cy.agorise.crystalwallet.apigenerator.insightapi;
import android.content.Context;
import android.util.Log; import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
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.enums.CryptoCoin; import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
import cy.agorise.crystalwallet.manager.GeneralAccountManager; import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
import cy.agorise.crystalwallet.models.GTxIO;
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
import cy.agorise.crystalwallet.models.GeneralTransaction;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
@ -20,40 +25,43 @@ 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<String> mAddresses = new ArrayList<>(); private List<GeneralCoinAddress> 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 mServerUrl; private String serverUrl;
private String mPath;
private CryptoCoin cryptoNet;
private boolean inProcess = false;
private InsightApiGenerator.HasTransactionListener listener;
/** /**
* Basic consturcotr * Basic consturcotr
* @param account The account to be query
* @param context This app context
*/ */
public GetTransactionByAddress(CryptoCoin cryptoNet, String serverUrl, String path, InsightApiGenerator.HasTransactionListener listener) { public GetTransactionByAddress(GeneralCoinAccount account, String serverUrl, Context context) {
this.mPath = path; this.serverUrl = serverUrl;
this.cryptoNet = cryptoNet; this.mAccount = account;
this.mServerUrl = serverUrl;
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl); this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
this.listener = listener; 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(String address) { public void addAddress(GeneralCoinAddress address) {
this.mAddresses.add(address); this.mAddresses.add(address);
} }
@ -65,23 +73,110 @@ 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;
AddressTxi addressTxi = response.body(); AddressTxi addressTxi = response.body();
if(listener != null) {
if (addressTxi.items.length > 0 ) {
listener.hasTransaction(true);
}else{
listener.hasTransaction(false);
}
}
for (Txi txi : addressTxi.items) { for (Txi txi : addressTxi.items) {
GeneralAccountManager.getAccountManager(this.cryptoNet).processTxi(txi); GeneralCoinAccount tempAccount = null;
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);
} }
}else{ for (Vout vout : txi.vout) {
listener.hasTransaction(false); 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();
}
} }
} }
@ -92,7 +187,6 @@ 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");
} }
@ -101,15 +195,14 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
*/ */
@Override @Override
public void run() { public void run() {
if (this.mAddresses.size() > 0 && !inProcess) { if (this.mAddresses.size() > 0) {
inProcess = true;
StringBuilder addressToQuery = new StringBuilder(); StringBuilder addressToQuery = new StringBuilder();
for (String address : this.mAddresses) { for (GeneralCoinAddress address : this.mAddresses) {
addressToQuery.append(address).append(","); addressToQuery.append(address.getAddressString(this.mAccount.getNetworkParam())).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(this.mPath,addressToQuery.toString()); Call<AddressTxi> addressTxiCall = service.getTransactionByAddress(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),addressToQuery.toString());
addressTxiCall.enqueue(this); addressTxiCall.enqueue(this);
} }
} }

View file

@ -7,8 +7,6 @@ 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;
@ -22,6 +20,10 @@ 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
*/ */
@ -30,38 +32,41 @@ 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;
private String mPath;
/** /**
* If has to wait for another confirmation * If has to wait for another confirmation
*/ */
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, String serverUrl, String path, CryptoCoin cryptoCoin) { public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context) {
this(txid, serverUrl, path, cryptoCoin, false); this(txid, account, serverUrl, context, 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, String serverUrl, String path, CryptoCoin cryptoCoin, boolean mustWait) { public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context, boolean mustWait) {
this.mPath = path;
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;
} }
/** /**
@ -79,19 +84,104 @@ 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(this.mPath,this.mTxId); Call<Txi> txiCall = service.getTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),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);
if (txi.confirmations < this.cryptoCoin.getCryptoNet().getConfirmationsNeeded()) { 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.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.mServerUrl, this.mPath, this.cryptoCoin, true).start(); new GetTransactionData(this.mTxId, this.mAccount, this.mServerUrl, this.mContext, true).start();
} }
} }
} }

View file

@ -49,7 +49,4 @@ interface InsightApiService {
@GET("{path}/utils/estimatefee?nbBlocks=2") @GET("{path}/utils/estimatefee?nbBlocks=2")
Call<JsonObject> estimateFee(@Path(value = "path", encoded = true) String path); Call<JsonObject> estimateFee(@Path(value = "path", encoded = true) String path);
@GET("{path}/block-index/0")
Call<JsonObject> genesisBlock(@Path(value = "path", encoded = true) String path);
} }

View file

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

View file

@ -17,7 +17,6 @@ import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoNet; import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.BitsharesAsset; import cy.agorise.crystalwallet.models.BitsharesAsset;
import cy.agorise.crystalwallet.models.BitsharesAssetInfo; import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence; import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.network.CryptoNetManager; import cy.agorise.crystalwallet.network.CryptoNetManager;
@ -50,27 +49,6 @@ public class CrystalApplication extends Application {
//This is for testing the equivalent values on the testnet TODO remove //This is for testing the equivalent values on the testnet TODO remove
public static BitsharesAsset bitEURAsset = new BitsharesAsset("EUR",4,"1.3.120",BitsharesAsset.Type.SMART_COIN); public static BitsharesAsset bitEURAsset = new BitsharesAsset("EUR",4,"1.3.120",BitsharesAsset.Type.SMART_COIN);
public static final String BITCOIN_SERVER_URLS[] ={
"https://testnet.blockexplorer.com/",
"https://test-insight.bitpay.com",
//"https://insight.bitpay.com/"
};
public static final CryptoCurrency BITCOIN_CURRENCY = new CryptoCurrency("BTC",CryptoNet.BITCOIN,8);
public static String STEEM_URL[] =
{
"https://api.steemit.com",
"https://api.steemitdev.com",
"https://api.steemitstage.com",
"https://api.steem.house",
"https://appbasetest.timcliff.com",
};
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -84,10 +62,10 @@ public class CrystalApplication extends Application {
//This is for testing the equivalent values on the testnet TODO remove //This is for testing the equivalent values on the testnet TODO remove
if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitEURAsset.getBitsharesId())== null){ if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitEURAsset.getBitsharesId())== null){
if(db.cryptoCurrencyDao().getByName(bitEURAsset.getName(),bitEURAsset.getCryptoNet().name())== null){ if(db.cryptoCurrencyDao().getByName(bitEURAsset.getName())== null){
db.cryptoCurrencyDao().insertCryptoCurrency(bitEURAsset); db.cryptoCurrencyDao().insertCryptoCurrency(bitEURAsset);
} }
long idCurrency = db.cryptoCurrencyDao().getByName(bitEURAsset.getName(),bitEURAsset.getCryptoNet().name()).getId(); long idCurrency = db.cryptoCurrencyDao().getByName(bitEURAsset.getName()).getId();
BitsharesAssetInfo info = new BitsharesAssetInfo(bitEURAsset); BitsharesAssetInfo info = new BitsharesAssetInfo(bitEURAsset);
info.setCryptoCurrencyId(idCurrency); info.setCryptoCurrencyId(idCurrency);
db.bitsharesAssetDao().insertBitsharesAssetInfo(info); db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
@ -96,10 +74,10 @@ public class CrystalApplication extends Application {
//This is for testing the equivalent values on the testnet TODO remove //This is for testing the equivalent values on the testnet TODO remove
if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitUSDAsset.getBitsharesId())== null){ if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitUSDAsset.getBitsharesId())== null){
if(db.cryptoCurrencyDao().getByName(bitUSDAsset.getName(),bitUSDAsset.getCryptoNet().name())== null){ if(db.cryptoCurrencyDao().getByName(bitUSDAsset.getName())== null){
db.cryptoCurrencyDao().insertCryptoCurrency(bitUSDAsset); db.cryptoCurrencyDao().insertCryptoCurrency(bitUSDAsset);
} }
long idCurrency = db.cryptoCurrencyDao().getByName(bitUSDAsset.getName(),bitUSDAsset.getCryptoNet().name()).getId(); long idCurrency = db.cryptoCurrencyDao().getByName(bitUSDAsset.getName()).getId();
BitsharesAssetInfo info = new BitsharesAssetInfo(bitUSDAsset); BitsharesAssetInfo info = new BitsharesAssetInfo(bitUSDAsset);
info.setCryptoCurrencyId(idCurrency); info.setCryptoCurrencyId(idCurrency);
db.bitsharesAssetDao().insertBitsharesAssetInfo(info); db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
@ -115,16 +93,6 @@ public class CrystalApplication extends Application {
// TODO and hoop over the urls if no connection can be established // TODO and hoop over the urls if no connection can be established
CryptoNetManager.addCryptoNetURL(CryptoNet.BITSHARES,BITSHARES_URL); CryptoNetManager.addCryptoNetURL(CryptoNet.BITSHARES,BITSHARES_URL);
//Adding Bitcoin info
CryptoNetManager.addCryptoNetURL(CryptoNet.BITCOIN,BITCOIN_SERVER_URLS);
if(db.cryptoCurrencyDao().getByName(BITCOIN_CURRENCY.getName(),BITCOIN_CURRENCY.getCryptoNet().name())== null){
db.cryptoCurrencyDao().insertCryptoCurrency(BITCOIN_CURRENCY);
}
CryptoNetManager.addCryptoNetURL(CryptoNet.STEEM,STEEM_URL);
GeneralSetting generalSettingPreferredLanguage = db.generalSettingDao().getSettingByName(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE); GeneralSetting generalSettingPreferredLanguage = db.generalSettingDao().getSettingByName(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE);
if (generalSettingPreferredLanguage != null) { if (generalSettingPreferredLanguage != null) {
@ -137,11 +105,6 @@ public class CrystalApplication extends Application {
resources.updateConfiguration(configuration, dm); resources.updateConfiguration(configuration, dm);
} }
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class); Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class);
startService(intent); startService(intent);
} }

View file

@ -16,8 +16,6 @@ import java.util.List;
import cy.agorise.crystalwallet.activities.PatternRequestActivity; import cy.agorise.crystalwallet.activities.PatternRequestActivity;
import cy.agorise.crystalwallet.activities.PinRequestActivity; import cy.agorise.crystalwallet.activities.PinRequestActivity;
import cy.agorise.crystalwallet.activities.PocketRequestActivity; import cy.agorise.crystalwallet.activities.PocketRequestActivity;
import cy.agorise.crystalwallet.fragments.PatternSecurityFragment;
import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.notifiers.CrystalWalletNotifier; import cy.agorise.crystalwallet.notifiers.CrystalWalletNotifier;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel; import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
@ -131,7 +129,7 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
public void onActivityStarted(Activity activity) { public void onActivityStarted(Activity activity) {
if (numStarted == 0) { if (numStarted == 0) {
if (!actualSecurity().equals("")){ if (!actualSecurity().equals("")){
callPasswordRequest(activity,null); callPasswordRequest(activity);
} }
} }
numStarted++; numStarted++;
@ -142,41 +140,18 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
numStarted--; numStarted--;
if (numStarted == 0) { if (numStarted == 0) {
if (!actualSecurity().equals("")){ if (!actualSecurity().equals("")){
callPasswordRequest(activity,null); callPasswordRequest(activity);
} }
} }
} }
public void callPasswordRequest(Activity activity, final OnResponse onResponsePattern){ public void callPasswordRequest(Activity activity){
if ((!activity.getIntent().hasExtra("ACTIVITY_TYPE")) || (!activity.getIntent().getStringExtra("ACTIVITY_TYPE").equals("PASSWORD_REQUEST"))) { if ((!activity.getIntent().hasExtra("ACTIVITY_TYPE")) || (!activity.getIntent().getStringExtra("ACTIVITY_TYPE").equals("PASSWORD_REQUEST"))) {
Intent intent = null; Intent intent = null;
if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) { if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) {
intent = new Intent(activity, PinRequestActivity.class); intent = new Intent(activity, PinRequestActivity.class);
PinRequestActivity.setOnResponse(null);
/*
* Connect error and success listeners
* */
if(onResponsePattern != null){
PinRequestActivity.setOnResponse(onResponsePattern);
}
} else if ((this.patternEncrypted != null) && (!this.patternEncrypted.equals(""))) { } else if ((this.patternEncrypted != null) && (!this.patternEncrypted.equals(""))) {
intent = new Intent(activity, PatternRequestActivity.class); intent = new Intent(activity, PatternRequestActivity.class);
PatternRequestActivity.setOnResponse(null);
/*
* Connect error and success listeners
* */
if(onResponsePattern != null){
PatternRequestActivity.setOnResponse(onResponsePattern);
}
} else {
onResponsePattern.onSuccess();
} }
if (intent != null) { if (intent != null) {
intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST"); intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST");
@ -222,4 +197,7 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
public void onActivityDestroyed(Activity activity) { public void onActivityDestroyed(Activity activity) {
// //
} }
} }

View file

@ -32,7 +32,7 @@ public abstract class BitsharesConstant {
//testnet faucet //testnet faucet
//public final static String FAUCET_URL = "http://185.208.208.147:5010"; //public final static String FAUCET_URL = "http://185.208.208.147:5010";
public final static String FAUCET_URL = "https://faucet.palmpay.io"; public final static String FAUCET_URL = "https://de.palmpay.io";
public final static String EQUIVALENT_URL = "wss://bitshares.openledger.info/ws"; public final static String EQUIVALENT_URL = "wss://bitshares.openledger.info/ws";
public final static BitsharesAsset[] SMARTCOINS = new BitsharesAsset[]{ public final static BitsharesAsset[] SMARTCOINS = new BitsharesAsset[]{
@ -74,10 +74,10 @@ public abstract class BitsharesConstant {
public static void addSmartCoins(Context context){ public static void addSmartCoins(Context context){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
for(BitsharesAsset smartcoin : SMARTCOINS){ for(BitsharesAsset smartcoin : SMARTCOINS){
if(db.cryptoCurrencyDao().getByName(smartcoin.getName(),CryptoNet.BITSHARES.name())== null){ if(db.cryptoCurrencyDao().getByName(smartcoin.getName())== null){
db.cryptoCurrencyDao().insertCryptoCurrency(smartcoin); db.cryptoCurrencyDao().insertCryptoCurrency(smartcoin);
} }
long idCurrency = db.cryptoCurrencyDao().getByName(smartcoin.getName(),CryptoNet.BITSHARES.name()).getId(); long idCurrency = db.cryptoCurrencyDao().getByName(smartcoin.getName()).getId();
BitsharesAssetInfo info = new BitsharesAssetInfo(smartcoin); BitsharesAssetInfo info = new BitsharesAssetInfo(smartcoin);
info.setCryptoCurrencyId(idCurrency); info.setCryptoCurrencyId(idCurrency);
db.bitsharesAssetDao().insertBitsharesAssetInfo(info); db.bitsharesAssetDao().insertBitsharesAssetInfo(info);

View file

@ -1,42 +0,0 @@
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.BitcoinAddress;
import cy.agorise.crystalwallet.models.BitcoinTransaction;
import cy.agorise.crystalwallet.models.BitcoinTransactionExtended;
/**
* Created by Henry Varona on 10/17/2018.
*/
@Dao
public interface BitcoinAddressDao {
@Query("SELECT * FROM bitcoin_address")
LiveData<BitcoinAddress> getAll();
@Query("SELECT COUNT(*) FROM bitcoin_address ba WHERE ba.address = :address")
Boolean addressExists(String address);
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address = :address")
BitcoinAddress getdadress(String address);
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address_index = :index and ba.is_change = 'true'")
BitcoinAddress getChangeByIndex(long index);
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address_index = :index and ba.is_change = 'false'")
BitcoinAddress getExternalByIndex(long index);
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'true' ")
long getLastChangeAddress(long accountId);
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'false' ")
long getLastExternalAddress(long accountId);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public long[] insertBitcoinAddresses(BitcoinAddress... addresses);
}

View file

@ -1,41 +0,0 @@
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 java.util.List;
import cy.agorise.crystalwallet.models.BitcoinTransaction;
import cy.agorise.crystalwallet.models.BitcoinTransactionExtended;
import cy.agorise.crystalwallet.models.BitcoinTransactionGTxIO;
/**
* 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")
List<BitcoinTransaction> getTransactionsByTxid(String txid);
@Query("SELECT * FROM bitcoin_transaction bt WHERE bt.crypto_coin_transaction_id = :idCryptoCoinTransaction")
BitcoinTransaction getBitcoinTransactionByCryptoCoinTransaction(long idCryptoCoinTransaction);
@Query("SELECT * FROM bitcoin_transaction_gt_io bt WHERE bt.bitcoin_transaction_id= :idBitcoinTransaction")
List<BitcoinTransactionGTxIO> getGtxIOByTransaction(long idBitcoinTransaction);
@Query("SELECT * FROM bitcoin_transaction_gt_io bt WHERE bt.address= :address")
List<BitcoinTransactionGTxIO> getGtxIOByAddress(String address);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public long[] insertBitcoinTransaction(BitcoinTransaction... transactions);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public long[] insertBitcoinTransactionGTxIO(BitcoinTransactionGTxIO... transactiongtxios);
}

View file

@ -23,9 +23,6 @@ public interface CryptoCurrencyDao {
@Query("SELECT * FROM crypto_currency WHERE id = :id") @Query("SELECT * FROM crypto_currency WHERE id = :id")
CryptoCurrency getById(long id); CryptoCurrency getById(long id);
@Query("SELECT * FROM crypto_currency WHERE id = :id")
LiveData<CryptoCurrency> getLDById(long id);
@Query("SELECT * FROM crypto_currency WHERE name = :name AND crypto_net = :cryptoNet") @Query("SELECT * FROM crypto_currency WHERE name = :name AND crypto_net = :cryptoNet")
CryptoCurrency getByNameAndCryptoNet(String name,String cryptoNet); CryptoCurrency getByNameAndCryptoNet(String name,String cryptoNet);
@ -35,8 +32,8 @@ public interface CryptoCurrencyDao {
@Query("SELECT * FROM crypto_currency WHERE name = :name") @Query("SELECT * FROM crypto_currency WHERE name = :name")
LiveData<CryptoCurrency> getLiveDataByName(String name); LiveData<CryptoCurrency> getLiveDataByName(String name);
@Query("SELECT * FROM crypto_currency WHERE name = :name and crypto_net = :cryptoNet") @Query("SELECT * FROM crypto_currency WHERE name = :name")
CryptoCurrency getByName(String name, String cryptoNet); CryptoCurrency getByName(String name);
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
public long[] insertCryptoCurrency(CryptoCurrency... currencies); public long[] insertCryptoCurrency(CryptoCurrency... currencies);

View file

@ -29,9 +29,6 @@ public interface CryptoNetAccountDao {
@Query("SELECT cna.* FROM crypto_net_account cna WHERE seed_id = :seedId") @Query("SELECT cna.* FROM crypto_net_account cna WHERE seed_id = :seedId")
List<CryptoNetAccount> getAllCryptoNetAccountBySeed( long seedId); List<CryptoNetAccount> getAllCryptoNetAccountBySeed( long seedId);
@Query("SELECT cna.* FROM crypto_net_account cna WHERE crypto_net == 'BITCOIN'")
LiveData<List<CryptoNetAccount>> getAllBitcoins();
@Query("SELECT * FROM crypto_net_account WHERE id = :accountId") @Query("SELECT * FROM crypto_net_account WHERE id = :accountId")
LiveData<CryptoNetAccount> getByIdLiveData( long accountId); LiveData<CryptoNetAccount> getByIdLiveData( long accountId);

View file

@ -10,9 +10,6 @@ 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.BitcoinAddress;
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;
@ -42,11 +39,8 @@ import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
BitsharesAssetInfo.class, BitsharesAssetInfo.class,
BitsharesAccountNameCache.class, BitsharesAccountNameCache.class,
CryptoCurrencyEquivalence.class, CryptoCurrencyEquivalence.class,
GeneralSetting.class, GeneralSetting.class
BitcoinTransaction.class, }, version = 4, exportSchema = false)
BitcoinTransactionGTxIO.class,
BitcoinAddress.class
}, version = 6, exportSchema = false)
@TypeConverters({Converters.class}) @TypeConverters({Converters.class})
public abstract class CrystalDatabase extends RoomDatabase { public abstract class CrystalDatabase extends RoomDatabase {
@ -63,8 +57,6 @@ 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 abstract BitcoinAddressDao bitcoinAddressDao();
public static CrystalDatabase getAppDatabase(Context context) { public static CrystalDatabase getAppDatabase(Context context) {
if (instance == null) { if (instance == null) {
@ -72,10 +64,8 @@ public abstract class CrystalDatabase extends RoomDatabase {
Room.databaseBuilder(context, Room.databaseBuilder(context,
CrystalDatabase.class, "CrystalWallet.db") CrystalDatabase.class, "CrystalWallet.db")
.allowMainThreadQueries() .allowMainThreadQueries()
//.addMigrations(MIGRATION_2_3) .addMigrations(MIGRATION_2_3)
//.addMigrations(MIGRATION_3_4) .addMigrations(MIGRATION_3_4)
//.addMigrations(MIGRATION_4_5)
//.addMigrations(MIGRATION_5_6)
.build(); .build();
} }
return instance; return instance;
@ -101,41 +91,4 @@ 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,"
+"amount INTEGER NOT NULL,"
+"script_hex TEXT,"
+"original_txid TEXT,"
+"PRIMARY KEY (bitcoin_transaction_id, io_index, is_output),"
+"FOREIGN KEY (bitcoin_transaction_id) REFERENCES bitcoin_transaction(crypto_coin_transaction_id) ON DELETE CASCADE)");
}
};
static final Migration MIGRATION_5_6 = new Migration(5, 6) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE bitcoin_address ("
+"account_id INTEGER NOT NULL,"
+"address_index INTEGER NOT NULL,"
+"is_change INTEGER NOT NULL,"
+"address TEXT NOT NULL,"
+"PRIMARY KEY (account_id, address_index, is_change),"
+"FOREIGN KEY (account_id) REFERENCES crypto_net_account(id) ON DELETE CASCADE)");
}
};
} }

View file

@ -51,10 +51,7 @@ public interface TransactionDao {
List<CryptoCoinTransaction> getByIdAccount(long idAccount); List<CryptoCoinTransaction> getByIdAccount(long idAccount);
@Query("SELECT * FROM crypto_coin_transaction WHERE id = :id") @Query("SELECT * FROM crypto_coin_transaction WHERE id = :id")
LiveData<CryptoCoinTransaction> getByIdLiveData(long id); LiveData<CryptoCoinTransaction> getById(long id);
@Query("SELECT * FROM crypto_coin_transaction WHERE id = :id")
CryptoCoinTransaction getById(long id);
@Query("SELECT * FROM crypto_coin_transaction WHERE date = :date and 'from' = :from and 'to' = :to and amount = :amount ") @Query("SELECT * FROM crypto_coin_transaction WHERE date = :date and 'from' = :from and 'to' = :to and amount = :amount ")
CryptoCoinTransaction getByTransaction(Date date, String from, String to, long amount); CryptoCoinTransaction getByTransaction(Date date, String from, String to, long amount);

View file

@ -1,7 +1,5 @@
package cy.agorise.crystalwallet.enums; package cy.agorise.crystalwallet.enums;
import org.bitcoinj.core.NetworkParameters;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -13,26 +11,21 @@ import java.util.List;
*/ */
public enum CryptoCoin implements Serializable { public enum CryptoCoin implements Serializable {
BITCOIN(CryptoNet.BITCOIN,"BTC",8,0,NetworkParameters.fromID(NetworkParameters.ID_TESTNET)), BITCOIN(CryptoNet.BITCOIN,"BTC",8),
BITCOIN_TEST(CryptoNet.BITCOIN_TEST,"BTC",8,1,NetworkParameters.fromID(NetworkParameters.ID_TESTNET)), BITCOIN_TEST(CryptoNet.BITCOIN_TEST,"BTC",8),
LITECOIN(CryptoNet.LITECOIN,"LTC",8,2,null), LITECOIN(CryptoNet.LITECOIN,"LTC",8),
DASH(CryptoNet.DASH,"DASH",8,5,null), DASH(CryptoNet.DASH,"DASH",8),
DOGECOIN(CryptoNet.DOGECOIN,"DOGE",8,3,null), DOGECOIN(CryptoNet.DOGECOIN,"DOGE",8),
BITSHARES(CryptoNet.BITSHARES,"BTS",5,0,null), BITSHARES(CryptoNet.BITSHARES,"BTS",5);
STEEM(CryptoNet.STEEM,"BTS",5,0,null);
protected CryptoNet cryptoNet; protected CryptoNet cryptoNet;
protected String label; protected String label;
protected int precision; protected int precision;
protected int coinNumber;
protected NetworkParameters parameters;
CryptoCoin(CryptoNet cryptoNet, String label, int precision, int coinNumber, NetworkParameters parameters){ CryptoCoin(CryptoNet cryptoNet, String label, int precision){
this.cryptoNet = cryptoNet; this.cryptoNet = cryptoNet;
this.label = label; this.label = label;
this.precision = precision; this.precision = precision;
this.coinNumber = coinNumber;
this.parameters = parameters;
} }
@ -45,14 +38,6 @@ public enum CryptoCoin implements Serializable {
public int getPrecision(){ public int getPrecision(){
return this.precision; return this.precision;
} }
public NetworkParameters getParameters() {
return parameters;
}
public int getCoinNumber() {
return coinNumber;
}
public static List<CryptoCoin> getByCryptoNet(CryptoNet cryptoNet){ public static List<CryptoCoin> getByCryptoNet(CryptoNet cryptoNet){
List<CryptoCoin> result = new ArrayList<CryptoCoin>(); List<CryptoCoin> result = new ArrayList<CryptoCoin>();

View file

@ -4,8 +4,6 @@ import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import cy.agorise.crystalwallet.R;
/** /**
* CryptoNet Enumeration, a Crypto Net is define as the net where a CryptoCoin works, iniside the * CryptoNet Enumeration, a Crypto Net is define as the net where a CryptoCoin works, iniside the
* CrypotNet is where the transaction and balance works, using the CryptoCoin Assets * CrypotNet is where the transaction and balance works, using the CryptoCoin Assets
@ -13,14 +11,7 @@ import cy.agorise.crystalwallet.R;
* Created by Henry Varona on 12/9/2017. * Created by Henry Varona on 12/9/2017.
*/ */
public enum CryptoNet implements Serializable { public enum CryptoNet implements Serializable {
UNKNOWN("UNKNOWN",6,-1,android.R.drawable .ic_menu_help), UNKNOWN("UNKNOWN",6,-1), BITCOIN("BITCOIN",6,1), BITCOIN_TEST("BITCOIN(TEST)",6,2), LITECOIN("LITECOIN",6,3), DASH("DASH",6,5), DOGECOIN("DOGECOIN",6,4), BITSHARES("BITSHARES",1,6), STEEM("STEEM",1,7);
BITCOIN("BITCOIN",6,1,R.drawable.coin_icon_bitcoin),
BITCOIN_TEST("BITCOIN(TEST)",6,2,R.drawable.coin_icon_bitcoin),
LITECOIN("LITECOIN",6,3,R.drawable.coin_icon_litecoin),
DASH("DASH",6,5,R.drawable.coin_icon_dash),
DOGECOIN("DOGECOIN",6,4,R.drawable.coin_icon_doge),
BITSHARES("BITSHARES",1,6,R.drawable.bts),
STEEM("STEEM",1,7,R.drawable.coin_icon_steem);
protected String label; protected String label;
@ -28,8 +19,6 @@ public enum CryptoNet implements Serializable {
protected int bip44Index; protected int bip44Index;
protected int iconImageResource;
private static Map<Integer, CryptoNet> bip44Map = new HashMap<Integer, CryptoNet>(); private static Map<Integer, CryptoNet> bip44Map = new HashMap<Integer, CryptoNet>();
static { static {
for (CryptoNet cryptoNetEnum : CryptoNet.values()) { for (CryptoNet cryptoNetEnum : CryptoNet.values()) {
@ -37,11 +26,10 @@ public enum CryptoNet implements Serializable {
} }
} }
CryptoNet(String label,int confirmationsNeeded, int bip44Index, int iconImageResource){ CryptoNet(String label,int confirmationsNeeded, int bip44Index){
this.label = label; this.label = label;
this.confirmationsNeeded = confirmationsNeeded; this.confirmationsNeeded = confirmationsNeeded;
this.bip44Index = bip44Index; this.bip44Index = bip44Index;
this.iconImageResource = iconImageResource;
} }
public String getLabel(){ public String getLabel(){
@ -56,10 +44,6 @@ public enum CryptoNet implements Serializable {
return this.bip44Index; return this.bip44Index;
} }
public int getIconImageResource() {
return this.iconImageResource;
}
public static CryptoNet fromBip44Index(int index){ public static CryptoNet fromBip44Index(int index){
if (bip44Map.containsKey(index)) { if (bip44Map.containsKey(index)) {
return bip44Map.get(index); return bip44Map.get(index);

View file

@ -6,6 +6,5 @@ package cy.agorise.crystalwallet.enums;
public enum SeedType { public enum SeedType {
BIP39, BIP39,
BRAINKEY, BRAINKEY
WIF
} }

View file

@ -7,11 +7,8 @@ import android.text.SpannableStringBuilder;
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.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
@ -44,22 +41,6 @@ public class AccountsSettingsFragment extends Fragment {
@BindView(R.id.tvRemove) @BindView(R.id.tvRemove)
public TextView tvRemove; public TextView tvRemove;
@BindView(R.id.btnUpgrade)
public Button btnUpgrade;
@BindView(R.id.btnImport)
public Button btnImport;
@BindView(R.id.btnRefresh)
public Button btnRefresh;
@BindView(R.id.btnRemove)
public Button btnRemove;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
@ -72,36 +53,6 @@ public class AccountsSettingsFragment extends Fragment {
tvRefresh.setText(makeFirstWordsBold(getResources().getString(R.string.refresh_description))); tvRefresh.setText(makeFirstWordsBold(getResources().getString(R.string.refresh_description)));
tvRemove.setText(makeFirstWordsBold(getResources().getString(R.string.remove_description))); tvRemove.setText(makeFirstWordsBold(getResources().getString(R.string.remove_description)));
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnUpgrade)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
}
} );
PushDownAnim.setPushDownAnimTo(btnImport)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
}
} );
PushDownAnim.setPushDownAnimTo(btnRefresh)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
}
} );
PushDownAnim.setPushDownAnimTo(btnRemove)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
}
} );
return v; return v;
} }

View file

@ -1,21 +1,14 @@
package cy.agorise.crystalwallet.fragments; package cy.agorise.crystalwallet.fragments;
import android.Manifest;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.support.annotation.NonNull;
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.content.ContextCompat;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
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;
@ -23,8 +16,6 @@ import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import java.io.File; import java.io.File;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -48,11 +39,6 @@ import cy.agorise.crystalwallet.requestmanagers.FileServiceRequests;
*/ */
public class BackupsSettingsFragment extends Fragment{ public class BackupsSettingsFragment extends Fragment{
private static final int PERMISSION_REQUEST_CODE = 1;
public BackupsSettingsFragment() { public BackupsSettingsFragment() {
// Required empty public constructor // Required empty public constructor
} }
@ -79,7 +65,6 @@ public class BackupsSettingsFragment extends Fragment{
@BindView(R.id.btnBinFile) @BindView(R.id.btnBinFile)
public Button btnBinFile; public Button btnBinFile;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
@ -87,25 +72,6 @@ public class BackupsSettingsFragment extends Fragment{
View v = inflater.inflate(R.layout.fragment_backups_settings, container, false); View v = inflater.inflate(R.layout.fragment_backups_settings, container, false);
ButterKnife.bind(this, v); ButterKnife.bind(this, v);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnBinFile)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
makeBackupFile();
}
} );
PushDownAnim.setPushDownAnimTo(btnBrainkey)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
btnBrainOnClick();
}
} );
tvBinFile.setText(makeFirstWordsBold(getResources().getString(R.string.bin_file_description))); tvBinFile.setText(makeFirstWordsBold(getResources().getString(R.string.bin_file_description)));
tvBrainkey.setText(makeFirstWordsBold(getResources().getString(R.string.brainkey_description))); tvBrainkey.setText(makeFirstWordsBold(getResources().getString(R.string.brainkey_description)));
tvWIFKey.setText(makeFirstWordsBold(getResources().getString(R.string.wif_key_description))); tvWIFKey.setText(makeFirstWordsBold(getResources().getString(R.string.wif_key_description)));
@ -126,40 +92,12 @@ public class BackupsSettingsFragment extends Fragment{
public void btnBrainOnClick(){ public void btnBrainOnClick(){
Intent intent = new Intent(getContext(), BackupSeedActivity.class); Intent intent = new Intent(getContext(), BackupSeedActivity.class);
intent. putExtra("SEED_ID","");
startActivity(intent); startActivity(intent);
} }
@OnClick(R.id.btnBinFile) @OnClick(R.id.btnBinFile)
public void makeBackupFile(){ public void makeBackupFile(){
/*
* Check for WRITE_EXTERNAL_STORAGE 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
makeBackupfileAfterPermission();
} else {
requestPermission(); // Code for permission
}
}
else {
// Code for Below 23 API Oriented Device
// Do next code
makeBackupfileAfterPermission();
}
}
private void makeBackupfileAfterPermission(){
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
LiveData<GeneralSetting> generalSettingLD = CrystalDatabase.getAppDatabase(getContext()).generalSettingDao().getByName(GeneralSetting.SETTING_PASSWORD); LiveData<GeneralSetting> generalSettingLD = CrystalDatabase.getAppDatabase(getContext()).generalSettingDao().getByName(GeneralSetting.SETTING_PASSWORD);
@ -167,13 +105,13 @@ public class BackupsSettingsFragment extends Fragment{
generalSettingLD.observe(this, new Observer<GeneralSetting>() { generalSettingLD.observe(this, new Observer<GeneralSetting>() {
@Override @Override
public void onChanged(@Nullable GeneralSetting generalSetting) { public void onChanged(@Nullable GeneralSetting generalSetting) {
String password = ""; String password = "";
if (generalSetting != null) { if (generalSetting != null) {
password = generalSetting.getValue(); password = generalSetting.getValue();
} }
final CreateBackupRequest backupFileRequest = new CreateBackupRequest(getContext(), password); final CreateBackupRequest backupFileRequest = new CreateBackupRequest(getContext(), password);
backupFileRequest.setListener(new FileServiceRequestListener() { backupFileRequest.setListener(new FileServiceRequestListener() {
@Override @Override
public void onCarryOut() { public void onCarryOut() {
@ -194,40 +132,4 @@ public class BackupsSettingsFragment extends Fragment{
}); });
} }
} }
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() {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.Permision_storage), Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("value", "Permission Granted, Now you can use local drive .");
} else {
Log.e("value", "Permission Denied, You cannot use local drive .");
makeBackupfileAfterPermission();
}
break;
}
}
} }

View file

@ -3,15 +3,13 @@ package cy.agorise.crystalwallet.fragments;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
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.widget.TextView;
import java.util.List; import java.util.List;
@ -19,20 +17,15 @@ import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.models.CryptoNetBalance; import cy.agorise.crystalwallet.models.CryptoNetBalance;
import cy.agorise.crystalwallet.viewmodels.CryptoCoinBalanceListViewModel;
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel; import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
import cy.agorise.crystalwallet.views.CryptoNetBalanceListAdapter; import cy.agorise.crystalwallet.views.CryptoNetBalanceListView;
public class BalanceFragment extends Fragment { public class BalanceFragment extends Fragment {
CryptoNetBalanceListViewModel cryptoNetBalanceListViewModel; CryptoNetBalanceListViewModel cryptoNetBalanceListViewModel;
@BindView(R.id.tvNoBalances) @BindView(R.id.vCryptoNetBalanceListView)
TextView tvNoBalances; CryptoNetBalanceListView vCryptoNetBalanceListView;
@BindView(R.id.rvBalances)
RecyclerView rvBalances;
CryptoNetBalanceListAdapter balancesAdapter;
public BalanceFragment() { public BalanceFragment() {
// Required empty public constructor // Required empty public constructor
@ -51,33 +44,22 @@ public class BalanceFragment extends Fragment {
} }
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_balance, container, false); View view = inflater.inflate(R.layout.fragment_balance, container, false);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
// Configure RecyclerView and its adapter
rvBalances.setLayoutManager(new LinearLayoutManager(getContext()));
balancesAdapter = new CryptoNetBalanceListAdapter(this);
rvBalances.setAdapter(balancesAdapter);
//Prevents the UI from an infinite scrolling of balances
rvBalances.setNestedScrollingEnabled(false);
cryptoNetBalanceListViewModel = ViewModelProviders.of(this).get(CryptoNetBalanceListViewModel.class); cryptoNetBalanceListViewModel = ViewModelProviders.of(this).get(CryptoNetBalanceListViewModel.class);
final LiveData<List<CryptoNetBalance>> cryptoNetBalanceData = cryptoNetBalanceListViewModel.getCryptoNetBalanceList(); LiveData<List<CryptoNetBalance>> cryptoNetBalanceData = cryptoNetBalanceListViewModel.getCryptoNetBalanceList();
vCryptoNetBalanceListView.setData(null, this);
final Fragment fragment = this;
cryptoNetBalanceData.observe(this, new Observer<List<CryptoNetBalance>>() { cryptoNetBalanceData.observe(this, new Observer<List<CryptoNetBalance>>() {
@Override @Override
public void onChanged(List<CryptoNetBalance> cryptoNetBalances) { public void onChanged(List<CryptoNetBalance> cryptoNetBalances) {
balancesAdapter.submitList(cryptoNetBalances); vCryptoNetBalanceListView.setData(cryptoNetBalances, fragment);
if(cryptoNetBalances != null && cryptoNetBalances.size() > 0) {
tvNoBalances.setVisibility(View.INVISIBLE);
} else {
tvNoBalances.setVisibility(View.VISIBLE);
}
} }
}); });

View file

@ -19,7 +19,6 @@ import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import com.vincent.filepicker.Constant; import com.vincent.filepicker.Constant;
import com.vincent.filepicker.activity.AudioPickActivity; import com.vincent.filepicker.activity.AudioPickActivity;
import com.vincent.filepicker.filter.entity.AudioFile; import com.vincent.filepicker.filter.entity.AudioFile;
@ -74,9 +73,6 @@ public class BitsharesSettingsFragment extends Fragment {
GrapheneAccountInfo grapheneAccountInfo; GrapheneAccountInfo grapheneAccountInfo;
GrapheneAccount grapheneAccount; GrapheneAccount grapheneAccount;
public BitsharesSettingsFragment() { public BitsharesSettingsFragment() {
if (getArguments() != null) { if (getArguments() != null) {
long cryptoNetAcountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID", -1); long cryptoNetAcountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID", -1);
@ -118,17 +114,6 @@ public class BitsharesSettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_bitshares_settings, container, false); View v = inflater.inflate(R.layout.fragment_bitshares_settings, container, false);
ButterKnife.bind(this, v); ButterKnife.bind(this, v);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnUpgradeToLtm)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
upgradeAccountToLtm();
}
} );
initAlreadyLtm(); initAlreadyLtm();
return v; return v;

View file

@ -14,7 +14,6 @@ import android.support.v7.widget.RecyclerView;
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.widget.TextView;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -28,9 +27,6 @@ public class ContactsFragment extends Fragment {
@BindView(R.id.rvContacts) @BindView(R.id.rvContacts)
RecyclerView rvContacts; RecyclerView rvContacts;
@BindView(R.id.tvNoContacts)
TextView tvNoContacts;
ContactListAdapter adapter; ContactListAdapter adapter;
FloatingActionButton fabAddContact; FloatingActionButton fabAddContact;
@ -90,13 +86,6 @@ public class ContactsFragment extends Fragment {
@Override @Override
public void onChanged(@Nullable PagedList<Contact> contacts) { public void onChanged(@Nullable PagedList<Contact> contacts) {
adapter.submitList(contacts); adapter.submitList(contacts);
if(contacts != null && contacts.size() > 0){
tvNoContacts.setVisibility(View.INVISIBLE);
}
else{
tvNoContacts.setVisibility(View.VISIBLE);
}
} }
}); });

View file

@ -1,127 +0,0 @@
package cy.agorise.crystalwallet.fragments;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
/**
* Created by xd on 12/28/17.
*/
public class CryptoNetAccountActivationSettingsFragment extends Fragment {
@BindView(R.id.tvMnemonic)
TextView tvMnemonic;
@BindView(R.id.btnCopy)
Button btnCopy;
CryptoNetAccount cryptoNetAccount;
AccountSeed accountSeed;
public CryptoNetAccountActivationSettingsFragment() {
if (getArguments() != null) {
long cryptoNetAcountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID", -1);
if (cryptoNetAcountId > -1) {
this.cryptoNetAccount = CrystalDatabase.getAppDatabase(getContext()).cryptoNetAccountDao().getById(cryptoNetAcountId);
this.accountSeed = CrystalDatabase.getAppDatabase(getContext()).accountSeedDao().findById(this.cryptoNetAccount.getSeedId());
}
}
// Required empty public constructor
}
public static CryptoNetAccountActivationSettingsFragment newInstance(long cryptoNetAccountId) {
CryptoNetAccountActivationSettingsFragment fragment = new CryptoNetAccountActivationSettingsFragment();
Bundle args = new Bundle();
args.putLong("CRYPTO_NET_ACCOUNT_ID", cryptoNetAccountId);
fragment.setArguments(args);
if (cryptoNetAccountId > -1){
fragment.cryptoNetAccount = CrystalDatabase.getAppDatabase(fragment.getContext()).cryptoNetAccountDao().getById(cryptoNetAccountId);
fragment.accountSeed = CrystalDatabase.getAppDatabase(fragment.getContext()).accountSeedDao().findById(fragment.cryptoNetAccount.getSeedId());
}
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false);
ButterKnife.bind(this, v);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnCopy)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
btnCopyClick();
}
} );
initAlreadyLtm();
return v;
}
public void initAlreadyLtm(){
if (this.cryptoNetAccount != null) {
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();
}
}

View file

@ -1,121 +0,0 @@
package cy.agorise.crystalwallet.fragments;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetSelection;
import cy.agorise.crystalwallet.requestmanagers.CreateBitcoinAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.views.CryptoNetSelectionListAdapter;
/**
* Created by xd on 12/28/17.
*/
public class GeneralAccountSeedCoinSettingsFragment extends Fragment implements CryptoNetSelectionListAdapter.CryptoNetSelectionListener {
@BindView(R.id.rvCoinSelection)
RecyclerView rvCoinSelection;
AccountSeed accountSeed;
ArrayList<CryptoNetSelection> cryptoNetSelectionList;
public GeneralAccountSeedCoinSettingsFragment() {
if (getArguments() != null) {
long accountSeedId = getArguments().getLong("SEED_ID", -1);
if (accountSeedId > -1) {
this.accountSeed = CrystalDatabase.getAppDatabase(getContext()).accountSeedDao().findById(accountSeedId);
}
}
cryptoNetSelectionList = new ArrayList<CryptoNetSelection>();
CryptoNetSelection nextCryptoNetSelection;
for (CryptoNet nextCryptoNet : CryptoNet.values()){
if ((nextCryptoNet != CryptoNet.UNKNOWN) && (nextCryptoNet != CryptoNet.BITCOIN_TEST)) {
nextCryptoNetSelection = new CryptoNetSelection(nextCryptoNet, false);
cryptoNetSelectionList.add(nextCryptoNetSelection);
}
}
// Required empty public constructor
}
public static GeneralAccountSeedCoinSettingsFragment newInstance(long accountSeedId) {
GeneralAccountSeedCoinSettingsFragment fragment = new GeneralAccountSeedCoinSettingsFragment();
Bundle args = new Bundle();
args.putLong("SEED_ID", accountSeedId);
fragment.setArguments(args);
if (accountSeedId > -1){
fragment.accountSeed = CrystalDatabase.getAppDatabase(fragment.getContext()).accountSeedDao().findById(accountSeedId);
}
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_general_account_seed_coin_settings, container, false);
ButterKnife.bind(this, v);
CryptoNetSelectionListAdapter cryptoNetSelectionListAdapter = new CryptoNetSelectionListAdapter(this.cryptoNetSelectionList);
cryptoNetSelectionListAdapter.addListener(this);
rvCoinSelection.setAdapter(cryptoNetSelectionListAdapter);
LinearLayoutManager llm = new LinearLayoutManager(this.getContext());
llm.setOrientation(LinearLayoutManager.VERTICAL);
rvCoinSelection.setLayoutManager(llm);
return v;
}
@Override
public void onCryptoNetSelectionChecked(CryptoNetSelection source) {
//Toast.makeText(this.getContext(),"the coin "+source.getCryptoNet().name()+" was "+(source.getSelected()?"selected":"unselected"),Toast.LENGTH_LONG).show();
List<CryptoCoin> cryptoCoins = CryptoCoin.getByCryptoNet(source.getCryptoNet());
final CreateBitcoinAccountRequest request = new CreateBitcoinAccountRequest(this.accountSeed,this.getContext(),cryptoCoins.get(0));
request.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if (request.getStatus() == CreateBitcoinAccountRequest.StatusCode.SUCCEEDED){
Toast.makeText(getContext(),"The account was successfully created",Toast.LENGTH_LONG);
} else {
Toast.makeText(getContext(),"There was an error enabling the account",Toast.LENGTH_LONG);
}
}
});
CryptoNetInfoRequests.getInstance().addRequest(request);
}
}

View file

@ -1,122 +0,0 @@
package cy.agorise.crystalwallet.fragments;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
/**
* Created by xd on 12/28/17.
*/
public class GeneralAccountSeedFragment extends Fragment {
@BindView(R.id.tvMnemonic)
TextView tvMnemonic;
@BindView(R.id.btnCopy)
Button btnCopy;
AccountSeed accountSeed;
public GeneralAccountSeedFragment() {
if (getArguments() != null) {
long accountSeedId = getArguments().getLong("SEED_ID", -1);
if (accountSeedId > -1) {
this.accountSeed = CrystalDatabase.getAppDatabase(getContext()).accountSeedDao().findById(accountSeedId);
}
}
// Required empty public constructor
}
public static GeneralAccountSeedFragment newInstance(long accountSeedId) {
GeneralAccountSeedFragment fragment = new GeneralAccountSeedFragment();
Bundle args = new Bundle();
args.putLong("SEED_ID", accountSeedId);
fragment.setArguments(args);
if (accountSeedId > -1){
fragment.accountSeed = CrystalDatabase.getAppDatabase(fragment.getContext()).accountSeedDao().findById(accountSeedId);
}
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false);
ButterKnife.bind(this, v);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnCopy)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
btnCopyClick();
}
} );
initAlreadyLtm();
return v;
}
public void initAlreadyLtm(){
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();
}
}

View file

@ -1,10 +1,6 @@
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;
@ -12,15 +8,11 @@ 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 com.thekhaeng.pushdownanim.PushDownAnim;
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;
@ -38,15 +30,9 @@ 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) {
@ -87,18 +73,6 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false); View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false);
ButterKnife.bind(this, v); ButterKnife.bind(this, v);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnCopy)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
btnCopyClick();
}
} );
initAlreadyLtm(); initAlreadyLtm();
return v; return v;
@ -109,24 +83,4 @@ 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();
}
} }

View file

@ -15,12 +15,10 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import com.thekhaeng.pushdownanim.PushDownAnim;
import com.vincent.filepicker.Constant; import com.vincent.filepicker.Constant;
import com.vincent.filepicker.activity.AudioPickActivity; import com.vincent.filepicker.activity.AudioPickActivity;
import com.vincent.filepicker.filter.entity.AudioFile; import com.vincent.filepicker.filter.entity.AudioFile;
@ -73,8 +71,6 @@ public class GeneralSettingsFragment extends Fragment {
Spinner spDisplayDateTime; Spinner spDisplayDateTime;
@BindView (R.id.tvReceiveFundsSoundValue) @BindView (R.id.tvReceiveFundsSoundValue)
TextView tvReceiveFundsSound; TextView tvReceiveFundsSound;
@BindView (R.id.btnContact)
Button btnContact;
public GeneralSettingsFragment() { public GeneralSettingsFragment() {
this.spPreferredLanguageInitialized = false; this.spPreferredLanguageInitialized = false;
@ -103,17 +99,6 @@ public class GeneralSettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_general_settings, container, false); View v = inflater.inflate(R.layout.fragment_general_settings, container, false);
ButterKnife.bind(this, v); ButterKnife.bind(this, v);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnContact)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
}
} );
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class); generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList(); generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList();

View file

@ -5,20 +5,13 @@ 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.graphics.PorterDuff;
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.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
@ -26,15 +19,11 @@ import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Toast; import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import com.vincent.filepicker.ToastUtil;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.OnTouch;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.activities.BoardActivity; import cy.agorise.crystalwallet.activities.BoardActivity;
import cy.agorise.crystalwallet.activities.ImportSeedActivity; import cy.agorise.crystalwallet.activities.ImportSeedActivity;
@ -60,10 +49,7 @@ public class ImportAccountOptionsFragment extends DialogFragment {
Button btnClose; Button btnClose;
@BindView(R.id.btnImportBackup) @BindView(R.id.btnImportBackup)
Button btnImportBackup; Button btnImportBackup;
@BindView(R.id.btnImportSeed)
Button btnImportSeed;
private static final int PERMISSION_REQUEST_CODE = 1;
/* /*
Dialog for loading Dialog for loading
@ -104,34 +90,6 @@ public class ImportAccountOptionsFragment extends DialogFragment {
View view = inflater.inflate(R.layout.fragment_import_account_options, null); View view = inflater.inflate(R.layout.fragment_import_account_options, null);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnClose)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
cancel();
}
} );
PushDownAnim.setPushDownAnimTo(btnImportBackup)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
importBackup();
}
} );
PushDownAnim.setPushDownAnimTo(btnImportSeed)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
importSeed();
}
} );
return builder.setView(view).create(); return builder.setView(view).create();
} }
@ -152,88 +110,18 @@ 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(), getActivity().getResources().getString(R.string.Permision_storage), 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

View file

@ -3,30 +3,18 @@ package cy.agorise.crystalwallet.fragments;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
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.v4.app.Fragment; import android.support.v4.app.Fragment;
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.widget.Button;
import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
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.activities.BoardActivity;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor; import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel; import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator; import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
@ -37,12 +25,6 @@ import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
public class NoneSecurityFragment extends Fragment { public class NoneSecurityFragment extends Fragment {
@BindView(R.id.btnOK)
Button btnOK;
public NoneSecurityFragment() { public NoneSecurityFragment() {
// Required empty public constructor // Required empty public constructor
} }
@ -61,41 +43,14 @@ public class NoneSecurityFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_none_security, container, false); View v = inflater.inflate(R.layout.fragment_none_security, container, false);
ButterKnife.bind(this, v); ButterKnife.bind(this, v);
return v; return v;
} }
@OnClick(R.id.btnOK)
public void btnOKClic(){
/*
* Question if user is sure to remove the security
* */
final QuestionDialog questionDialog = new QuestionDialog(getActivity());
questionDialog.setText(getActivity().getString(R.string.question_continue));
questionDialog.setOnNegative(new NegativeResponse() {
@Override @Override
public void onNegative(@NotNull DialogMaterial dialogMaterial) {
}
});
questionDialog.setOnPositive(new PositiveResponse() {
@Override
public void onPositive() {
CrystalSecurityMonitor.getInstance(null).clearSecurity();
Toast.makeText(getActivity().getBaseContext(),getActivity().getString(R.string.Security_mode_changed_to_none),
Toast.LENGTH_SHORT).show();
}
});
questionDialog.show();
}
/*@Override
public void setUserVisibleHint(boolean isVisibleToUser) { public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser); super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) { if (isVisibleToUser) {
CrystalSecurityMonitor.getInstance(null).clearSecurity(); CrystalSecurityMonitor.getInstance(null).clearSecurity();
} }
}*/ }
} }

View file

@ -1,15 +1,12 @@
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.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.text.Editable; import android.text.Editable;
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;
@ -21,19 +18,13 @@ import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener; import com.andrognito.patternlockview.listener.PatternLockViewListener;
import java.util.List; import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnTextChanged; import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor; import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.dialogs.material.CrystalDialog;
import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.util.ChildViewPager;
import cy.agorise.crystalwallet.util.PasswordManager; import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel; import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator; import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
@ -51,17 +42,9 @@ public class PatternSecurityFragment extends Fragment {
@BindView(R.id.tvPatternText) @BindView(R.id.tvPatternText)
TextView tvPatternText; TextView tvPatternText;
/*
* Contains the ChildViewPager to block the viewpager when the user is using the pattern control
* */
private ChildViewPager childViewPager;
private PatternLockViewListener actualPatternListener; private PatternLockViewListener actualPatternListener;
private String patternEntered; private String patternEntered;
public PatternSecurityFragment() { public PatternSecurityFragment() {
// Required empty public constructor // Required empty public constructor
} }
@ -94,11 +77,6 @@ public class PatternSecurityFragment extends Fragment {
return patternString; return patternString;
} }
public void setChildViewPager(ChildViewPager childViewPager) {
this.childViewPager = childViewPager;
}
public void removePatternListener(){ public void removePatternListener(){
if (actualPatternListener != null){ if (actualPatternListener != null){
patternLockView.removePatternLockListener(actualPatternListener); patternLockView.removePatternLockListener(actualPatternListener);
@ -109,12 +87,12 @@ public class PatternSecurityFragment extends Fragment {
public void showNewPatternUI(){ public void showNewPatternUI(){
removePatternListener(); removePatternListener();
patternLockView.clearPattern(); patternLockView.clearPattern();
tvPatternText.setTextColor(Color.WHITE); tvPatternText.setText("Enter new pattern");
tvPatternText.setText(getActivity().getResources().getString(R.string.Enter_new_pattern));
actualPatternListener = new PatternLockViewListener() { actualPatternListener = new PatternLockViewListener() {
@Override @Override
public void onStarted() { public void onStarted() {
} }
@Override @Override
@ -140,7 +118,7 @@ public class PatternSecurityFragment extends Fragment {
removePatternListener(); removePatternListener();
patternLockView.clearPattern(); patternLockView.clearPattern();
patternLockView.requestFocus(); patternLockView.requestFocus();
tvPatternText.setText(getActivity().getResources().getString(R.string.Confirm_new_pattern)); tvPatternText.setText("Confirm new pattern");
actualPatternListener = new PatternLockViewListener() { actualPatternListener = new PatternLockViewListener() {
@Override @Override
@ -157,9 +135,7 @@ public class PatternSecurityFragment extends Fragment {
public void onComplete(List<PatternLockView.Dot> pattern) { public void onComplete(List<PatternLockView.Dot> pattern) {
if (patternEntered.equals(patternToString(pattern))){ if (patternEntered.equals(patternToString(pattern))){
savePattern(patternEntered); savePattern(patternEntered);
} showNewPatternUI();
else{
resetPattern();
} }
} }
@ -171,79 +147,9 @@ public class PatternSecurityFragment extends Fragment {
patternLockView.addPatternLockListener(actualPatternListener); patternLockView.addPatternLockListener(actualPatternListener);
} }
private void resetPattern(){
/*
* Show error
* */
tvPatternText.setText(getActivity().getResources().getString(R.string.Incorrect_pattern));
tvPatternText.setTextColor(Color.RED);
final Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
t.cancel();
showNewPatternUI();
}
});
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
}
public void savePattern(String pattern){ public void savePattern(String pattern){
String patternEncripted = PasswordManager.encriptPassword(pattern); String patternEncripted = PasswordManager.encriptPassword(pattern);
CrystalSecurityMonitor.getInstance(null).setPatternEncrypted(patternEncripted); CrystalSecurityMonitor.getInstance(null).setPatternEncrypted(patternEncripted);
/*CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity(), new OnResponse() { CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
@Override
public void onSuccess() {
Log.i("onSuccess","onSuccess");
Toast.makeText(getActivity(), "onSuccess", Toast.LENGTH_LONG).show();
}
@Override
public void onFailed() {
Log.i("onFailed","onFailed");
Toast.makeText(getActivity(), "onFailed", Toast.LENGTH_LONG).show();
}
});*/
/*
* Show success
* */
tvPatternText.setText(getActivity().getResources().getString(R.string.Pattern_set_correctly));
tvPatternText.setTextColor(Color.GREEN);
final Timer t_ = new Timer();
t_.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
t_.cancel();
showNewPatternUI();
}
});
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
} }
} }

View file

@ -1,35 +1,24 @@
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.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.text.Editable; import android.text.Editable;
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.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnFocusChange;
import butterknife.OnTextChanged; import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor; import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.PasswordManager; import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel; import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
@ -53,19 +42,6 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
@BindView(R.id.tvConfirmPinError) @BindView(R.id.tvConfirmPinError)
TextView tvConfirmPinError; TextView tvConfirmPinError;
@BindView(R.id.btnOK)
Button btnOK;
/*
* Validates the new typing for the patterns
* */
private boolean first = true;
/*
* Flag to check if validation of fields is correct
* */
private boolean valid = false;
GeneralSettingListViewModel generalSettingListViewModel; GeneralSettingListViewModel generalSettingListViewModel;
GeneralSetting passwordGeneralSetting; GeneralSetting passwordGeneralSetting;
PinSecurityValidator pinSecurityValidator; PinSecurityValidator pinSecurityValidator;
@ -88,117 +64,15 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
View v = inflater.inflate(R.layout.fragment_pin_security, container, false); View v = inflater.inflate(R.layout.fragment_pin_security, container, false);
ButterKnife.bind(this, v); ButterKnife.bind(this, v);
/*
* Initially not enabled til it passes validations
* */
btnOK.setEnabled(false);
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class); generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList(); LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
pinSecurityValidator = new PinSecurityValidator(this.getContext(), etNewPin, etConfirmPin); pinSecurityValidator = new PinSecurityValidator(this.getContext(), etNewPin, etConfirmPin);
pinSecurityValidator.setListener(this); pinSecurityValidator.setListener(this);
/*
* If PIN is configured set some text
* */
final CrystalSecurityMonitor crystalSecurityMonitor = CrystalSecurityMonitor.getInstance(getActivity());
switch(CrystalSecurityMonitor.getInstance(getActivity()).actualSecurity()) {
case GeneralSetting.SETTING_PASSWORD:
if(etNewPin!=null && etConfirmPin!=null){
etNewPin.setText("123456");
etConfirmPin.setText("123456");
}
break;
case GeneralSetting.SETTING_PATTERN:
break;
default:
if(etNewPin!=null && etConfirmPin!=null) {
etNewPin.setText("");
etConfirmPin.setText("");
}
}
/*
* Focus in no where
* */
tvNewPinError.requestFocus();
return v; return v;
} }
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
first = true;
/*
* If PIN is configured set some text
* */
final CrystalSecurityMonitor crystalSecurityMonitor = CrystalSecurityMonitor.getInstance(getActivity());
switch(CrystalSecurityMonitor.getInstance(getActivity()).actualSecurity()) {
case GeneralSetting.SETTING_PASSWORD:
if(etNewPin!=null && etConfirmPin!=null){
etNewPin.setText("123456");
etConfirmPin.setText("123456");
}
break;
case GeneralSetting.SETTING_PATTERN:
break;
default:
if(etNewPin!=null && etConfirmPin!=null) {
etNewPin.setText("");
etConfirmPin.setText("");
}
}
/*
* Focus in no where
* */
if(getActivity()!=null){
tvNewPinError.requestFocus();
}
}
@OnClick(R.id.btnOK)
void okClic(final View view) {
/*
* Only can continue if the fields are correctly validated
* */
if(valid){
/*
* Question if continue or not
* */
final QuestionDialog questionDialog = new QuestionDialog(getActivity());
questionDialog.setText(getActivity().getString(R.string.question_continue));
questionDialog.setOnNegative(new NegativeResponse() {
@Override
public void onNegative(@NotNull DialogMaterial dialogMaterial) {
}
});
questionDialog.setOnPositive(new PositiveResponse() {
@Override
public void onPositive() {
savePassword();
}
});
questionDialog.show();
}
}
@OnTextChanged(value = R.id.etNewPin, @OnTextChanged(value = R.id.etNewPin,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterNewPinChanged(Editable editable) { void afterNewPinChanged(Editable editable) {
@ -220,16 +94,6 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
} }
} }
@OnFocusChange({R.id.etNewPin,R.id.etConfirmPin})
public void focusChangePIN(View view, boolean hasFocus){
if(hasFocus){
if(first){
first = false;
clearFields();
}
}
}
@Override @Override
public void onValidationSucceeded(final ValidationField field) { public void onValidationSucceeded(final ValidationField field) {
final PinSecurityFragment fragment = this; final PinSecurityFragment fragment = this;
@ -244,64 +108,29 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
} }
if (pinSecurityValidator.isValid()){ if (pinSecurityValidator.isValid()){
//savePassword(); CharSequence text = "Your password has been sucessfully changed!";
int duration = Toast.LENGTH_SHORT;
if(!first){ Toast toast = Toast.makeText(getContext(), text, duration);
toast.show();
//Now is valid savePassword(etNewPin.getText().toString());
valid = true;
/*
* Enable ok button to continue
* */
btnOK.setEnabled(true);
}
clearFields();
} }
} }
}); });
} }
private void savePassword(){
savePassword(etNewPin.getText().toString());
CharSequence text = "Your password has been sucessfully changed!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(getContext(), text, duration);
toast.show();
etNewPin.setText("123456");
etConfirmPin.setText("123456");
first = true;
btnOK.setEnabled(false);
/*
* Focus in no where
* */
tvNewPinError.requestFocus();
}
public void savePassword(String password) { public void savePassword(String password) {
String passwordEncripted = PasswordManager.encriptPassword(password); String passwordEncripted = PasswordManager.encriptPassword(password);
CrystalSecurityMonitor.getInstance(getActivity()).setPasswordSecurity(passwordEncripted); CrystalSecurityMonitor.getInstance(null).setPasswordSecurity(passwordEncripted);
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
//CrystalSecurityMonitor.getInstance(getActivity()).callPasswordRequest(this.getActivity());
} }
@Override @Override
public void onValidationFailed(final ValidationField field) { public void onValidationFailed(final ValidationField field) {
//Still false
valid = false;
/*
* Disable til it passes validations
* */
btnOK.setEnabled(false);
this.getActivity().runOnUiThread(new Runnable() { this.getActivity().runOnUiThread(new Runnable() {
@Override @Override

View file

@ -9,7 +9,6 @@ import android.content.ContextWrapper;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.AsyncTask;
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;
@ -23,28 +22,18 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.widget.ArrayAdapter;
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.ProgressBar;
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.MultiFormatWriter; import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException; import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.journeyapps.barcodescanner.BarcodeEncoder;
import butterknife.OnClick; import butterknife.OnClick;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.requestmanagers.CalculateBitcoinUriRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.requestmanagers.NextBitcoinAccountAddressRequest;
import cy.agorise.crystalwallet.util.CircularImageView; import cy.agorise.crystalwallet.util.CircularImageView;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountListViewModel; import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountListViewModel;
import cy.agorise.crystalwallet.views.CryptoNetAccountAdapter; import cy.agorise.crystalwallet.views.CryptoNetAccountAdapter;
@ -86,8 +75,6 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
TextView tvAssetError; TextView tvAssetError;
@BindView(R.id.ivQrCode) @BindView(R.id.ivQrCode)
ImageView ivQrCode; ImageView ivQrCode;
@BindView(R.id.pbQrCode)
ProgressBar pbQrCode;
@BindView(R.id.tvCancel) @BindView(R.id.tvCancel)
TextView tvCancel; TextView tvCancel;
@ -108,10 +95,6 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
private FloatingActionButton fabReceive; private FloatingActionButton fabReceive;
private AsyncTask qrCodeTask;
private Double lastAmount = -1.0;
public static ReceiveTransactionFragment newInstance(long cryptoNetAccountId) { public static ReceiveTransactionFragment newInstance(long cryptoNetAccountId) {
ReceiveTransactionFragment f = new ReceiveTransactionFragment(); ReceiveTransactionFragment f = new ReceiveTransactionFragment();
@ -149,13 +132,36 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
db = CrystalDatabase.getAppDatabase(this.getContext()); db = CrystalDatabase.getAppDatabase(this.getContext());
this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId); this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId);
/*
* this is only for graphene accounts.
*
**/
this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
final LiveData<List<CryptoCoinBalance>> balancesList = db.cryptoCoinBalanceDao().getBalancesFromAccount(cryptoNetAccountId);
balancesList.observe(this, new Observer<List<CryptoCoinBalance>>() {
@Override
public void onChanged(@Nullable List<CryptoCoinBalance> cryptoCoinBalances) {
ArrayList<Long> assetIds = new ArrayList<Long>();
for (CryptoCoinBalance nextBalance : balancesList.getValue()) {
assetIds.add(nextBalance.getCryptoCurrencyId());
}
List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds);
CryptoCurrencyAdapter assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
spAsset.setAdapter(assetAdapter);
}
});
receiveTransactionValidator = new ReceiveTransactionValidator(this.getContext(), this.cryptoNetAccount, spAsset, etAmount);
receiveTransactionValidator.setListener(this);
CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class); CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList(); List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter toSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts); CryptoNetAccountAdapter toSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
spTo.setAdapter(toSpinnerAdapter); spTo.setAdapter(toSpinnerAdapter);
spTo.setSelection(0); spTo.setSelection(0);
setAccountUI();
} }
builder.setView(view); builder.setView(view);
@ -228,59 +234,8 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
} }
} }
public void setAccountUI(){
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
/*
* this is only for graphene accounts.
*
**/
this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
final LiveData<List<CryptoCoinBalance>> balancesList = db.cryptoCoinBalanceDao().getBalancesFromAccount(cryptoNetAccountId);
balancesList.observe(this, new Observer<List<CryptoCoinBalance>>() {
@Override
public void onChanged(@Nullable List<CryptoCoinBalance> cryptoCoinBalances) {
ArrayList<Long> assetIds = new ArrayList<Long>();
for (CryptoCoinBalance nextBalance : balancesList.getValue()) {
assetIds.add(nextBalance.getCryptoCurrencyId());
}
List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds);
/*
* Test
* */
//CryptoCurrency crypto1 = new CryptoCurrency();
//crypto1.setId(1);
//crypto1.setName("BITCOIN");
//crypto1.setPrecision(1);
//cryptoCurrencyList.add(crypto1);
CryptoCurrencyAdapter assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
spAsset.setAdapter(assetAdapter);
}
});
receiveTransactionValidator = new ReceiveTransactionValidator(this.getContext(), this.cryptoNetAccount, spAsset, etAmount);
receiveTransactionValidator.setListener(this);
} else {
CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
List<String> currencyList = new ArrayList<>();
currencyList.add(cryptoCoin.getLabel());
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this.getContext(),android.R.layout.simple_list_item_1,currencyList);
spAsset.setAdapter(arrayAdapter);
receiveTransactionValidator = new ReceiveTransactionValidator(this.getContext(), this.cryptoNetAccount, spAsset, etAmount);
receiveTransactionValidator.setListener(this);
}
}
@OnItemSelected(R.id.spTo) @OnItemSelected(R.id.spTo)
public void afterToSelected(Spinner spinner, int position) { public void afterToSelected(Spinner spinner, int position) {
this.cryptoNetAccount = (CryptoNetAccount)spinner.getSelectedItem();
setAccountUI();
this.receiveTransactionValidator.validate(); this.receiveTransactionValidator.validate();
} }
@ -292,10 +247,7 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
@OnItemSelected(R.id.spAsset) @OnItemSelected(R.id.spAsset)
public void afterAssetSelected(Spinner spinner, int position) { public void afterAssetSelected(Spinner spinner, int position) {
if (spinner.getSelectedItem() instanceof CryptoCurrency) { this.cryptoCurrency = (CryptoCurrency)spinner.getSelectedItem();
this.cryptoCurrency = (CryptoCurrency) spinner.getSelectedItem();
}
this.receiveTransactionValidator.validate(); this.receiveTransactionValidator.validate();
} }
@ -343,26 +295,15 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
} }
public void createQrCode(){ public void createQrCode(){
final Double amount; Double amount = 0.0;
try{ try{
amount = Double.valueOf(this.etAmount.getText().toString()); amount = Double.valueOf(this.etAmount.getText().toString());
} catch(NumberFormatException e){ } catch(NumberFormatException e){
lastAmount = -1.0;
Log.e("ReceiveFragment","Amount casting error."); Log.e("ReceiveFragment","Amount casting error.");
return;
} }
if (!amount.equals(lastAmount)) {
pbQrCode.setVisibility(View.VISIBLE);
lastAmount = amount;
CryptoNetAccount toAccountSelected = (CryptoNetAccount) spTo.getSelectedItem(); CryptoNetAccount toAccountSelected = (CryptoNetAccount) spTo.getSelectedItem();
if (this.qrCodeTask != null) {
this.qrCodeTask.cancel(true);
}
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
/* /*
* this is only for graphene accounts. * this is only for graphene accounts.
* *
@ -382,108 +323,43 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
this.invoice.setTo(grapheneAccountSelected.getName()); this.invoice.setTo(grapheneAccountSelected.getName());
this.invoice.setCurrency(this.cryptoCurrency.getName()); this.invoice.setCurrency(this.cryptoCurrency.getName());
//if (this.qrCodeTask != null) {
// this.qrCodeTask.cancel(true);
//}
this.qrCodeTask = new AsyncTask<Object, Void, Void>() {
@Override
protected Void doInBackground(Object... voids) {
try { try {
final Bitmap bitmap = textToImageEncode(Invoice.toQrCode(invoice)); Bitmap bitmap = textToImageEncode(Invoice.toQrCode(invoice));
if (!this.isCancelled()) {
ReceiveTransactionFragment.this.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
ivQrCode.setImageBitmap(bitmap); ivQrCode.setImageBitmap(bitmap);
pbQrCode.setVisibility(View.GONE);
}
});
}
} catch (WriterException e) { } catch (WriterException e) {
Log.e("ReceiveFragment", "Error creating QrCode"); Log.e("ReceiveFragment", "Error creating QrCode");
} }
return null;
}
};
this.qrCodeTask.execute(null, null, null);
} else {
final CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
final CalculateBitcoinUriRequest uriRequest = new CalculateBitcoinUriRequest(cryptoCoin, cryptoNetAccount, getContext(), amount);
uriRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if (uriRequest.getUri() != null) {
qrCodeTask = new AsyncTask<Object, Void, Void>() {
@Override
protected Void doInBackground(Object... voids) {
try {
final Bitmap bitmap = textToImageEncode(uriRequest.getUri());
if (!this.isCancelled()) {
ReceiveTransactionFragment.this.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//Double amountNow = -1.0;
//try{
// amountNow = Double.valueOf(etAmount.getText().toString());
//} catch(NumberFormatException e){
//}
//if (amountNow >= 0) {
if (amount.equals(lastAmount)) {
if (!isCancelled()) {
ivQrCode.setImageBitmap(bitmap);
pbQrCode.setVisibility(View.GONE);
}
}
//}
}
});
}
} catch (WriterException e) {
Log.e("ReceiveFragment", "Error creating QrCode");
}
return null;
}
};
qrCodeTask.execute(null, null, null);
} else {
Log.e("ReceiveFragment", "Error obtaining the uri");
}
}
});
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
CryptoNetInfoRequests.getInstance().addRequest(uriRequest);
}
});
thread.start();
}
}
} }
Bitmap textToImageEncode(String Value) throws WriterException { Bitmap textToImageEncode(String Value) throws WriterException {
Bitmap bitmap = null; //TODO: do this in another thread
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
BitMatrix bitMatrix;
try { try {
BitMatrix bitMatrix = multiFormatWriter.encode(Value, BarcodeFormat.QR_CODE, ivQrCode.getWidth(), ivQrCode.getHeight()); bitMatrix = new MultiFormatWriter().encode(
BarcodeEncoder barcodeEncoder = new BarcodeEncoder(); Value,
bitmap = barcodeEncoder.createBitmap(bitMatrix); BarcodeFormat.DATA_MATRIX.QR_CODE,
} catch (WriterException e) { ivQrCode.getWidth(), ivQrCode.getHeight(), null
e.printStackTrace(); );
} catch (IllegalArgumentException Illegalargumentexception) {
return null;
}
int bitMatrixWidth = bitMatrix.getWidth();
int bitMatrixHeight = bitMatrix.getHeight();
int[] pixels = new int[bitMatrixWidth * bitMatrixHeight];
for (int y = 0; y < bitMatrixHeight; y++) {
int offset = y * bitMatrixWidth;
for (int x = 0; x < bitMatrixWidth; x++) {
pixels[offset + x] = bitMatrix.get(x, y) ?
getResources().getColor(R.color.QRCodeBlackColor):getResources().getColor(R.color.QRCodeWhiteColor);
}
} }
Bitmap bitmap = Bitmap.createBitmap(bitMatrixWidth, bitMatrixHeight, Bitmap.Config.ARGB_4444);
bitmap.setPixels(pixels, 0, ivQrCode.getWidth(), 0, 0, bitMatrixWidth, bitMatrixHeight);
return bitmap; return bitmap;
} }
} }

View file

@ -83,15 +83,10 @@ public class SecuritySettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_security_settings, container, false); View v = inflater.inflate(R.layout.fragment_security_settings, container, false);
ButterKnife.bind(this, v); ButterKnife.bind(this, v);
/*
* For now this will not be implemented
* */
sPocketSecurity.setEnabled(false);
securityPagerAdapter = new SecurityPagerAdapter(getChildFragmentManager()); securityPagerAdapter = new SecurityPagerAdapter(getChildFragmentManager());
mPager.setAdapter(securityPagerAdapter); mPager.setAdapter(securityPagerAdapter);
switch(CrystalSecurityMonitor.getInstance(getActivity()).actualSecurity()) { switch(CrystalSecurityMonitor.getInstance(null).actualSecurity()) {
case GeneralSetting.SETTING_PASSWORD: case GeneralSetting.SETTING_PASSWORD:
mPager.setCurrentItem(1); mPager.setCurrentItem(1);
break; break;
@ -101,6 +96,7 @@ public class SecuritySettingsFragment extends Fragment {
default: default:
mPager.setCurrentItem(0); mPager.setCurrentItem(0);
} }
mPager.setSwipeLocked(true);
TabLayout tabLayout = v.findViewById(R.id.tabs); TabLayout tabLayout = v.findViewById(R.id.tabs);
@ -121,7 +117,7 @@ public class SecuritySettingsFragment extends Fragment {
public void setUserVisibleHint(boolean isVisibleToUser) { public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser); super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) { if (isVisibleToUser) {
//CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity()); CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
} }
} }
@ -138,9 +134,7 @@ public class SecuritySettingsFragment extends Fragment {
case 1: case 1:
return new PinSecurityFragment(); return new PinSecurityFragment();
case 2: case 2:
final PatternSecurityFragment patternSecurityFragment = new PatternSecurityFragment(); return new PatternSecurityFragment();
patternSecurityFragment.setChildViewPager(mPager);
return patternSecurityFragment;
} }
return null; //new OnConstructionFragment(); return null; //new OnConstructionFragment();

View file

@ -8,11 +8,11 @@ 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.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,21 +22,25 @@ 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.widget.ArrayAdapter; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
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;
import com.jaredrummler.materialspinner.MaterialSpinner;
import com.vincent.filepicker.ToastUtil;
import java.io.File; import java.io.File;
import java.math.RoundingMode; import java.math.RoundingMode;
@ -52,14 +56,6 @@ 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.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.dialogs.material.CrystalDialog;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.requestmanagers.BitcoinSendRequest;
import cy.agorise.crystalwallet.requestmanagers.BitcoinUriParseRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
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;
@ -85,12 +81,10 @@ import static butterknife.internal.Utils.listOf;
public class SendTransactionFragment extends DialogFragment implements UIValidatorListener, ZXingScannerView.ResultHandler { public class SendTransactionFragment extends DialogFragment implements UIValidatorListener, ZXingScannerView.ResultHandler {
private final String TAG = getClass().getName();
SendTransactionValidator sendTransactionValidator; SendTransactionValidator sendTransactionValidator;
@BindView(R.id.spFrom) @BindView(R.id.spFrom)
Spinner spFrom; MaterialSpinner spFrom;
@BindView(R.id.tvFromError) @BindView(R.id.tvFromError)
TextView tvFromError; TextView tvFromError;
@BindView(R.id.etTo) @BindView(R.id.etTo)
@ -99,14 +93,12 @@ 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)
TextView tvAssetError; TextView tvAssetError;
//@BindView(R.id.scrollMain) @BindView(R.id.scrollMain)
//ScrollView scrollMain; ScrollView scrollMain;
@BindView(R.id.etAmount) @BindView(R.id.etAmount)
EditText etAmount; EditText etAmount;
@BindView(R.id.tvAmountError) @BindView(R.id.tvAmountError)
@ -117,8 +109,11 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
TextView tvMemoError; TextView tvMemoError;
@BindView(R.id.btnSend) @BindView(R.id.btnSend)
FloatingActionButton btnSend; FloatingActionButton btnSend;
@BindView(R.id.btnCancel)
TextView btnCancel;
@BindView(R.id.ivPeople) @BindView(R.id.ivPeople)
ImageView ivPeople; ImageView ivPeople;
@BindView(R.id.ivCamera) @BindView(R.id.ivCamera)
ZXingScannerView mScannerView; ZXingScannerView mScannerView;
@ -127,8 +122,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
@BindView(R.id.gravatar) @BindView(R.id.gravatar)
CircularImageView userImg; CircularImageView userImg;
/* Flag to control when the camera is visible and when is hidden */ Button btnScanQrCode;
private boolean cameraVisible = false;
private long cryptoNetAccountId; private long cryptoNetAccountId;
private CryptoNetAccount cryptoNetAccount; private CryptoNetAccount cryptoNetAccount;
@ -137,8 +131,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
private FloatingActionButton fabSend; private FloatingActionButton fabSend;
private AlertDialog.Builder builder; private AlertDialog.Builder builder;
/* Dialog for loading */
private CrystalDialog crystalDialog;
public static SendTransactionFragment newInstance(long cryptoNetAccountId) { public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
SendTransactionFragment f = new SendTransactionFragment(); SendTransactionFragment f = new SendTransactionFragment();
@ -164,41 +157,68 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
//AlertDialog.Builder //AlertDialog.Builder
builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full); builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full);
//builder.setTitle("Send");
LayoutInflater inflater = getActivity().getLayoutInflater(); LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.send_transaction, null); View view = inflater.inflate(R.layout.send_transaction, null);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
/*
* Detet scroll changes
* */
scrollMain.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
View view = scrollMain.getChildAt(scrollMain.getChildCount() - 1);
int diff = (view.getBottom() - (scrollMain.getHeight() + scrollMain.getScrollY()));
float traslationY = btnSend.getTranslationY();
if(diff<=266 && diff>128){
//btnSend.setTranslationY(0);
//viewSend.setTranslationY(0);
btnSend.animate().y(880);
viewSend.animate().y(800);
}
else if(diff<=128 && diff>10){
//btnSend.setTranslationY(-130);
//viewSend.setTranslationY(-130);
btnSend.animate().y(880);
viewSend.animate().y(800);
}
else if(diff<=10 && diff>0){
//btnSend.setTranslationY(-170);
//viewSend.setTranslationY(-170);
btnSend.animate().y(680);
viewSend.animate().y(600);
}
else if(diff==0){
//btnSend.setTranslationY(-190);
//viewSend.setTranslationY(-190);
btnSend.animate().y(680);
viewSend.animate().y(600);
}
}
});
this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1); this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1);
/* Add style to the spinner android */ /*
* Add style to the spinner android
* */
spFrom.setBackground(getContext().getDrawable(R.drawable.square_color)); spFrom.setBackground(getContext().getDrawable(R.drawable.square_color));
if (this.cryptoNetAccountId != -1) { if (this.cryptoNetAccountId != -1) {
db = CrystalDatabase.getAppDatabase(this.getContext()); db = CrystalDatabase.getAppDatabase(this.getContext());
this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId); this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId);
CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
spFrom.setAdapter(fromSpinnerAdapter);
spFrom.setSelection(0);
setAccountUI();
}
loadUserImage();
/* Check for CAMERA permission */
if (Build.VERSION.SDK_INT >= 23 && !checkCameraPermission())
requestCameraPermission();
return builder.setView(view).create();
}
public void setAccountUI(){
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
/* /*
* this is only for graphene accounts. * this is only for graphene accounts.
* *
@ -216,100 +236,68 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
} }
List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds); List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds);
/*
* Test
* */
//CryptoCurrency crypto1 = new CryptoCurrency();
//crypto1.setId(1);
//crypto1.setName("BITCOIN");
//crypto1.setPrecision(1);
//cryptoCurrencyList.add(crypto1);
assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList); assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
spAsset.setAdapter(assetAdapter); spAsset.setAdapter(assetAdapter);
} }
}); });
// TODO SendTransactionValidator to accept spFrom // TODO SendTransactionValidator to accept spFrom
sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo); sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
sendTransactionValidator.setListener(this); sendTransactionValidator.setListener(this);
} else { CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0); List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
List<String> currencyList = new ArrayList<>();
currencyList.add(cryptoCoin.getLabel());
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this.getContext(),android.R.layout.simple_list_item_1,currencyList);
spAsset.setAdapter(arrayAdapter);
// TODO SendTransactionValidator to accept spFrom
sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
sendTransactionValidator.setListener(this);
}
}
private boolean checkCameraPermission() {
int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA);
return result == PackageManager.PERMISSION_GRANTED;
}
private void requestCameraPermission() {
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 */
btnCloseCamera.setVisibility(View.INVISIBLE);
} else {
requestPermissions(new String[] {android.Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}
spFrom.setAdapter(fromSpinnerAdapter);
//spFrom.setSelection(0);
/*
* Custom material spinner implementation
* */
spFrom.setItems(cryptoNetAccounts);
//spFrom.setSelectedIndex(0);
spFrom.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<CryptoNetAccount>() {
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onItemSelected(MaterialSpinner view, int position, long id, CryptoNetAccount item) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults); sendTransactionValidator.validate();
}
});
spFrom.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {
switch (requestCode) { @Override public void onNothingSelected(MaterialSpinner spinner) {
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();
} }
}); });
} else { // etFrom.setText(this.grapheneAccount.getName());
Log.e("value", "Permission Denied, You cannot use the camera."); }
getActivity().runOnUiThread(new Runnable(){ loadUserImage();
public void run() { try {
Toast.makeText(getActivity(), getActivity().getString(R.string.permission_denied_camera), Toast.LENGTH_LONG).show(); verifyCameraPermissions(getActivity());
} beginScanQrCode();
}); }catch(Exception e){
} e.printStackTrace();
break;
} }
return builder.setView(view).create();
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mScannerView.setResultHandler(this); /*builder.setNeutralButton("Scan QR Code", new DialogInterface.OnClickListener() {
loadUserImage();
}
@Override @Override
public void onPause() { public void onClick(DialogInterface dialogInterface, int i) {
super.onPause(); beginScanQrCode();
mScannerView.stopCamera(); }
});*/
// Force dialog fragment to use the full width of the screen
Window dialogWindow = getDialog().getWindow();
assert dialogWindow != null;
dialogWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
loadUserImage();
} }
@Override @Override
@ -340,12 +328,10 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
} }
} }
@OnItemSelected(R.id.spFrom) /*@OnItemSelected(R.id.spFrom)
public void afterFromSelected(Spinner spinner, int position) { public void afterFromSelected(Spinner spinner, int position) {
this.cryptoNetAccount = (CryptoNetAccount)spinner.getSelectedItem();
setAccountUI();
this.sendTransactionValidator.validate(); this.sendTransactionValidator.validate();
} }*/
@OnTextChanged(value = R.id.etTo, @OnTextChanged(value = R.id.etTo,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
@ -365,46 +351,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
} }
@OnClick(R.id.fabCloseCamera)
public void onClickCloseCamera(){
if(cameraVisible)
hideCamera();
else
showCamera();
}
/**
* Shows the camera and hide the black background
* */
private void showCamera(){
/* Change visibilities of views */
mScannerView.setVisibility(View.VISIBLE);
/* Change icon */
btnCloseCamera.setImageDrawable(getResources().getDrawable(R.drawable.ic_close));
/* Reset variable */
cameraVisible = true;
/* Star the camera again */
beginScanQrCode();
}
/**
* Hides the camera and show the black background
* */
private void hideCamera(){
/* Change visibilities of views */
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) {
@ -462,113 +408,51 @@ 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;
final CryptoNetInfoRequest sendRequest;
if (this.sendTransactionValidator.isValid()) { if (this.sendTransactionValidator.isValid()) {
//CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex()); CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex());
CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getSelectedItem();
if (fromAccountSelected.getCryptoNet() == CryptoNet.BITSHARES) { /*
/* This is only for graphene accounts. */ * this is only for graphene accounts.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected); GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId())); grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId()));
//TODO convert the amount to long type using the precision of the currency //TODO convert the amount to long type using the precision of the currency
Double amountFromEditText = Double.parseDouble(this.etAmount.getText().toString()); Double amountFromEditText = Double.parseDouble(this.etAmount.getText().toString());
Long amount = (long) Math.floor(amountFromEditText * Math.round(Math.pow(10, ((CryptoCurrency) spAsset.getSelectedItem()).getPrecision()))); Long amount = (long)Math.floor(amountFromEditText*Math.round(Math.pow(10,((CryptoCurrency)spAsset.getSelectedItem()).getPrecision())));
/*final ValidateBitsharesSendRequest*/ final ValidateBitsharesSendRequest sendRequest = new ValidateBitsharesSendRequest(
sendRequest = new ValidateBitsharesSendRequest(
this.getContext(), this.getContext(),
grapheneAccountSelected, grapheneAccountSelected,
this.etTo.getText().toString(), this.etTo.getText().toString(),
amount, amount,
((CryptoCurrency) spAsset.getSelectedItem()).getName(), ((CryptoCurrency)spAsset.getSelectedItem()).getName(),
etMemo.getText().toString() etMemo.getText().toString()
); );
sendRequest.setListener(new CryptoNetInfoRequestListener() { sendRequest.setListener(new CryptoNetInfoRequestListener() {
@Override @Override
public void onCarryOut() { public void onCarryOut() {
if (((ValidateBitsharesSendRequest)sendRequest).getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)) { if (sendRequest.getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)){
try { try {
crystalDialog.dismiss(); this.finalize();
thisFragment.dismiss();
//thisFragment.finalize();
} catch (Throwable throwable) { } catch (Throwable throwable) {
throwable.printStackTrace(); throwable.printStackTrace();
} }
} else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
} }
} }
}); });
} else {
CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
//TODO convert the amount to long type using the precision of the currency
Double amountFromEditText = Double.parseDouble(this.etAmount.getText().toString());
Long amount = (long) Math.floor(amountFromEditText * (Math.pow(10, cryptoCoin.getPrecision())));
sendRequest = new BitcoinSendRequest(
this.getContext(),
this.cryptoNetAccount,
this.etTo.getText().toString(),
amount,
cryptoCoin,
etMemo.getText().toString()
);
sendRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if (((BitcoinSendRequest)sendRequest).getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)) {
try {
crystalDialog.dismiss();
thisFragment.dismiss();
//thisFragment.finalize();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
} else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
}
}
});
}
/* If exists mode security show it and validate events in case of success or fail */
CrystalSecurityMonitor.getInstance(this.getActivity()).callPasswordRequest(this.getActivity(), new OnResponse() {
@Override
public void onSuccess() {
/* Show loading dialog */
crystalDialog = new CrystalDialog((Activity) getContext());
crystalDialog.setText("Sending");
crystalDialog.progress();
crystalDialog.show();
CryptoNetInfoRequests.getInstance().addRequest(sendRequest); CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
} }
@Override
public void onFailed() {
}
});
//CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
}
} }
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);
@ -578,6 +462,24 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
// Camera Permissions // Camera Permissions
private static final int REQUEST_CAMERA_PERMISSION = 1; private static final int REQUEST_CAMERA_PERMISSION = 1;
private static String[] PERMISSIONS_CAMERA = {
Manifest.permission.CAMERA
};
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) {
@ -632,14 +534,13 @@ 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());
Log.d(TAG, "QR Code read: " + invoice.toJsonString());
etTo.setText(invoice.getTo()); etTo.setText(invoice.getTo());
for (int i = 0; i < assetAdapter.getCount(); i++) { for (int i = 0; i < assetAdapter.getCount(); i++) {
if (assetAdapter.getItem(i).getName().equals(invoice.getCurrency().toUpperCase())) { if (assetAdapter.getItem(i).getName().equals(invoice.getCurrency())) {
spAsset.setSelection(i); spAsset.setSelection(i);
break; break;
} }
@ -656,34 +557,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ENGLISH)); df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ENGLISH));
etAmount.setText(df.format(amount)); etAmount.setText(df.format(amount));
Log.i("SendFragment", result.getText()); Log.i("SendFragment", result.getText());
return;
}catch(Exception e){ }catch(Exception e){
e.printStackTrace(); e.printStackTrace();
} }
//Is not a bitshares QR
//CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
final BitcoinUriParseRequest bitcoinUriParseRequest = new BitcoinUriParseRequest(result.getText(), CryptoCoin.BITCOIN);
bitcoinUriParseRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if (bitcoinUriParseRequest.getAddress() != null) {
if (!bitcoinUriParseRequest.getAddress().equals("")) {
etTo.setText(bitcoinUriParseRequest.getAddress());
}
if (bitcoinUriParseRequest.getAmount() > 0) {
etAmount.setText(bitcoinUriParseRequest.getAmount().toString());
}
if (!bitcoinUriParseRequest.getMemo().equals("")) {
etMemo.setText(bitcoinUriParseRequest.getMemo());
}
} else {
Toast.makeText(getContext(), "Not a valid QR info", Toast.LENGTH_LONG);
}
}
});
CryptoNetInfoRequests.getInstance().addRequest(bitcoinUriParseRequest);
} }
} }

View file

@ -5,20 +5,18 @@ import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList; import android.arch.paging.PagedList;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.Editable; import android.text.Editable;
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.widget.AdapterView; import android.widget.AdapterView;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -27,30 +25,27 @@ import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnTextChanged; import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended; import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended;
import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel; import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel;
import cy.agorise.crystalwallet.views.TransactionListAdapter; import cy.agorise.crystalwallet.views.TransactionListView;
import cy.agorise.crystalwallet.views.TransactionOrderSpinnerAdapter; import cy.agorise.crystalwallet.views.TransactionOrderSpinnerAdapter;
public class TransactionsFragment extends Fragment { public class TransactionsFragment extends Fragment {
@BindView(R.id.vTransactionListView)
TransactionListView transactionListView;
@BindView(R.id.spTransactionsOrder) @BindView(R.id.spTransactionsOrder)
Spinner spTransactionsOrder; Spinner spTransactionsOrder;
@BindView(R.id.etTransactionSearch) @BindView(R.id.etTransactionSearch)
EditText etTransactionSearch; EditText etTransactionSearch;
@BindView(R.id.tvNoTransactions) RecyclerView balanceRecyclerView;
TextView tvNoTransactions;
@BindView(R.id.rvTransactions)
RecyclerView rvTransactions;
FloatingActionButton fabSend; FloatingActionButton fabSend;
FloatingActionButton fabReceive; FloatingActionButton fabReceive;
TransactionListAdapter transactionListAdapter;
TransactionListViewModel transactionListViewModel; TransactionListViewModel transactionListViewModel;
LiveData<PagedList<CryptoCoinTransactionExtended>> transactionsLiveData; LiveData<PagedList<CryptoCoinTransactionExtended>> transactionsLiveData;
@ -71,22 +66,20 @@ public class TransactionsFragment extends Fragment {
} }
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_transactions, container, false); View view = inflater.inflate(R.layout.fragment_transactions, container, false);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
rvTransactions.setLayoutManager(new LinearLayoutManager(getContext())); // Gets the Balance RecyclerView
transactionListAdapter = new TransactionListAdapter(this); balanceRecyclerView = view.findViewById(R.id.transactionListView);
rvTransactions.setAdapter(transactionListAdapter);
fabSend = getActivity().findViewById(R.id.fabSend); fabSend = getActivity().findViewById(R.id.fabSend);
fabReceive = getActivity().findViewById(R.id.fabReceive); fabReceive = getActivity().findViewById(R.id.fabReceive);
// TODO move this listener to the activity, to make this fragment reusable // TODO move this listener to the activity, to make this fragment reusable
// Adds listener to the RecyclerView to show and hide buttons at the bottom of the screen // Adds listener to the RecyclerView to show and hide buttons at the bottom of the screen
rvTransactions.addOnScrollListener(new RecyclerView.OnScrollListener() { balanceRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override @Override
public void onScrolled(RecyclerView recyclerView, int dx,int dy){ public void onScrolled(RecyclerView recyclerView, int dx,int dy){
super.onScrolled(recyclerView, dx, dy); super.onScrolled(recyclerView, dx, dy);
@ -126,17 +119,12 @@ public class TransactionsFragment extends Fragment {
transactionListViewModel.initTransactionList(orderSelected.getField(),etTransactionSearch.getText().toString()); transactionListViewModel.initTransactionList(orderSelected.getField(),etTransactionSearch.getText().toString());
transactionsLiveData = transactionListViewModel.getTransactionList(); transactionsLiveData = transactionListViewModel.getTransactionList();
final Fragment fragment = this;
transactionsLiveData.observe(this, new Observer<PagedList<CryptoCoinTransactionExtended>>() { transactionsLiveData.observe(this, new Observer<PagedList<CryptoCoinTransactionExtended>>() {
@Override @Override
public void onChanged(@Nullable PagedList<CryptoCoinTransactionExtended> transactions) { public void onChanged(@Nullable PagedList<CryptoCoinTransactionExtended> cryptoCoinTransactions) {
transactionListAdapter.submitList(transactions); Log.i("Transactions","Transactions have change! Count:"+cryptoCoinTransactions.size());
transactionListView.setData(cryptoCoinTransactions, fragment);
if(transactions != null && transactions.size() > 0){
tvNoTransactions.setVisibility(View.INVISIBLE);
}
else{
tvNoTransactions.setVisibility(View.VISIBLE);
}
} }
}); });
} }
@ -148,7 +136,7 @@ public class TransactionsFragment extends Fragment {
} }
public void initTransactionsOrderSpinner(){ public void initTransactionsOrderSpinner(){
List<TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem> spinnerValues = new ArrayList<>(); List<TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem> spinnerValues = new ArrayList<TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem>();
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("date","Date",0,false)); spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("date","Date",0,false));
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("amount","Amount",0,false)); spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("amount","Amount",0,false));
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("is_input","In/Out",0,false)); spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("is_input","In/Out",0,false));

View file

@ -1,6 +0,0 @@
package cy.agorise.crystalwallet.interfaces;
public interface OnResponse {
void onSuccess();
void onFailed();
}

View file

@ -2,13 +2,11 @@ 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;
import org.bitcoinj.core.ECKey; import org.bitcoinj.core.ECKey;
import java.math.BigInteger;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -22,14 +20,12 @@ 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;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest; import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener; import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
import cy.agorise.crystalwallet.requestmanagers.GetBitsharesAccountNameCacheRequest; import cy.agorise.crystalwallet.requestmanagers.GetBitsharesAccountNameCacheRequest;
import cy.agorise.crystalwallet.requestmanagers.ImportBitsharesAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesLTMUpgradeRequest; import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesLTMUpgradeRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest; import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest; import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest;
@ -59,7 +55,6 @@ import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.models.AccountProperties; import cy.agorise.graphenej.models.AccountProperties;
import cy.agorise.graphenej.models.BlockHeader; import cy.agorise.graphenej.models.BlockHeader;
import cy.agorise.graphenej.models.HistoricalTransfer; import cy.agorise.graphenej.models.HistoricalTransfer;
import cy.agorise.graphenej.objects.Memo;
import cy.agorise.graphenej.operations.TransferOperationBuilder; import cy.agorise.graphenej.operations.TransferOperationBuilder;
/** /**
@ -69,6 +64,8 @@ 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";
@ -92,11 +89,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(fetch)[0]; long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(fetch)[0];
fetch.setId(idAccount); fetch.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(fetch)); db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(fetch));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(fetch.getId(),fetch.getAccountId(),context); subscribeBitsharesAccount(fetch.getId(),fetch.getAccountId(),context);
request.success(fetch); request.success(fetch);
} }
@ -137,11 +129,6 @@ 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));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context); subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
} }
@ -158,14 +145,8 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
GrapheneAccount fetch = (GrapheneAccount) answer; GrapheneAccount fetch = (GrapheneAccount) answer;
grapheneAccount.setName(fetch.getName()); grapheneAccount.setName(fetch.getName());
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0]; db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
grapheneAccount.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount)); db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context); subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
} }
@ -176,14 +157,8 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
}); });
}else { }else {
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0]; db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
grapheneAccount.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount)); db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context); subscribeBitsharesAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context);
} }
} }
@ -204,11 +179,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
info.setAccountId(fetch.getAccountId()); info.setAccountId(fetch.getAccountId());
grapheneAccount.setAccountId(fetch.getAccountId()); grapheneAccount.setAccountId(fetch.getAccountId());
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info); db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context); subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
} }
@ -225,11 +195,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
info.setName(fetch.getName()); info.setName(fetch.getName());
grapheneAccount.setName(fetch.getName()); grapheneAccount.setName(fetch.getName());
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info); db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context); subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
} }
@ -239,11 +204,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
} }
}); });
}else{ }else{
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context); subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
} }
} }
@ -252,7 +212,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
private void subscribeBitsharesAccount(long accountId, String accountBitsharesID, Context context){ private void subscribeBitsharesAccount(long accountId, String accountBitsharesID, Context context){
GrapheneApiGenerator.subscribeBitsharesAccount(accountId,accountBitsharesID,context); GrapheneApiGenerator.subscribeBitsharesAccount(accountId,accountBitsharesID,context);
BitsharesAccountManager.refreshAccountTransactions(accountId,context); BitsharesAccountManager.refreshAccountTransactions(accountId,context);
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesID,CryptoNet.BITSHARES,context); GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesID,context);
} }
/** /**
@ -261,102 +221,26 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
*/ */
@Override @Override
public void onNewRequest(CryptoNetInfoRequest request) { public void onNewRequest(CryptoNetInfoRequest request) {
if(request.getCoin().equals(CryptoCoin.BITSHARES)) { if (request instanceof ValidateImportBitsharesAccountRequest){
if (request instanceof ImportBitsharesAccountRequest) {
this.importAccount((ImportBitsharesAccountRequest) request);
} else 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());
} }
} }
}
private void importAccount(final ImportBitsharesAccountRequest importRequest){
final CrystalDatabase db = CrystalDatabase.getAppDatabase(importRequest.getContext());
final AccountSeedDao accountSeedDao = db.accountSeedDao();
ApiRequest getAccountNamesBK = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
if(answer != null && importRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.NOT_STARTED)) {
UserAccount userAccount = (UserAccount) answer;
importRequest.setSeedType(SeedType.BRAINKEY);
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
AccountSeed seed = new AccountSeed();
seed.setName(userAccount.getName());
seed.setType(importRequest.getSeedType());
seed.setMasterSeed(importRequest.getMnemonic());
long idSeed = accountSeedDao.insertAccountSeed(seed);
if (idSeed >= 0) {
GrapheneAccount account = new GrapheneAccount();
account.setCryptoNet(CryptoNet.BITSHARES);
account.setAccountIndex(0);
account.setSeedId(idSeed);
account.setAccountId(userAccount.getObjectId());
importAccountFromSeed(account, importRequest.getContext());
}
}
}
@Override
public void fail(int idPetition) {
BIP39 bip39 = new BIP39(-1, importRequest.getMnemonic());
ApiRequest getAccountNamesBP39 = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
if(answer != null && importRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.NOT_STARTED)) {
UserAccount userAccount = (UserAccount) answer;
importRequest.setSeedType(SeedType.BIP39);
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
AccountSeed seed = new AccountSeed();
seed.setName(userAccount.getName());
seed.setType(importRequest.getSeedType());
seed.setMasterSeed(importRequest.getMnemonic());
long idSeed = accountSeedDao.insertAccountSeed(seed);
if (idSeed >= 0) {
GrapheneAccount account = new GrapheneAccount();
account.setCryptoNet(CryptoNet.BITSHARES);
account.setAccountIndex(0);
account.setSeedId(idSeed);
account.setAccountId(userAccount.getObjectId());
importAccountFromSeed(account, importRequest.getContext());
}
}
}
@Override
public void fail(int idPetition) {
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.BAD_SEED);
}
});
GrapheneApiGenerator.getAccountByOwnerOrActiveAddress(new Address(ECKey.fromPublicOnly(bip39.getBitsharesActiveKey(0).getPubKey())),CryptoNet.BITSHARES,getAccountNamesBP39);
}
});
BrainKey bk = new BrainKey(importRequest.getMnemonic(), 0);
GrapheneApiGenerator.getAccountByOwnerOrActiveAddress(bk.getPublicAddress("BTS"),CryptoNet.BITSHARES,getAccountNamesBK);
}
/** /**
* Process the import account request * Process the import account request
@ -423,7 +307,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.NO_ACCOUNT_DATA); importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.NO_ACCOUNT_DATA);
} }
}); });
GrapheneApiGenerator.getAccountById((String)answer,CryptoNet.BITSHARES,getAccountInfo); GrapheneApiGenerator.getAccountById((String)answer,getAccountInfo);
} }
@Override @Override
@ -433,7 +317,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
} }
}); });
GrapheneApiGenerator.getAccountIdByName(importRequest.getAccountName(),CryptoNet.BITSHARES,checkAccountName); GrapheneApiGenerator.getAccountIdByName(importRequest.getAccountName(),checkAccountName);
} }
private void validateCreateAccount(final ValidateCreateBitsharesAccountRequest createRequest){ private void validateCreateAccount(final ValidateCreateBitsharesAccountRequest createRequest){
@ -488,7 +372,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
validateRequest.setAccountExists(false); validateRequest.setAccountExists(false);
} }
}); });
GrapheneApiGenerator.getAccountIdByName(validateRequest.getAccountName(),CryptoNet.BITSHARES,checkAccountName); GrapheneApiGenerator.getAccountIdByName(validateRequest.getAccountName(),checkAccountName);
} }
/** /**
@ -587,16 +471,9 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
.setTransferAmount(new AssetAmount(UnsignedLong.valueOf(sendRequest.getAmount()), new Asset(idAsset))) .setTransferAmount(new AssetAmount(UnsignedLong.valueOf(sendRequest.getAmount()), new Asset(idAsset)))
.setFee(new AssetAmount(UnsignedLong.valueOf(0), feeAsset)); .setFee(new AssetAmount(UnsignedLong.valueOf(0), feeAsset));
if (sendRequest.getMemo() != null) { if (sendRequest.getMemo() != null) {
try { //builder.setMemo(new Memo(fromUserAccount,toUserAccount,0,sendRequest.getMemo().getBytes()));
//TODO change authority for memo //TODO memo
Address fromAddress = new Address(fromUserAccount.getActive().getKeyAuthList().get(0).getKey(), "BTS"); System.out.println("transaction has memo");
Address toAddress = new Address(toUserAccount.getActive().getKeyAuthList().get(0).getKey(), "BTS");
builder.setMemo(new Memo(fromAddress,toAddress,BigInteger.ZERO,sendRequest.getMemo().getBytes()));
//TODO add random nonce
}catch ( Exception e){
e.printStackTrace();
//TODO error
}
} }
ArrayList<BaseOperation> operationList = new ArrayList<>(); ArrayList<BaseOperation> operationList = new ArrayList<>();
operationList.add(builder.build()); operationList.add(builder.build());
@ -693,7 +570,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
AccountIdOrNameListener listener = new AccountIdOrNameListener(request); AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
ApiRequest accountRequest = new ApiRequest(0, listener); ApiRequest accountRequest = new ApiRequest(0, listener);
GrapheneApiGenerator.getAccountById(grapheneId,CryptoNet.BITSHARES,accountRequest); GrapheneApiGenerator.getAccountById(grapheneId,accountRequest);
} }
/** /**
@ -705,7 +582,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
AccountIdOrNameListener listener = new AccountIdOrNameListener(request); AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
ApiRequest accountRequest = new ApiRequest(0, listener); ApiRequest accountRequest = new ApiRequest(0, listener);
GrapheneApiGenerator.getAccountByName(grapheneName,CryptoNet.BITSHARES,accountRequest); GrapheneApiGenerator.getAccountByName(grapheneName,accountRequest);
} }
@ -716,7 +593,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
ApiRequest assetRequest = new ApiRequest(0, nameListener); ApiRequest assetRequest = new ApiRequest(0, nameListener);
ArrayList<String> assetNames = new ArrayList<>(); ArrayList<String> assetNames = new ArrayList<>();
assetNames.add(assetName); assetNames.add(assetName);
GrapheneApiGenerator.getAssetByName(assetNames, CryptoNet.BITSHARES,assetRequest); GrapheneApiGenerator.getAssetByName(assetNames, assetRequest);
} }
@ -739,7 +616,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
int stop = start + limit; int stop = start + limit;
ApiRequest transactionRequest = new ApiRequest(0, new TransactionRequestListener(start, stop, limit, grapheneAccount, db)); ApiRequest transactionRequest = new ApiRequest(0, new TransactionRequestListener(start, stop, limit, grapheneAccount, db));
GrapheneApiGenerator.getAccountTransaction(grapheneAccount.getAccountId(), start, stop, limit, CryptoNet.BITSHARES,transactionRequest); GrapheneApiGenerator.getAccountTransaction(grapheneAccount.getAccountId(), start, stop, limit, transactionRequest);
} }
} }
@ -829,7 +706,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
}); });
ArrayList<String> assets = new ArrayList<>(); ArrayList<String> assets = new ArrayList<>();
assets.add(transfer.getOperation().getAssetAmount().getAsset().getObjectId()); assets.add(transfer.getOperation().getAssetAmount().getAsset().getObjectId());
GrapheneApiGenerator.getAssetById(assets,CryptoNet.BITSHARES,assetRequest); GrapheneApiGenerator.getAssetById(assets,assetRequest);
}else{ }else{
saveTransaction(transaction,info,transfer); saveTransaction(transaction,info,transfer);
@ -842,7 +719,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
int newStart= start + limit; int newStart= start + limit;
int newStop= stop + limit; int newStop= stop + limit;
ApiRequest transactionRequest = new ApiRequest(newStart/limit, new TransactionRequestListener(newStart,newStop,limit,account,db)); ApiRequest transactionRequest = new ApiRequest(newStart/limit, new TransactionRequestListener(newStart,newStop,limit,account,db));
GrapheneApiGenerator.getAccountTransaction(account.getAccountId(),newStart,newStop,limit,CryptoNet.BITSHARES,transactionRequest); GrapheneApiGenerator.getAccountTransaction(account.getAccountId(),newStart,newStop,limit,transactionRequest);
} }
} }
@ -858,7 +735,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
transaction.setInput(!transfer.getOperation().getFrom().getObjectId().equals(account.getAccountId())); transaction.setInput(!transfer.getOperation().getFrom().getObjectId().equals(account.getAccountId()));
transaction.setTo(transfer.getOperation().getTo().getObjectId()); transaction.setTo(transfer.getOperation().getTo().getObjectId());
GrapheneApiGenerator.getBlockHeaderTime(transfer.getBlockNum(),CryptoNet.BITSHARES, new ApiRequest(0, new GetTransactionDate(transaction, db.transactionDao()))); GrapheneApiGenerator.getBlockHeaderTime(transfer.getBlockNum(), new ApiRequest(0, new GetTransactionDate(transaction, db.transactionDao())));
} }
} }

View file

@ -327,6 +327,7 @@ public class FileBackupManager implements FileServiceRequestsListener {
public static byte[] decompress(byte[] inputBytes, int which) { public static byte[] decompress(byte[] inputBytes, int which) {
InputStream in = null; InputStream in = null;
try { try {
System.out.println("Bytes: "+Util.bytesToHex(inputBytes));
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes); ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048); ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048);
if(which == Util.XZ) { if(which == Util.XZ) {

View file

@ -3,74 +3,32 @@ package cy.agorise.crystalwallet.manager;
import android.content.Context; import android.content.Context;
import org.bitcoinj.core.Address; import org.bitcoinj.core.Address;
import org.bitcoinj.core.AddressFormatException;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionOutPoint; import org.bitcoinj.core.TransactionOutPoint;
import org.bitcoinj.crypto.ChildNumber; import org.bitcoinj.crypto.ChildNumber;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.crypto.HDKeyDerivation; 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.models.Txi; import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
import cy.agorise.crystalwallet.dao.BitcoinAddressDao;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.BitcoinAddress;
import cy.agorise.crystalwallet.models.BitcoinTransaction;
import cy.agorise.crystalwallet.models.BitcoinTransactionGTxIO;
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount; import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.requestmanagers.BitcoinSendRequest; import cy.agorise.crystalwallet.models.GTxIO;
import cy.agorise.crystalwallet.requestmanagers.BitcoinUriParseRequest; import cy.agorise.crystalwallet.models.GeneralCoinAddress;
import cy.agorise.crystalwallet.requestmanagers.CalculateBitcoinUriRequest; import cy.agorise.crystalwallet.models.GeneralTransaction;
import cy.agorise.crystalwallet.requestmanagers.CreateBitcoinAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest; import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener; import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
import cy.agorise.crystalwallet.requestmanagers.NextBitcoinAccountAddressRequest; import cy.agorise.crystalwallet.requestmanagers.GeneralAccountSendRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitcoinAddressRequest;
import cy.agorise.graphenej.Util; 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) {
@ -82,347 +40,55 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
} }
@Override @Override
public void loadAccountFromDB(final CryptoNetAccount account, Context context) { public void loadAccountFromDB(CryptoNetAccount account, Context context) {
final CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
AccountSeed seed = db.accountSeedDao().findById(account.getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(account.getAccountIndex(), true));
final DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
final DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
CryptoCoinBalance balance = new CryptoCoinBalance();
long amount = 0;
List<CryptoCoinTransaction> trransactions = db.transactionDao().getByIdAccount(account.getId());
for(CryptoCoinTransaction transaction : trransactions){
if(transaction.isConfirmed()){
if(transaction.getInput()){
amount += transaction.getAmount();
}else{
amount -= transaction.getAmount();
}
} }
}
balance.setBalance(amount);
balance.setCryptoCurrencyId(db.cryptoCurrencyDao().getByName(cryptoCoin.getLabel(),cryptoCoin.name()).getId());
balance.setAccountId(account.getId());
db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance);
long indexExternal = db.bitcoinAddressDao().getLastExternalAddress(account.getId());
if(indexExternal > 0){
for(int i = 0; i < indexExternal;i++){
BitcoinAddress address = db.bitcoinAddressDao().getExternalByIndex(i);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,address.getAddress(),true,null);
}
}else {
ECKey externalAddrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) 0, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(false);
address.setAccountId(account.getId());
address.setIndex(0);
String addressString = externalAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
new CheckAddressForTransaction(db.bitcoinAddressDao(),account.getId(),externalKey,false,0));
}
long indexChange = db.bitcoinAddressDao().getLastChangeAddress(account.getId());
if(indexChange > 0){
for(int i = 0; i < indexChange;i++){
BitcoinAddress address = db.bitcoinAddressDao().getChangeByIndex(i);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,address.getAddress(),true,null);
}
}else {
ECKey changeAddrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) 0, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(true);
address.setAccountId(account.getId());
address.setIndex(0);
String addressString =changeAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
new CheckAddressForTransaction(db.bitcoinAddressDao(),account.getId(),externalKey,true,0));
}
}
@Override @Override
public void onNewRequest(CryptoNetInfoRequest request) { public void onNewRequest(CryptoNetInfoRequest request) {
//if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
if(request.getCoin().equals(this.cryptoCoin)){
if(request instanceof BitcoinSendRequest) {
this.send((BitcoinSendRequest) request);
}else if(request instanceof CreateBitcoinAccountRequest){
this.createGeneralAccount((CreateBitcoinAccountRequest) request);
}else if(request instanceof NextBitcoinAccountAddressRequest){
this.getNextAddress((NextBitcoinAccountAddressRequest) request);
}else if(request instanceof ValidateBitcoinAddressRequest){
this.validateAddress((ValidateBitcoinAddressRequest) request);
}else if(request instanceof CalculateBitcoinUriRequest){
this.calculateUri((CalculateBitcoinUriRequest) request);
}else if(request instanceof BitcoinUriParseRequest){
this.parseUri((BitcoinUriParseRequest) 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){
try {
System.out.println("GeneralAccountManager processingTxi " + txi.txid);
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
List<BitcoinTransaction> btTransactions = db.bitcoinTransactionDao().getTransactionsByTxid(txi.txid);
if (!btTransactions.isEmpty()) {
System.out.println("GeneralAccountManager Transaction not null " + txi.txid);
for (BitcoinTransaction btTransaction : btTransactions) {
btTransaction.setConfirmations(txi.confirmations);
CryptoCoinTransaction ccTransaction = db.transactionDao().getById(btTransaction.getCryptoCoinTransactionId());
if (!ccTransaction.isConfirmed() && btTransaction.getConfirmations() >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
ccTransaction.setConfirmed(true);
db.transactionDao().insertTransaction(ccTransaction);
updateBalance(ccTransaction, (ccTransaction.getInput() ? 1 : -1) * ccTransaction.getAmount(), db);
}
db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction);
}
} else {
/*List<CryptoCoinTransaction> ccTransactions = new ArrayList();
btTransactions = new ArrayList();*/ //TODO transactions involving multiples accounts
CryptoCoinTransaction ccTransaction = new CryptoCoinTransaction();
BitcoinTransaction btTransaction = new BitcoinTransaction();
btTransaction.setTxId(txi.txid);
btTransaction.setBlock(txi.blockheight);
btTransaction.setFee((long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision())));
btTransaction.setConfirmations(txi.confirmations);
ccTransaction.setDate(new Date(txi.time * 1000));
if (txi.txlock || txi.confirmations >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
ccTransaction.setConfirmed(true);
} else {
ccTransaction.setConfirmed(false);
}
ccTransaction.setInput(false);
long amount = 0;
//transaction.setAccount(this.mAccount);
//transaction.setType(cryptoCoin);
List<BitcoinTransactionGTxIO> gtxios = new ArrayList();
for (Vin vin : txi.vin) {
BitcoinTransactionGTxIO input = new BitcoinTransactionGTxIO();
String addr = vin.addr;
input.setAddress(addr);
input.setIndex(vin.n);
input.setOutput(true);
input.setAmount((long) (vin.value * Math.pow(10, cryptoCoin.getPrecision())));
input.setOriginalTxId(vin.txid);
input.setScriptHex(vin.scriptSig.hex);
BitcoinAddress address = db.bitcoinAddressDao().getdadress(addr);
if (address != null) {
if (ccTransaction.getAccountId() < 0) {
ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setFrom(addr);
ccTransaction.setInput(false);
amount -= (long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision()));
}
//if (ccTransaction.getAccountId() == address.getAccountId()) {
amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision()));
//}
}
if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) {
ccTransaction.setFrom(addr);
}
gtxios.add(input);
} }
for (Vout vout : txi.vout) { public void send(final GeneralAccountSendRequest request){
if (vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0) {
} else {
BitcoinTransactionGTxIO output = new BitcoinTransactionGTxIO();
String addr = vout.scriptPubKey.addresses[0];
output.setAddress(addr);
output.setIndex(vout.n);
output.setOutput(false);
output.setAmount((long) (vout.value * Math.pow(10, cryptoCoin.getPrecision())));
output.setScriptHex(vout.scriptPubKey.hex);
output.setOriginalTxId(txi.txid);
gtxios.add(output);
BitcoinAddress address = db.bitcoinAddressDao().getdadress(addr);
if (address != null) {
if (ccTransaction.getAccountId() < 0) {
ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setInput(true);
ccTransaction.setTo(addr);
}
//if (ccTransaction.getAccountId() == address.getAccountId()) {
amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision()));
//}
} else {
//TOOD multiple send address
if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) {
ccTransaction.setTo(addr);
}
}
}
}
ccTransaction.setAmount(amount);
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.getLabel(), this.cryptoCoin.getCryptoNet().name());
if (currency == null) {
currency = new CryptoCurrency();
currency.setCryptoNet(this.cryptoCoin.getCryptoNet());
currency.setName(this.cryptoCoin.getLabel());
currency.setPrecision(this.cryptoCoin.getPrecision());
long idCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(currency)[0];
currency.setId(idCurrency);
}
ccTransaction.setIdCurrency((int) currency.getId());
long ccId = db.transactionDao().insertTransaction(ccTransaction)[0];
btTransaction.setCryptoCoinTransactionId(ccId);
long btId = db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction)[0];
for (BitcoinTransactionGTxIO gtxio : gtxios) {
gtxio.setBitcoinTransactionId(ccId);
db.bitcoinTransactionDao().insertBitcoinTransactionGTxIO(gtxio);
}
if (ccTransaction.isConfirmed()) {
updateBalance(ccTransaction, amount, db);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
private void createGeneralAccount(CreateBitcoinAccountRequest request){
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
CryptoNetAccount account = new CryptoNetAccount();
account.setAccountIndex(0);
account.setCryptoNet(this.cryptoCoin.getCryptoNet());
account.setName(request.getAccountSeed().getName());
account.setSeedId(request.getAccountSeed().getId());
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(account)[0];
account.setId(idAccount);
loadAccountFromDB(account,request.getContext());
request.setStatus(CreateBitcoinAccountRequest.StatusCode.SUCCEEDED);
}
private void updateBalance(CryptoCoinTransaction ccTransaction, long amount, CrystalDatabase db){
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.getLabel(), this.cryptoCoin.getCryptoNet().name());
if (currency == null) {
currency = new CryptoCurrency();
currency.setCryptoNet(this.cryptoCoin.getCryptoNet());
currency.setName(this.cryptoCoin.getLabel());
currency.setPrecision(this.cryptoCoin.getPrecision());
long idCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(currency)[0];
currency.setId(idCurrency);
}
CryptoCoinBalance balance = db.cryptoCoinBalanceDao().getBalanceFromAccount(ccTransaction.getAccountId(), currency.getId());
if (balance == null) {
balance = new CryptoCoinBalance();
balance.setAccountId(ccTransaction.getAccountId());
balance.setCryptoCurrencyId(currency.getId());
long idBalance = db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance)[0];
balance.setId(idBalance);
}
balance.setBalance(balance.getBalance()+amount);
db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance);
}
private void validateAddress(ValidateBitcoinAddressRequest request){
try{
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), request.getAddress());
request.setAddressValid(true);
}catch(AddressFormatException ex){
request.setAddressValid(false);
}
request.validate();
}
public void send(final BitcoinSendRequest request){
//TODO check server connection //TODO check server connection
//TODO validate to address //TODO validate to address
System.out.println("GeneralAccount Manager Send request, asking fee"); InsightApiGenerator.getEstimateFee(request.getAccount().getCryptoNet(),new ApiRequest(1, new ApiRequestListener() {
InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
System.out.println("GeneralAccount Manager Send request, fee " + answer.toString()); Transaction tx = new Transaction(request.getAccount().getNetworkParam());
try {
Transaction tx = new Transaction(cryptoCoin.getParameters());
long currentAmount = 0; long currentAmount = 0;
long fee = -1; long fee = -1;
long feeRate = (long) (((double) answer) * Math.pow(10, cryptoCoin.getPrecision())); long feeRate = (Long) answer;
fee = 226 * feeRate; fee = 226 * feeRate;
System.out.println("GeneralAccount Manager Send request getting utxos" ); List<GeneralCoinAddress> addresses = request.getAccount().getAddresses();
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext()); List<GTxIO> utxos = new ArrayList();
db.bitcoinTransactionDao(); for(GeneralCoinAddress address : addresses){
List<GTxIO> addrUtxos = address.getUTXos();
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(), db); for(GTxIO addrUtxo : addrUtxos){
System.out.println("GeneralAccount Manager Send request utxos found " + utxos.size() ); utxos.add(addrUtxo);
for(BitcoinTransactionGTxIO utxo : utxos){ currentAmount += addrUtxo.getAmount();
currentAmount += utxo.getAmount(); if(currentAmount >= request.getAmount()+ fee){
if(currentAmount >= request.getAmount() + fee) { break;
}
}
if(currentAmount >= request.getAmount() + fee){
break; break;
} }
} }
if (currentAmount < request.getAmount() + fee) {
System.out.println("GeneralAccount Manager Send request no balance" ); if(currentAmount< request.getAmount() + fee){
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE); request.setStatus(GeneralAccountSendRequest.StatusCode.NO_BALANCE);
return; return;
} }
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
//String to an address //String to an address
Address toAddr = Address.fromBase58(cryptoCoin.getParameters(), request.getToAccount()); Address toAddr = Address.fromBase58(request.getAccount().getNetworkParam(), request.getToAccount());
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr); tx.addOutput(Coin.valueOf(request.getAmount()), toAddr);
/*if(request.getMemo()!= null && !request.getMemo().isEmpty()){ if(request.getMemo()!= null && !request.getMemo().isEmpty()){
String memo = request.getMemo(); String memo = request.getMemo();
if(request.getMemo().length()>40){ if(request.getMemo().length()>40){
memo = memo.substring(0,40); memo = memo.substring(0,40);
@ -433,282 +99,47 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
System.arraycopy(memo.getBytes(),0,scriptByte,2,memo.length()); System.arraycopy(memo.getBytes(),0,scriptByte,2,memo.length());
Script memoScript = new Script(scriptByte); Script memoScript = new Script(scriptByte);
tx.addOutput(Coin.valueOf(0),memoScript); tx.addOutput(Coin.valueOf(0),memoScript);
}*/ }
//Change address //Change address
long remain = currentAmount - request.getAmount() - fee; long remain = currentAmount - request.getAmount() - fee;
if (remain > 0) { if( remain > 0 ) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId()); Address changeAddr = Address.fromBase58(request.getAccount().getNetworkParam(), request.getAccount().getNextChangeAddress());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr;
if (btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size() <= 0) {
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
} else {
if (btAddress == null) {
index = 0;
} else {
index++;
}
btAddress = new BitcoinAddress();
btAddress.setIndex(index);
btAddress.setAccountId(request.getSourceAccount().getId());
btAddress.setChange(true);
btAddress.setAddress(HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)).toAddress(cryptoCoin.getParameters()).toString());
db.bitcoinAddressDao().insertBitcoinAddresses(btAddress);
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
}
tx.addOutput(Coin.valueOf(remain), changeAddr); tx.addOutput(Coin.valueOf(remain), changeAddr);
} }
for (BitcoinTransactionGTxIO utxo : utxos) { for(GTxIO utxo: utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId()); Sha256Hash txHash = Sha256Hash.wrap(utxo.getTransaction().getTxid());
Script script = new Script(Util.hexToBytes(utxo.getScriptHex())); Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash); TransactionOutPoint outPoint = new TransactionOutPoint(request.getAccount().getNetworkParam(), utxo.getIndex(), txHash);
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress()); if(utxo.getAddress().getKey().isPubKeyOnly()){
ECKey addrKey; if(utxo.getAddress().isIsChange()){
utxo.getAddress().setKey(HDKeyDerivation.deriveChildKey(request.getAccount().getChangeKey(), new ChildNumber(utxo.getAddress().getIndex(), false)));
if (btAddress.isChange()) { }else{
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)); utxo.getAddress().setKey(HDKeyDerivation.deriveChildKey(request.getAccount().getExternalKey(), new ChildNumber(utxo.getAddress().getIndex(), false)));
} else {
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
} }
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
currentAmount -= utxo.getAmount();
if(currentAmount<= 0){
break;
} }
tx.addSignedInput(outPoint, script, utxo.getAddress().getKey(), Transaction.SigHash.ALL, true);
} }
System.out.println("GeneralAccount Manager Send request rawtx " +Util.bytesToHex(tx.bitcoinSerialize()) ); InsightApiGenerator.broadcastTransaction(request.getAccount().getCryptoNet(),Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
InsightApiGenerator.broadcastTransaction(cryptoCoin, 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) {
System.out.println("GeneralAccount MAnager succed send"); request.setStatus(GeneralAccountSendRequest.StatusCode.SUCCEEDED);
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
} }
@Override @Override
public void fail(int idPetition) { public void fail(int idPetition) {
System.out.println("GeneralAccount MAnager succed fail"); request.setStatus(GeneralAccountSendRequest.StatusCode.PETITION_FAILED);
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
} }
})); }));
}catch(Exception e){
System.out.println("GeneralAccount Manager Send request error ");
e.printStackTrace();
}
} }
@Override @Override
public void fail(int idPetition) { public void fail(int idPetition) {
System.out.println("GeneralAccount Manager Send request fee fail" ); request.setStatus(GeneralAccountSendRequest.StatusCode.NO_FEE);
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
} }
})); }));
} }
private void getNextAddress(NextBitcoinAccountAddressRequest request){
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
long index = db.bitcoinAddressDao().getLastExternalAddress(request.getAccount().getId());
BitcoinAddress address = db.bitcoinAddressDao().getExternalByIndex(index);
if(address != null && db.bitcoinTransactionDao().getGtxIOByAddress(address.getAddress()).size()<=0){
request.setAddress(address.getAddress());
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
}else {
index++;
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
ECKey addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) index, true));
address = new BitcoinAddress();
address.setChange(false);
address.setAccountId(request.getAccount().getId());
address.setIndex(index);
String addressString = addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin, addressString, true, null);
request.setAddress(addressString);
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
}
}
private void calculateUri(CalculateBitcoinUriRequest request) {
StringBuilder uri = new StringBuilder(this.cryptoCoin.name().toLowerCase()+":");
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
long index = db.bitcoinAddressDao().getLastExternalAddress(request.getAccount().getId());
BitcoinAddress address = db.bitcoinAddressDao().getExternalByIndex(index);
if(address != null && db.bitcoinTransactionDao().getGtxIOByAddress(address.getAddress()).size()<=0){
uri.append(address.getAddress());
}else {
index++;
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
ECKey addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) index, true));
address = new BitcoinAddress();
address.setChange(false);
address.setAccountId(request.getAccount().getId());
address.setIndex(index);
String addressString = addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin, addressString, true, null);
uri.append(address.getAddress());
}
if(request.getAmount() > 0 ){
uri.append("?amount=");
uri.append(Double.toString(request.getAmount()));
}
System.out.println("GeneralAccountMAnager uri calculated : " + uri.toString());
request.setUri(uri.toString());
//request.validate();
}
private void parseUri(BitcoinUriParseRequest request){
String uri = request.getUri();
if(uri.indexOf(":")>0){
String cryptoNet = uri.substring(0,uri.indexOf(":"));
if(cryptoNet.equalsIgnoreCase(this.cryptoCoin.name().toLowerCase())){
try{
int parameterIndex =uri.indexOf("?");
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), uri.substring(uri.indexOf(":")+1,parameterIndex>0?parameterIndex:uri.length()));
request.setAddress(address.toString());
request.setStatus(BitcoinUriParseRequest.StatusCode.VALID);
if(parameterIndex>0){
try {
String[] parameters = uri.substring(parameterIndex + 1).split("&");
for (String parameter : parameters) {
int idx = parameter.indexOf("=");
if (idx > 0 && parameter.substring(0, idx).equalsIgnoreCase("amount")) {
request.setAmount(Double.parseDouble(parameter.substring(idx + 1)));
}
}
}catch(Exception ignored){}
}
}catch(AddressFormatException ex){
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
}
}else{
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
}
}else{
int parameterIndex =uri.indexOf("?");
if(parameterIndex>0){
try{
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), uri.substring(uri.indexOf(":")+1,parameterIndex>0?parameterIndex:uri.length()));
request.setAddress(address.toString());
request.setStatus(BitcoinUriParseRequest.StatusCode.VALID);
try{
String[] parameters = uri.substring(parameterIndex+1).split("&");
for(String parameter : parameters){
int idx = parameter.indexOf("=");
if(idx > 0 && parameter.substring(0,idx).equalsIgnoreCase("amount")){
request.setAmount(Double.parseDouble(parameter.substring(idx+1)));
}
}
}catch(Exception ignored){}
}catch(AddressFormatException ex){
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
}
}else{
try{
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), uri);
request.setAddress(address.toString());
request.setStatus(BitcoinUriParseRequest.StatusCode.VALID);
}catch(AddressFormatException ex){
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
}
}
}
request.validate();
}
private List<BitcoinTransactionGTxIO> getUtxos(long accountId, CrystalDatabase db){
List<BitcoinTransactionGTxIO> answer = new ArrayList<>();
List<BitcoinTransactionGTxIO> bTGTxI = new ArrayList<>();
List<BitcoinTransactionGTxIO> bTGTxO = new ArrayList<>();
List<CryptoCoinTransaction> ccTransactions = db.transactionDao().getByIdAccount(accountId);
for(CryptoCoinTransaction ccTransaction : ccTransactions) {
List<BitcoinTransactionGTxIO> gtxios = db.bitcoinTransactionDao().getGtxIOByTransaction(ccTransaction.getId());
for(BitcoinTransactionGTxIO gtxio : gtxios){
if(db.bitcoinAddressDao().addressExists(gtxio.getAddress())){
if(gtxio.isOutput()){
bTGTxO.add(gtxio);
}else{
bTGTxI.add(gtxio);
}
}
}
}
for(BitcoinTransactionGTxIO gtxi : bTGTxI){
boolean find = false;
for(BitcoinTransactionGTxIO gtxo : bTGTxO){
if(gtxo.getOriginalTxId().equals(gtxi.getOriginalTxId())){
find = true;
break;
}
}
if(!find){
answer.add(gtxi);
}
}
return answer;
}
class CheckAddressForTransaction implements InsightApiGenerator.HasTransactionListener{
BitcoinAddressDao bitcoinAddressDao;
long idAccount;
DeterministicKey addressKey;
boolean isChange;
int lastIndex;
public CheckAddressForTransaction(BitcoinAddressDao bitcoinAddressDao, long idAccount, DeterministicKey addressKey, boolean isChange, int lastIndex) {
this.bitcoinAddressDao = bitcoinAddressDao;
this.idAccount = idAccount;
this.addressKey = addressKey;
this.isChange = isChange;
this.lastIndex = lastIndex;
}
@Override
public void hasTransaction(boolean value) {
if(value){
ECKey externalAddrKey = HDKeyDerivation.deriveChildKey(addressKey, new ChildNumber(lastIndex+1, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(isChange);
address.setAccountId(idAccount);
address.setIndex(lastIndex+1);
String addressString =externalAddrKey.toAddress(cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
bitcoinAddressDao.insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
new CheckAddressForTransaction(bitcoinAddressDao,idAccount,addressKey,isChange,lastIndex+1));
}
}
}
} }

View file

@ -1,756 +0,0 @@
package cy.agorise.crystalwallet.manager;
import android.annotation.SuppressLint;
import android.content.Context;
import com.google.common.primitives.UnsignedLong;
import org.bitcoinj.core.ECKey;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
import cy.agorise.crystalwallet.apigenerator.ApiRequest;
import cy.agorise.crystalwallet.apigenerator.ApiRequestListener;
import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
import cy.agorise.crystalwallet.dao.AccountSeedDao;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.dao.TransactionDao;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.enums.SeedType;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
import cy.agorise.crystalwallet.models.BitsharesAsset;
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount;
import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
import cy.agorise.crystalwallet.models.seed.BIP39;
import cy.agorise.crystalwallet.network.CryptoNetManager;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
import cy.agorise.crystalwallet.requestmanagers.GetBitsharesAccountNameCacheRequest;
import cy.agorise.crystalwallet.requestmanagers.ImportBitsharesAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateExistBitsharesAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.BaseOperation;
import cy.agorise.graphenej.BrainKey;
import cy.agorise.graphenej.PublicKey;
import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.models.AccountProperties;
import cy.agorise.graphenej.models.BlockHeader;
import cy.agorise.graphenej.models.HistoricalTransfer;
import cy.agorise.graphenej.operations.TransferOperationBuilder;
/**
* The manager for the Bitshare CryptoCoin
*
* Created by henry on 26/9/2017.
*/
public class SteemAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
private final static String SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
private final static String DEFAULT_TIME_ZONE = "GMT";
@Override
public void createAccountFromSeed(CryptoNetAccount account, final ManagerRequest request, final Context context) {
//TODO error, can't create steem accounts
}
@Override
public void importAccountFromSeed(CryptoNetAccount account, final Context context) {
if(account instanceof GrapheneAccount) {
final GrapheneAccount grapheneAccount = (GrapheneAccount) account;
if(grapheneAccount.getAccountId() == null){
this.getAccountInfoByName(grapheneAccount.getName(), new ManagerRequest() {
@Override
public void success(Object answer) {
GrapheneAccount fetch = (GrapheneAccount) answer;
grapheneAccount.setAccountId(fetch.getAccountId());
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
long[] idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
grapheneAccount.setId(idAccount[0]);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
subscribeSteemAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
@Override
public void fail() {
//TODO get account data fail
}
});
}else if(grapheneAccount.getName() == null){
this.getAccountInfoById(grapheneAccount.getAccountId(), new ManagerRequest() {
@Override
public void success(Object answer) {
GrapheneAccount fetch = (GrapheneAccount) answer;
grapheneAccount.setName(fetch.getName());
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
grapheneAccount.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
subscribeSteemAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
@Override
public void fail() {
//TODO get account data fail
}
});
}else {
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
grapheneAccount.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
subscribeSteemAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context);
}
}
}
@Override
public void loadAccountFromDB(CryptoNetAccount account, final Context context) {
if(account instanceof GrapheneAccount){
final GrapheneAccount grapheneAccount = (GrapheneAccount) account;
final CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final GrapheneAccountInfo info = db.grapheneAccountInfoDao().getByAccountId(account.getId());
grapheneAccount.loadInfo(info);
if(grapheneAccount.getAccountId() == null){
this.getAccountInfoByName(grapheneAccount.getName(), new ManagerRequest() {
@Override
public void success(Object answer) {
GrapheneAccount fetch = (GrapheneAccount) answer;
info.setAccountId(fetch.getAccountId());
grapheneAccount.setAccountId(fetch.getAccountId());
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
subscribeSteemAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
@Override
public void fail() {
//TODO account data retrieve failed
}
});
}else if(grapheneAccount.getName() == null){
this.getAccountInfoById(grapheneAccount.getAccountId(), new ManagerRequest() {
@Override
public void success(Object answer) {
GrapheneAccount fetch = (GrapheneAccount) answer;
info.setName(fetch.getName());
grapheneAccount.setName(fetch.getName());
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
subscribeSteemAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
@Override
public void fail() {
//TODO account data retrieve failed
}
});
}else{
subscribeSteemAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
}
}
private void subscribeSteemAccount(long accountId, String accountSteemID, Context context){
GrapheneApiGenerator.subscribeSteemAccount(accountId,accountSteemID,context);
SteemAccountManager.refreshAccountTransactions(accountId,context);
GrapheneApiGenerator.getAccountBalance(accountId,accountSteemID,CryptoNet.STEEM,context);
}
/**
* Process the bitshares manager request
* @param request The request Object
*/
@Override
public void onNewRequest(CryptoNetInfoRequest request) {
if(request.getCoin().equals(CryptoCoin.STEEM)) {
if (request instanceof ImportBitsharesAccountRequest) {
this.importAccount((ImportBitsharesAccountRequest) request);
} else if (request instanceof ValidateImportBitsharesAccountRequest) {
this.validateImportAccount((ValidateImportBitsharesAccountRequest) request);
} else if (request instanceof ValidateExistBitsharesAccountRequest) {
this.validateExistAcccount((ValidateExistBitsharesAccountRequest) request);
} else if (request instanceof ValidateBitsharesSendRequest) {
this.validateSendRequest((ValidateBitsharesSendRequest) request);
} else if (request instanceof GetBitsharesAccountNameCacheRequest) {
this.getBitsharesAccountNameCacheRequest((GetBitsharesAccountNameCacheRequest) request);
} else {
//TODO not implemented
System.out.println("Error request not implemented " + request.getClass().getName());
}
}
}
private void importAccount(final ImportBitsharesAccountRequest importRequest){
final CrystalDatabase db = CrystalDatabase.getAppDatabase(importRequest.getContext());
final AccountSeedDao accountSeedDao = db.accountSeedDao();
ApiRequest getAccountNamesBK = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
if(answer != null && importRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.NOT_STARTED)) {
UserAccount userAccount = (UserAccount) answer;
importRequest.setSeedType(SeedType.BRAINKEY);
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
AccountSeed seed = new AccountSeed();
seed.setName(userAccount.getName());
seed.setType(importRequest.getSeedType());
seed.setMasterSeed(importRequest.getMnemonic());
long idSeed = accountSeedDao.insertAccountSeed(seed);
if (idSeed >= 0) {
GrapheneAccount account = new GrapheneAccount();
account.setCryptoNet(CryptoNet.STEEM);
account.setAccountIndex(0);
account.setSeedId(idSeed);
account.setAccountId(userAccount.getObjectId());
importAccountFromSeed(account, importRequest.getContext());
}
}
}
@Override
public void fail(int idPetition) {
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.BAD_SEED);
}
});
BrainKey bk = new BrainKey(importRequest.getMnemonic(), 0);
GrapheneApiGenerator.getAccountByOwnerOrActiveAddress(bk.getPublicAddress("STM"),CryptoNet.STEEM,getAccountNamesBK);
}
/**
* Process the import account request
*/
private void validateImportAccount(final ValidateImportBitsharesAccountRequest importRequest){
//TODO check internet and server status
final CrystalDatabase db = CrystalDatabase.getAppDatabase(importRequest.getContext());
final AccountSeedDao accountSeedDao = db.accountSeedDao();
ApiRequest checkAccountName = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
ApiRequest getAccountInfo = new ApiRequest(1,new ApiRequestListener(){
@Override
public void success(Object answer, int idPetition) {
if(answer != null && answer instanceof AccountProperties) {
AccountProperties prop = (AccountProperties) answer;
BrainKey bk = new BrainKey(importRequest.getMnemonic(), 0);
for(PublicKey activeKey : prop.owner.getKeyAuthList()){
if((new Address(activeKey.getKey(),"STM")).toString().equals(bk.getPublicAddress("STM").toString())){
importRequest.setSeedType(SeedType.BRAINKEY);
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
break;
}
}
if ((importRequest.getStatus() == ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)){
if (importRequest.addAccountIfValid()) {
AccountSeed seed = new AccountSeed();
seed.setName(importRequest.getAccountName());
seed.setType(importRequest.getSeedType());
seed.setMasterSeed(importRequest.getMnemonic());
long idSeed = accountSeedDao.insertAccountSeed(seed);
if (idSeed >= 0) {
GrapheneAccount account = new GrapheneAccount();
account.setCryptoNet(CryptoNet.STEEM);
account.setAccountIndex(0);
account.setSeedId(idSeed);
account.setName(importRequest.getAccountName());
importAccountFromSeed(account, importRequest.getContext());
}
}
return;
}
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.BAD_SEED);
}
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.PETITION_FAILED);
}
@Override
public void fail(int idPetition) {
//
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.NO_ACCOUNT_DATA);
}
});
GrapheneApiGenerator.getAccountById((String)answer,CryptoNet.STEEM,getAccountInfo);
}
@Override
public void fail(int idPetition) {
//
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.ACCOUNT_DOESNT_EXIST);
}
});
GrapheneApiGenerator.getAccountIdByName(importRequest.getAccountName(),CryptoNet.STEEM,checkAccountName);
}
/**
* Process the account exist request, it consults the bitshares api for the account name.
*
* This can be used to know if the name is avaible, or the account to be send fund exists
*/
private void validateExistAcccount(final ValidateExistBitsharesAccountRequest validateRequest){
ApiRequest checkAccountName = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
if (answer != null) {
validateRequest.setAccountExists(true);
} else {
validateRequest.setAccountExists(false);
}
}
@Override
public void fail(int idPetition) {
//TODO verified
validateRequest.setAccountExists(false);
}
});
GrapheneApiGenerator.getAccountIdByName(validateRequest.getAccountName(),CryptoNet.STEEM,checkAccountName);
}
/**
* Broadcast a transaction request
*/
private void validateSendRequest(final ValidateBitsharesSendRequest sendRequest) {
//TODO check internet, server connection
//TODO feeAsset
CrystalDatabase db = CrystalDatabase.getAppDatabase(sendRequest.getContext());
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(sendRequest.getAsset(), CryptoNet.STEEM.name());
if (currency == null){
getAssetInfoByName(sendRequest.getAsset(), new ManagerRequest() {
@Override
public void success(Object answer) {
validateSendRequest(sendRequest, ((BitsharesAsset) answer).getBitsharesId());
}
@Override
public void fail() {
sendRequest.setStatus(ValidateBitsharesSendRequest.StatusCode.NO_ASSET_INFO_DB);
}
});
}else{
BitsharesAssetInfo info = db.bitsharesAssetDao().getBitsharesAssetInfo(currency.getId());
if (info == null || info.getBitsharesId() == null || info.getBitsharesId().isEmpty()){
getAssetInfoByName(sendRequest.getAsset(), new ManagerRequest() {
@Override
public void success(Object answer) {
validateSendRequest(sendRequest, ((BitsharesAsset) answer).getBitsharesId());
}
@Override
public void fail() {
sendRequest.setStatus(ValidateBitsharesSendRequest.StatusCode.NO_ASSET_INFO);
}
});
}else {
this.validateSendRequest(sendRequest, info.getBitsharesId());
}
}
}
/**
* Broadcast a send asset request, the idAsset is already fetched
* @param sendRequest The petition for transfer
* @param idAsset The Bitshares Asset's id
*/
private void validateSendRequest(final ValidateBitsharesSendRequest sendRequest , final String idAsset){
final Asset feeAsset = new Asset(idAsset);
final UserAccount fromUserAccount =new UserAccount(sendRequest.getSourceAccount().getAccountId());
final CrystalDatabase db = CrystalDatabase.getAppDatabase(sendRequest.getContext());
BitsharesAccountNameCache cacheAccount = db.bitsharesAccountNameCacheDao().getByAccountName(sendRequest.getToAccount());
if(cacheAccount == null) {
this.getAccountInfoByName(sendRequest.getToAccount(), new ManagerRequest() {
@Override
public void success(Object answer) {
GrapheneAccount toUserGrapheneAccount = (GrapheneAccount) answer;
UserAccount toUserAccount = new UserAccount(toUserGrapheneAccount.getAccountId());
try {
BitsharesAccountNameCache cacheAccount = new BitsharesAccountNameCache();
cacheAccount.setName(sendRequest.getToAccount());
cacheAccount.setAccountId(toUserAccount.getObjectId());
db.bitsharesAccountNameCacheDao().insertBitsharesAccountNameCache(cacheAccount);
}catch(Exception e){
e.printStackTrace();
}
validateSendRequest(sendRequest,fromUserAccount,toUserAccount,feeAsset,idAsset);
}
@Override
public void fail() {
sendRequest.setStatus(ValidateBitsharesSendRequest.StatusCode.NO_TO_USER_INFO);
}
});
}else {
UserAccount toUserAccount = new UserAccount(cacheAccount.getAccountId());
this.validateSendRequest(sendRequest,fromUserAccount,toUserAccount,feeAsset,idAsset);
}
}
/**
* Broadcast a transaction request
* @param sendRequest The petition for transfer operation
* @param fromUserAccount The source account
* @param toUserAccount The receiver account
* @param feeAsset The Fee Asset
* @param idAsset The id of the asset to be used on the operation
*/
private void validateSendRequest(final ValidateBitsharesSendRequest sendRequest, UserAccount fromUserAccount,
UserAccount toUserAccount, Asset feeAsset, String idAsset){
TransferOperationBuilder builder = new TransferOperationBuilder()
.setSource(fromUserAccount)
.setDestination(toUserAccount)
.setTransferAmount(new AssetAmount(UnsignedLong.valueOf(sendRequest.getAmount()), new Asset(idAsset)))
.setFee(new AssetAmount(UnsignedLong.valueOf(0), feeAsset));
if (sendRequest.getMemo() != null) {
//builder.setMemo(new Memo(fromUserAccount,toUserAccount,0,sendRequest.getMemo().getBytes()));
//TODO memo
System.out.println("transaction has memo");
}
ArrayList<BaseOperation> operationList = new ArrayList<>();
operationList.add(builder.build());
ECKey privateKey = sendRequest.getSourceAccount().getActiveKey(sendRequest.getContext());
Transaction transaction = new Transaction(privateKey, null, operationList);
transaction.setChainId(CryptoNetManager.getChaindId(CryptoNet.STEEM));
ApiRequest transactionRequest = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
sendRequest.setStatus(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
sendRequest.setStatus(ValidateBitsharesSendRequest.StatusCode.PETITION_FAILED);
}
});
GrapheneApiGenerator.broadcastTransaction(transaction, feeAsset, transactionRequest);
}
private void getBitsharesAccountNameCacheRequest(final GetBitsharesAccountNameCacheRequest request){
final CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
BitsharesAccountNameCache cacheAccount = db.bitsharesAccountNameCacheDao().getByAccountId(request.getAccountId());
if(cacheAccount == null) {
this.getAccountInfoById(request.getAccountId(), new ManagerRequest() {
@Override
public void success(Object answer) {
GrapheneAccount userGrapheneAccount = (GrapheneAccount) answer;
BitsharesAccountNameCache cacheAccount = new BitsharesAccountNameCache();
cacheAccount.setName(userGrapheneAccount.getName());
cacheAccount.setAccountId(request.getAccountId());
db.bitsharesAccountNameCacheDao().insertBitsharesAccountNameCache(cacheAccount);
request.setAccountName(userGrapheneAccount.getName());
}
@Override
public void fail() {
//TODO error
}
});
}else {
request.setAccountName(cacheAccount.getName());
}
}
/**
* Returns the account info from a graphene id
* @param grapheneId The graphene id of the account
*/
private void getAccountInfoById(String grapheneId, ManagerRequest request){
AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
ApiRequest accountRequest = new ApiRequest(0, listener);
GrapheneApiGenerator.getAccountById(grapheneId,CryptoNet.STEEM,accountRequest);
}
/**
* Gets account info by its name
* @param grapheneName The name of the account to retrieve
*/
private void getAccountInfoByName(String grapheneName, ManagerRequest request){
AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
ApiRequest accountRequest = new ApiRequest(0, listener);
GrapheneApiGenerator.getAccountByName(grapheneName,CryptoNet.STEEM,accountRequest);
}
//TODO expand function to be more generic
private void getAssetInfoByName(String assetName, ManagerRequest request){
AssetIdOrNameListener nameListener = new AssetIdOrNameListener(request);
ApiRequest assetRequest = new ApiRequest(0, nameListener);
ArrayList<String> assetNames = new ArrayList<>();
assetNames.add(assetName);
GrapheneApiGenerator.getAssetByName(assetNames, CryptoNet.STEEM, assetRequest);
}
/**
* Refresh the transactions of an account, important to notice, it return nothing, to get the changes tuse the LiveData
* @param idAccount database id of the account
* @param context The android context of this application
*/
private static void refreshAccountTransactions(long idAccount, Context context){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
List<CryptoCoinTransaction> transactions = db.transactionDao().getByIdAccount(idAccount);
CryptoNetAccount account = db.cryptoNetAccountDao().getById(idAccount);
if(account.getCryptoNet() == CryptoNet.STEEM) {
GrapheneAccount grapheneAccount = new GrapheneAccount(account);
grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(idAccount));
int start = transactions.size();
int limit = 50;
int stop = start + limit;
ApiRequest transactionRequest = new ApiRequest(0, new TransactionRequestListener(start, stop, limit, grapheneAccount, db));
GrapheneApiGenerator.getAccountTransaction(grapheneAccount.getAccountId(), start, stop, limit, CryptoNet.STEEM,transactionRequest);
}
}
/**
* Class that handles the transactions request
*/
private static class TransactionRequestListener implements ApiRequestListener{
/**
* Start index
*/
int start;
/**
* End index
*/
int stop;
/**
* Limit of transasction to fetch
*/
int limit;
/**
* The grapheneaccount with all data CryptoCurrnecy + info
*/
GrapheneAccount account;
/**
* The database
*/
CrystalDatabase db;
/**
* Basic consturctor
*/
TransactionRequestListener(int start, int stop, int limit, GrapheneAccount account, CrystalDatabase db) {
this.start = start;
this.stop = stop;
this.limit = limit;
this.account = account;
this.db = db;
}
/**
* Handles the success request of the transaction, if the amount of transaction is equal to the limit, ask for more transaction
* @param answer The answer, this object depends on the kind of request is made to the api
* @param idPetition the id of the ApiRequest petition
*/
@Override
public void success(Object answer, int idPetition) {
List<HistoricalTransfer> transfers = (List<HistoricalTransfer>) answer ;
for(final HistoricalTransfer transfer : transfers) {
if (transfer.getOperation() != null){
final CryptoCoinTransaction transaction = new CryptoCoinTransaction();
transaction.setAccountId(account.getId());
transaction.setAmount(transfer.getOperation().getAssetAmount().getAmount().longValue());
BitsharesAssetInfo info = db.bitsharesAssetDao().getBitsharesAssetInfoById(transfer.getOperation().getAssetAmount().getAsset().getObjectId());
if (info == null) {
//The cryptoCurrency is not in the database, queringfor its data
ApiRequest assetRequest = new ApiRequest(0, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
ArrayList<BitsharesAsset> assets = (ArrayList<BitsharesAsset>) answer;
for(BitsharesAsset asset : assets){
long currencyId = -1;
CryptoCurrency cryptoCurrencyDb = db.cryptoCurrencyDao().getByNameAndCryptoNet(asset.getName(),asset.getCryptoNet().name());
if (cryptoCurrencyDb != null){
currencyId = cryptoCurrencyDb.getId();
} else {
long idCryptoCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(asset)[0];
currencyId = idCryptoCurrency;
}
BitsharesAssetInfo info = new BitsharesAssetInfo(asset);
info.setCryptoCurrencyId(currencyId);
asset.setId((int)currencyId);
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
saveTransaction(transaction,info,transfer);
}
}
@Override
public void fail(int idPetition) {
//TODO Error
}
});
ArrayList<String> assets = new ArrayList<>();
assets.add(transfer.getOperation().getAssetAmount().getAsset().getObjectId());
GrapheneApiGenerator.getAssetById(assets,CryptoNet.STEEM,assetRequest);
}else{
saveTransaction(transaction,info,transfer);
}
}
}
if(transfers.size()>= limit){
// The amount of transaction in the answer is equal to the limit, we need to query to see if there is more transactions
int newStart= start + limit;
int newStop= stop + limit;
ApiRequest transactionRequest = new ApiRequest(newStart/limit, new TransactionRequestListener(newStart,newStop,limit,account,db));
GrapheneApiGenerator.getAccountTransaction(account.getAccountId(),newStart,newStop,limit,CryptoNet.STEEM,transactionRequest);
}
}
@Override
public void fail(int idPetition) {
}
private void saveTransaction(CryptoCoinTransaction transaction, BitsharesAssetInfo info, HistoricalTransfer transfer){
transaction.setIdCurrency((int)info.getCryptoCurrencyId());
transaction.setConfirmed(true); //graphene transaction are always confirmed
transaction.setFrom(transfer.getOperation().getFrom().getObjectId());
transaction.setInput(!transfer.getOperation().getFrom().getObjectId().equals(account.getAccountId()));
transaction.setTo(transfer.getOperation().getTo().getObjectId());
GrapheneApiGenerator.getBlockHeaderTime(transfer.getBlockNum(), CryptoNet.STEEM,new ApiRequest(0, new GetTransactionDate(transaction, db.transactionDao())));
}
}
/**
* Class to retrieve the account id or the account name, if one of those is missing
*/
private class AccountIdOrNameListener implements ApiRequestListener{
final ManagerRequest request;
GrapheneAccount account;
AccountIdOrNameListener(ManagerRequest request) {
this.request = request;
}
@Override
public void success(Object answer, int idPetition) {
if(answer instanceof AccountProperties){
AccountProperties props = (AccountProperties) answer;
account = new GrapheneAccount();
account.setAccountId(props.id);
account.setName(props.name);
}
request.success(account);
}
@Override
public void fail(int idPetition) {
request.fail();
}
}
/**
* Class to retrieve the asset id or the asset name, if one of those is missing
*/
private class AssetIdOrNameListener implements ApiRequestListener{
final ManagerRequest request;
BitsharesAsset asset;
AssetIdOrNameListener(ManagerRequest request) {
this.request = request;
}
@Override
public void success(Object answer, int idPetition) {
if(answer instanceof ArrayList) {
if (((ArrayList) answer).get(0) instanceof BitsharesAsset) {
asset = (BitsharesAsset) ((ArrayList) answer).get(0);
request.success(asset);
}
}
}
@Override
public void fail(int idPetition) {
//TODO fail asset retrieve
}
}
/**
* Class to retrieve the transaction date
*/
public static class GetTransactionDate implements ApiRequestListener{
/**
* The transaction to retrieve
*/
private CryptoCoinTransaction transaction;
/**
* The DAO to insert or update the transaction
*/
TransactionDao transactionDao;
GetTransactionDate(CryptoCoinTransaction transaction, TransactionDao transactionDao) {
this.transaction = transaction;
this.transactionDao = transactionDao;
}
@Override
public void success(Object answer, int idPetition) {
if(answer instanceof BlockHeader){
@SuppressLint("SimpleDateFormat") SimpleDateFormat dateFormat = new SimpleDateFormat(SIMPLE_DATE_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone(DEFAULT_TIME_ZONE));
try {
transaction.setDate(dateFormat.parse(((BlockHeader) answer).timestamp));
if (transactionDao.getByTransaction(transaction.getDate(),transaction.getFrom(),transaction.getTo(),transaction.getAmount()) == null) {
transactionDao.insertTransaction(transaction);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
@Override
public void fail(int idPetition) {
}
}
}

View file

@ -9,14 +9,12 @@ import android.content.Context;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil; import android.support.v7.util.DiffUtil;
import org.bitcoinj.core.Base58;
import org.bitcoinj.core.ECKey; import org.bitcoinj.core.ECKey;
import org.bitcoinj.crypto.HDKeyDerivation; import org.bitcoinj.crypto.HDKeyDerivation;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.Arrays;
import cy.agorise.crystalwallet.enums.SeedType; import cy.agorise.crystalwallet.enums.SeedType;
import cy.agorise.crystalwallet.models.seed.BIP39; import cy.agorise.crystalwallet.models.seed.BIP39;
@ -117,6 +115,8 @@ public class AccountSeed {
BufferedReader reader = null; BufferedReader reader = null;
switch (type) { switch (type) {
case BRAINKEY: case BRAINKEY:
try { try {
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("brainkeydict.txt"), "UTF-8")); reader = new BufferedReader(new InputStreamReader(context.getAssets().open("brainkeydict.txt"), "UTF-8"));
@ -130,7 +130,6 @@ public class AccountSeed {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
break;
case BIP39: case BIP39:
try { try {
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("bip39dict.txt"), "UTF-8")); reader = new BufferedReader(new InputStreamReader(context.getAssets().open("bip39dict.txt"), "UTF-8"));
@ -140,7 +139,6 @@ public class AccountSeed {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
break;
} }
return null; return null;
} }
@ -151,15 +149,6 @@ public class AccountSeed {
return new BrainKey(this.mMasterSeed,0).getPrivateKey(); return new BrainKey(this.mMasterSeed,0).getPrivateKey();
case BIP39: case BIP39:
return HDKeyDerivation.createMasterPrivateKey(new BIP39(mId, mMasterSeed).getSeed()); return HDKeyDerivation.createMasterPrivateKey(new BIP39(mId, mMasterSeed).getSeed());
case WIF:
byte[] decoded = Base58.decode(this.mMasterSeed);
byte[] privKey = Arrays.copyOfRange(decoded, 1, decoded.length - 4);
byte[] checksum = Arrays.copyOfRange(decoded, decoded.length - 4, decoded.length);
//TODO calculate chekcsum
while(privKey.length>32){
privKey = Arrays.copyOfRange(privKey,0,privKey.length-1);
}
return ECKey.fromPrivate(privKey);
} }
return null; return null;
} }

View file

@ -1,93 +0,0 @@
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.support.annotation.NonNull;
/**
* Represents a Bitcoin derivated address
*
* Created by Henry Varona on 10/17/2018.
*/
@Entity(
tableName="bitcoin_address",
primaryKeys = {"account_id","address_index","is_change"},
foreignKeys = {
@ForeignKey(
entity = CryptoNetAccount.class,
parentColumns = "id",
childColumns = "account_id",
onDelete = ForeignKey.CASCADE
)
}
)
public class BitcoinAddress {
/**
* The id of the account associated
*/
@ColumnInfo(name="account_id")
protected long accountId;
/**
* The index of this address
*/
@ColumnInfo(name="address_index")
@NonNull protected long index;
/**
* Whether or not this address is a change one
*/
@ColumnInfo(name="is_change")
@NonNull protected boolean isChange;
/**
* Address
*/
@ColumnInfo(name="address")
@NonNull protected String address;
public BitcoinAddress(long accountId, @NonNull long index, boolean isChange, String address) {
this.accountId = accountId;
this.index = index;
this.isChange = isChange;
this.address = address;
}
public BitcoinAddress() {
}
public long getAccountId() {
return accountId;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
@NonNull
public long getIndex() {
return index;
}
public void setIndex(@NonNull long index) {
this.index = index;
}
public boolean isChange() {
return isChange;
}
public void setChange(boolean change) {
isChange = change;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View file

@ -1,113 +0,0 @@
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() {
}
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;
}
}

View file

@ -1,26 +0,0 @@
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;
}

View file

@ -1,124 +0,0 @@
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 = CryptoCoinTransaction.class,
parentColumns = "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;
@ColumnInfo(name="amount")
protected long amount;
@ColumnInfo(name="script_hex")
protected String scriptHex;
@ColumnInfo(name="original_txid")
protected String originalTxId;
public BitcoinTransactionGTxIO() {
}
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;
}
public long getAmount() {
return amount;
}
public void setAmount(long amount) {
this.amount = amount;
}
public String getScriptHex() {
return scriptHex;
}
public void setScriptHex(String scriptHex) {
this.scriptHex = scriptHex;
}
public String getOriginalTxId() {
return originalTxId;
}
public void setOriginalTxId(String originalTxId) {
this.originalTxId = originalTxId;
}
}

View file

@ -20,13 +20,9 @@ import cy.agorise.crystalwallet.enums.CryptoCoin;
*/ */
@Entity( @Entity(
tableName="crypto_coin_transaction", tableName="crypto_coin_transaction",
primaryKeys = {
},
indices={ indices={
@Index(value={"account_id"}), @Index(value={"account_id"}),
@Index(value={"id_currency"}), @Index(value={"id_currency"})
@Index(value={"date", "account_id", "id_currency", "from", "to"},unique=true)
}, },
foreignKeys = { foreignKeys = {
@ForeignKey( @ForeignKey(
@ -70,7 +66,7 @@ public class CryptoCoinTransaction {
* The id of the account assoiciated, this is used for the foreign key definition * The id of the account assoiciated, this is used for the foreign key definition
*/ */
@ColumnInfo(name="account_id") @ColumnInfo(name="account_id")
protected long accountId = -1; protected long accountId;
/** /**
* The amount of asset is moved in this transaction * The amount of asset is moved in this transaction
*/ */

View file

@ -45,15 +45,6 @@ public class CryptoCurrency {
@ColumnInfo(name = "precision") @ColumnInfo(name = "precision")
private int mPrecision; private int mPrecision;
public CryptoCurrency() {
}
public CryptoCurrency(String name, CryptoNet cryptoNet, int precision) {
this.mName = name;
this.mCryptoNet = cryptoNet;
this.mPrecision = precision;
}
public long getId() { public long getId() {
return mId; return mId;
} }

View file

@ -1,45 +0,0 @@
package cy.agorise.crystalwallet.models;
import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil;
import cy.agorise.crystalwallet.enums.CryptoNet;
public class CryptoNetSelection {
CryptoNet cryptoNet;
Boolean selected;
public CryptoNetSelection(CryptoNet cryptoNet, Boolean selected) {
this.cryptoNet = cryptoNet;
this.selected = selected;
}
public CryptoNet getCryptoNet() {
return cryptoNet;
}
public void setCryptoNet(CryptoNet cryptoNet) {
this.cryptoNet = cryptoNet;
}
public Boolean getSelected() {
return selected;
}
public void setSelected(Boolean selected) {
this.selected = selected;
}
public static final DiffUtil.ItemCallback<CryptoNetSelection> DIFF_CALLBACK = new DiffUtil.ItemCallback<CryptoNetSelection>() {
@Override
public boolean areItemsTheSame(
@NonNull CryptoNetSelection oldCryptoNetSelection, @NonNull CryptoNetSelection newCryptoNetSelection) {
return oldCryptoNetSelection.getCryptoNet() == newCryptoNetSelection.getCryptoNet();
}
@Override
public boolean areContentsTheSame(
@NonNull CryptoNetSelection oldCryptoNetSelection, @NonNull CryptoNetSelection newCryptoNetSelection) {
return oldCryptoNetSelection.equals(newCryptoNetSelection);
}
};
}

View file

@ -31,17 +31,10 @@ public class GrapheneAccount extends CryptoNetAccount {
} }
public void loadInfo(GrapheneAccountInfo info){ public void loadInfo(GrapheneAccountInfo info){
if(info != null){
this.name = info.getName(); this.name = info.getName();
this.accountId = info.getAccountId(); this.accountId = info.getAccountId();
this.upgradedToLtm = info.getUpgradedToLtm(); this.upgradedToLtm = info.getUpgradedToLtm();
} }
else{
this.name = "";
this.accountId = "-1";
this.upgradedToLtm = false;
}
}
public String getName() { public String getName() {
return name; return name;

View file

@ -1,48 +0,0 @@
package cy.agorise.crystalwallet.network;
import cy.agorise.crystalwallet.apigenerator.insightapi.GetGenesisBlock;
import cy.agorise.crystalwallet.enums.CryptoCoin;
public class BitcoinCryptoNetVerifier extends CryptoNetVerifier{
final CryptoCoin cryptoCoin;
public BitcoinCryptoNetVerifier(CryptoCoin cryptoCoin) {
this.cryptoCoin = cryptoCoin;
}
@Override
public void checkURL(final String url) {
final long startTime = System.currentTimeMillis();
GetGenesisBlock genesisBloc = new GetGenesisBlock(url, new GetGenesisBlock.genesisBlockListener() {
@Override
public void genesisBlock(String value) {
if(cryptoCoin.getParameters()!= null){
if(value.equals(cryptoCoin.getParameters().getGenesisBlock().getHashAsString())){
CryptoNetManager.verifiedCryptoNetURL(cryptoCoin.getCryptoNet(), url, System.currentTimeMillis() - startTime);
}else{
System.out.println("BitcoinCryptoNetVerifier bad genesis block " + value + " " + url);
}
//TODO bad genesis block
}else{
CryptoNetManager.verifiedCryptoNetURL(cryptoCoin.getCryptoNet(), url, System.currentTimeMillis() - startTime);
}
}
@Override
public void fail() {
//TODO failed
}
});
}
@Override
public String getChainId() {
if(cryptoCoin == null || cryptoCoin.getParameters()== null) {
return null;
}
return cryptoCoin.getParameters().getGenesisBlock().getHashAsString();
}
}

View file

@ -32,6 +32,7 @@ public abstract class CryptoNetManager {
public static String getURL(CryptoNet crypto, int index){ public static String getURL(CryptoNet crypto, int index){
if(TestedURLs.containsKey(crypto) && TestedURLs.get(crypto).size()>index){ if(TestedURLs.containsKey(crypto) && TestedURLs.get(crypto).size()>index){
System.out.println("Servers url list " + Arrays.toString(TestedURLs.get(crypto).toArray()));
return TestedURLs.get(crypto).get(index).getUrl(); return TestedURLs.get(crypto).get(index).getUrl();
} }
System.out.println("Servers " + crypto.getLabel()+" dioesn't have testedurl"); System.out.println("Servers " + crypto.getLabel()+" dioesn't have testedurl");

View file

@ -1,6 +1,5 @@
package cy.agorise.crystalwallet.network; package cy.agorise.crystalwallet.network;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet; import cy.agorise.crystalwallet.enums.CryptoNet;
/** /**
@ -16,10 +15,6 @@ public abstract class CryptoNetVerifier {
static CryptoNetVerifier getNetworkVerify(CryptoNet cryptoNet){ static CryptoNetVerifier getNetworkVerify(CryptoNet cryptoNet){
if(cryptoNet.getLabel().equals(CryptoNet.BITSHARES.getLabel())){ if(cryptoNet.getLabel().equals(CryptoNet.BITSHARES.getLabel())){
return new BitsharesCryptoNetVerifier(); return new BitsharesCryptoNetVerifier();
}else if(cryptoNet.getLabel().equals(CryptoNet.BITCOIN.getLabel())){
return new BitcoinCryptoNetVerifier(CryptoCoin.BITCOIN);
}else if(cryptoNet.getLabel().equals(CryptoNet.STEEM.getLabel())){
return new SteemCryptoNetVerifier();
} }
return null; return null;
} }

View file

@ -38,6 +38,7 @@ public class GetChainId extends BaseGrapheneHandler {
@Override @Override
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception { public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
System.out.println("<<< "+frame.getPayloadText());
String response = frame.getPayloadText(); String response = frame.getPayloadText();
Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType(); Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType();
@ -54,5 +55,7 @@ public class GetChainId extends BaseGrapheneHandler {
@Override @Override
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception { public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
if(frame.isTextFrame())
System.out.println(">>> "+frame.getPayloadText());
} }
} }

View file

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

View file

@ -1,49 +0,0 @@
package cy.agorise.crystalwallet.network;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.WitnessResponse;
/**
*
* Created by henry on 28/2/2018.
*/
public class SteemCryptoNetVerifier extends CryptoNetVerifier {
private final CryptoNet cryptoNet = CryptoNet.STEEM;
private final String CHAIN_ID = "0000000000000000000000000000000000000000000000000000000000000000";//mainnet
@Override
public void checkURL(final String url) {
final long startTime = System.currentTimeMillis();
WebSocketThread thread = new WebSocketThread(new GetChainId(new WitnessResponseListener() {
@Override
public void onSuccess(WitnessResponse response) {
if(response.result instanceof GetDatabaseVersion.VersionResponse) {
GetDatabaseVersion.VersionResponse result = (GetDatabaseVersion.VersionResponse) response.result;
if(result.chain_id.equals(CHAIN_ID)) {
CryptoNetManager.verifiedCryptoNetURL(cryptoNet, url, System.currentTimeMillis() - startTime);
}else{
System.out.println(" BitsharesCryptoNetVerifier Error we are not in the net current chain id " + result.chain_id + " excepted " + CHAIN_ID);
//TODO handle error bad chain
}
}else{
//TODO handle error bad answer
}
}
@Override
public void onError(BaseResponse.Error error) {
//TODO handle error
System.out.println("Bad server response " + url);
}
}),url);
thread.start();
}
@Override
public String getChainId() {
return CHAIN_ID;
}
}

View file

@ -1,85 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount;
/**
* Class used to make a bitcoin uri parse request.
*
* Created by henry on 11/13/2018.
*/
public class BitcoinUriParseRequest extends CryptoNetInfoRequest {
/**
* The status code of this request
*/
public enum StatusCode{
NOT_STARTED,
VALID,
NOT_VALID
}
private String uri;
private String address;
private Double amount;
private String memo;
private StatusCode status = StatusCode.NOT_STARTED;
public BitcoinUriParseRequest(String uri, CryptoCoin cryptoCoin) {
super(cryptoCoin);
this.address = "";
this.amount = -1.0;
this.memo = "";
this.uri = uri;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public void validate(){
if ((this.status != StatusCode.NOT_STARTED)){
this._fireOnCarryOutEvent();
}
}
public void setStatus(StatusCode code){
this.status = code;
this._fireOnCarryOutEvent();
}
public StatusCode getStatus() {
return status;
}
public String getUri() {
return uri;
}
}

View file

@ -1,76 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
/**
* This class validates that an account name exist, this can be used to verified the existing accounts
* or to verified if the name is available to create an Account
*
* Created by henry on 8/10/2017.
*/
public class CalculateBitcoinUriRequest extends CryptoNetInfoRequest {
private CryptoNetAccount account;
private CryptoCurrency currency;
private double amount;
private Context context;
private String uri;
public CalculateBitcoinUriRequest(CryptoCoin coin, CryptoNetAccount account, Context context) {
super(coin);
this.account = account;
this.context = context;
}
public CalculateBitcoinUriRequest(CryptoCoin coin, CryptoNetAccount account, Context context, double amount) {
super(coin);
this.account = account;
this.context = context;
this.amount = amount;
}
public CalculateBitcoinUriRequest(CryptoCoin coin, CryptoNetAccount account, CryptoCurrency currency, double amount, Context context) {
super(coin);
this.account = account;
this.currency = currency;
this.amount = amount;
this.context = context;
}
public CryptoNetAccount getAccount() {
return account;
}
public CryptoCurrency getCurrency() {
return currency;
}
public double getAmount() {
return amount;
}
public Context getContext() {
return context;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
this.validate();
}
public void validate(){
if ((this.uri != null)){
this._fireOnCarryOutEvent();
}
}
}

View file

@ -1,69 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import java.util.List;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.GrapheneAccount;
/**
* Creates bitcoin accounts using a seed,
*
* Created by Henry Varona on 10/22/2018.
*/
public class CreateBitcoinAccountRequest extends CryptoNetInfoRequest {
private AccountSeed accountSeed;
private CryptoNet accountCryptoNet;
private Context context;
/**
* The status code of this request
*/
public enum StatusCode{
NOT_STARTED,
SUCCEEDED,
ACCOUNT_EXIST
}
// The state of this request
private StatusCode status = StatusCode.NOT_STARTED;
public CreateBitcoinAccountRequest(AccountSeed accountSeed, Context context, CryptoCoin cryptoCoin){
super(cryptoCoin);
this.accountSeed = accountSeed;
this.accountCryptoNet = cryptoCoin.getCryptoNet();
this.context = context;
}
public AccountSeed getAccountSeed() {
return this.accountSeed;
}
public void validate(){
if(!status.equals(StatusCode.NOT_STARTED))
this._fireOnCarryOutEvent();
}
public CryptoNet getAccountCryptoNet() {
return this.accountCryptoNet;
}
public Context getContext() {
return context;
}
public void setStatus(StatusCode code){
this.status = code;
this.validate();
}
public StatusCode getStatus() {
return status;
}
}

View file

@ -21,6 +21,13 @@ public abstract class CryptoNetInfoRequest {
*/ */
protected CryptoNetInfoRequestListener listener; protected CryptoNetInfoRequestListener listener;
protected CryptoNetInfoRequest(CryptoCoin coin){ protected CryptoNetInfoRequest(CryptoCoin coin){
this.coin = coin; this.coin = coin;
} }
@ -36,7 +43,4 @@ public abstract class CryptoNetInfoRequest {
CryptoNetInfoRequests.getInstance().removeRequest(this); CryptoNetInfoRequests.getInstance().removeRequest(this);
} }
public CryptoCoin getCoin() {
return coin;
}
} }

View file

@ -3,16 +3,9 @@ package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context; import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin; import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.CryptoNetAccount; import cy.agorise.crystalwallet.models.GeneralCoinAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount;
/** public class GeneralAccountSendRequest extends CryptoNetInfoRequest {
* Class used to make a send amount request.
*
* Created by henry on 8/10/2017.
*/
public class BitcoinSendRequest extends CryptoNetInfoRequest {
/** /**
* The status code of this request * The status code of this request
*/ */
@ -21,48 +14,45 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
SUCCEEDED, SUCCEEDED,
NO_INTERNET, NO_INTERNET,
NO_SERVER_CONNECTION, NO_SERVER_CONNECTION,
NO_BALANCE, BAD_TO_ADDRESS,
NO_FEE, NO_FEE,
NO_BALANCE,
PETITION_FAILED PETITION_FAILED
} }
// The app context // The app context
private Context mContext; private Context mContext;
// The source account used to transfer fund from //The soruce Account
private CryptoNetAccount mSourceAccount; private GeneralCoinAccount mAccount;
// The destination account id // The destination account address
private String mToAccount; private String mToAccount;
// The amount of the transaction // The amount of the transaction
private long mAmount; private long mAmount;
// The asset id of the transaction
private CryptoCoin mCryptoCoin;
// The memo, can be null // The memo, can be null
private String mMemo; private String mMemo;
// The state of this request // The state of this request
private StatusCode status = StatusCode.NOT_STARTED; private StatusCode status = StatusCode.NOT_STARTED;
public BitcoinSendRequest(Context context, CryptoNetAccount sourceAccount, public GeneralAccountSendRequest(CryptoCoin coin, Context context, GeneralCoinAccount account, String toAccount, long amount, String memo) {
String toAccount, long amount, CryptoCoin cryptoCoin, String memo) { super(coin);
super(cryptoCoin);
this.mContext = context; this.mContext = context;
this.mSourceAccount = sourceAccount; this.mAccount = account;
this.mToAccount = toAccount; this.mToAccount = toAccount;
this.mAmount = amount; this.mAmount = amount;
this.mCryptoCoin = cryptoCoin;
this.mMemo = memo; this.mMemo = memo;
} }
public BitcoinSendRequest(Context context, GrapheneAccount sourceAccount, public GeneralAccountSendRequest(CryptoCoin coin, Context context, GeneralCoinAccount account, String toAccount, long amount) {
String toAccount, long amount, CryptoCoin cryptoCoin) { this(coin,context,account,toAccount,amount,null);
this(context, sourceAccount,toAccount,amount,cryptoCoin,null);
} }
public Context getContext() { public Context getContext() {
return mContext; return mContext;
} }
public CryptoNetAccount getSourceAccount() { public GeneralCoinAccount getAccount() {
return mSourceAccount; return mAccount;
} }
public String getToAccount() { public String getToAccount() {
@ -73,10 +63,6 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
return mAmount; return mAmount;
} }
public CryptoCoin getCryptoCoin() {
return mCryptoCoin;
}
public String getMemo() { public String getMemo() {
return mMemo; return mMemo;
} }
@ -89,10 +75,11 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
public void setStatus(StatusCode code){ public void setStatus(StatusCode code){
this.status = code; this.status = code;
this.validate(); this._fireOnCarryOutEvent();
} }
public StatusCode getStatus() { public StatusCode getStatus() {
return status; return status;
} }
} }

View file

@ -1,90 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.SeedType;
/**
* Imports a bitshares accounts,
*
* return true if the account exist, and the mnemonic (brainkey provide is for that account
* Created by Henry Varona on 10/24/2018.
*/
public class ImportBitsharesAccountRequest extends CryptoNetInfoRequest {
/**
* The status code of this request
*/
public enum StatusCode{
NOT_STARTED,
SUCCEEDED,
NO_INTERNET,
NO_SERVER_CONNECTION,
ACCOUNT_DOESNT_EXIST,
BAD_SEED,
NO_ACCOUNT_DATA,
PETITION_FAILED
}
/**
* The mnemonic words
*/
private final String mnemonic;
/**
* If this seed is BIP39 or Brainkey
*/
private SeedType seedType;
/**
* The status of this request
*/
private StatusCode status = StatusCode.NOT_STARTED;
private Context context;
public ImportBitsharesAccountRequest(String mnemonic, Context context){
super(CryptoCoin.BITSHARES);
this.mnemonic = mnemonic;
this.context = context;
}
public ImportBitsharesAccountRequest(String mnemonic, Context context, boolean addAccountIfValid){
super(CryptoCoin.BITSHARES);
this.mnemonic = mnemonic;
this.context = context;
}
public void validate(){
if (!(this.status.equals(StatusCode.NOT_STARTED))){
this._fireOnCarryOutEvent();
}
}
public String getMnemonic() {
return mnemonic;
}
public SeedType getSeedType() {
return seedType;
}
public Context getContext() {
return context;
}
public void setSeedType(SeedType seedType) {
this.seedType = seedType;
}
public void setStatus(StatusCode status) {
this.status = status;
this._fireOnCarryOutEvent();
}
public StatusCode getStatus() {
return status;
}
}

View file

@ -1,75 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
/**
* Ask for the next address of a bitcoin alike account
*
* Created by Henry Varona on 10/22/2018.
*/
public class NextBitcoinAccountAddressRequest extends CryptoNetInfoRequest {
private CryptoNetAccount account;
private CryptoCoin cryptoCoin;
private Context context;
private String address = null;
/**
* The status code of this request
*/
public enum StatusCode{
NOT_STARTED,
SUCCEEDED
}
// The state of this request
private StatusCode status = StatusCode.NOT_STARTED;
public NextBitcoinAccountAddressRequest(CryptoNetAccount account, CryptoCoin cryptoCoin, Context context){
super(cryptoCoin);
this.account = account;
this.cryptoCoin = cryptoCoin;
this.context = context;
}
public CryptoNetAccount getAccount() {
return this.account;
}
public CryptoCoin getCryptoCoin() {
return this.cryptoCoin;
}
public void validate(){
if(!status.equals(StatusCode.NOT_STARTED))
this._fireOnCarryOutEvent();
}
public Context getContext() {
return context;
}
public void setStatus(StatusCode code){
this.status = code;
this.validate();
}
public StatusCode getStatus() {
return status;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View file

@ -1,42 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import cy.agorise.crystalwallet.enums.CryptoCoin;
/**
* This class validates that an account name exist, this can be used to verified the existing accounts
* or to verified if the name is available to create an Account
*
* Created by henry on 8/10/2017.
*/
public class ValidateBitcoinAddressRequest extends CryptoNetInfoRequest {
// The account name to validate
private String address;
// The result of the validation, or null if there isn't a response
private Boolean addressValid;
public ValidateBitcoinAddressRequest(CryptoCoin cryptoCoin, String address) {
super(cryptoCoin);
this.address = address;
}
public boolean getAddressValid(){
return this.addressValid;
}
public void setAddressValid(boolean value){
this.addressValid = value;
this.validate();
}
public void validate(){
if ((this.addressValid != null)){
this._fireOnCarryOutEvent();
}
}
public String getAddress() {
return address;
}
}

View file

@ -16,9 +16,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator; import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.manager.FileBackupManager; import cy.agorise.crystalwallet.manager.FileBackupManager;
import cy.agorise.crystalwallet.manager.GeneralAccountManager;
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache; import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests; import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.dao.CrystalDatabase;
@ -45,7 +43,6 @@ public class CrystalWalletService extends LifecycleService {
private Looper mServiceLooper; private Looper mServiceLooper;
private ServiceHandler mServiceHandler; private ServiceHandler mServiceHandler;
private BitsharesAccountManager bitsharesAccountManager; private BitsharesAccountManager bitsharesAccountManager;
private GeneralAccountManager generalAccountManager;
private Thread LoadAccountTransactionsThread; private Thread LoadAccountTransactionsThread;
private Thread LoadBitsharesAccountNamesThread; private Thread LoadBitsharesAccountNamesThread;
private EquivalencesThread LoadEquivalencesThread; private EquivalencesThread LoadEquivalencesThread;
@ -170,15 +167,7 @@ public class CrystalWalletService extends LifecycleService {
} }
}); });
final LiveData<List<CryptoNetAccount>> cryptoNetAccountList = db.cryptoNetAccountDao().getAllBitcoins();
cryptoNetAccountList.observe(this, new Observer<List<CryptoNetAccount>>() {
@Override
public void onChanged(@Nullable List<CryptoNetAccount> cryptoNetAccounts) {
for(CryptoNetAccount nextCryptoNetAccount : cryptoNetAccounts) {
generalAccountManager.loadAccountFromDB(nextCryptoNetAccount,thisService);
}
}
});
/*while(this.keepLoadingAccountTransactions){ /*while(this.keepLoadingAccountTransactions){
try{ try{
@ -199,13 +188,11 @@ public class CrystalWalletService extends LifecycleService {
this.cryptoNetInfoRequests = CryptoNetInfoRequests.getInstance(); this.cryptoNetInfoRequests = CryptoNetInfoRequests.getInstance();
this.fileServiceRequests = FileServiceRequests.getInstance(); this.fileServiceRequests = FileServiceRequests.getInstance();
this.bitsharesAccountManager = new BitsharesAccountManager(); this.bitsharesAccountManager = new BitsharesAccountManager();
this.generalAccountManager = new GeneralAccountManager(CryptoCoin.BITCOIN,this.getApplicationContext());
this.fileBackupManager = new FileBackupManager(); this.fileBackupManager = new FileBackupManager();
//Add the managers as listeners of the CryptoNetInfoRequest so //Add the managers as listeners of the CryptoNetInfoRequest so
//they can carry out the info requests from the ui //they can carry out the info requests from the ui
this.cryptoNetInfoRequests.addListener(this.bitsharesAccountManager); this.cryptoNetInfoRequests.addListener(this.bitsharesAccountManager);
this.cryptoNetInfoRequests.addListener(this.generalAccountManager);
this.fileServiceRequests.addListener(this.fileBackupManager); this.fileServiceRequests.addListener(this.fileBackupManager);
} }

View file

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

View file

@ -0,0 +1,47 @@
package cy.agorise.crystalwallet.util;
/**
* Created by Henry Varona on 25/2/2018.
*/
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.squareup.picasso.Transformation;
public class CircleTransformation implements Transformation {
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
@Override
public String key() {
return "CircleTransformation";
}
}

View file

@ -1,13 +0,0 @@
package cy.agorise.crystalwallet.util;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
/**
* This function is used to generate a local Glide API accessible by a GlideApp call
* which makes it easier to use more advanced Glide methods.
* {more information - https://bumptech.github.io/glide/doc/generatedapi.html}
*/
@GlideModule
public class MyAppGlideModule extends AppGlideModule {}

View file

@ -0,0 +1,33 @@
package cy.agorise.crystalwallet.util;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
/**
* Created by xd on 1/24/18.
* ImageView which adjusts its size to always create a square
*/
public class SquaredImageView extends AppCompatImageView {
public SquaredImageView(Context context) {
super(context);
}
public SquaredImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SquaredImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(size, size);
}
}

View file

@ -9,6 +9,7 @@ import android.arch.paging.PagedList;
import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoNet; import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.Contact; import cy.agorise.crystalwallet.models.Contact;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
/** /**
* Created by Henry Varona on 1/17/2018. * Created by Henry Varona on 1/17/2018.

View file

@ -3,12 +3,19 @@ package cy.agorise.crystalwallet.viewmodels;
import android.app.Application; import android.app.Application;
import android.arch.lifecycle.AndroidViewModel; import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import android.arch.paging.DataSource; import android.arch.paging.DataSource;
import android.arch.paging.LivePagedListBuilder; import android.arch.paging.LivePagedListBuilder;
import android.arch.paging.LivePagedListProvider;
import android.arch.paging.PagedList; import android.arch.paging.PagedList;
import android.content.Context;
import java.util.List;
import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended; import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended;
import cy.agorise.crystalwallet.views.TransactionListView;
/** /**
* Created by Henry Varona on 12/9/2017. * Created by Henry Varona on 12/9/2017.

View file

@ -18,7 +18,7 @@ public class ImportSeedValidator extends UIValidator {
super(context); super(context);
this.addField(new PinValidationField(pinEdit)); this.addField(new PinValidationField(pinEdit));
this.addField(new PinConfirmationValidationField(pinEdit,pinConfirmationEdit)); this.addField(new PinConfirmationValidationField(pinEdit,pinConfirmationEdit));
//this.addField(new BitsharesAccountNameValidationField(bitsharesAccountNameEdit)); this.addField(new BitsharesAccountNameValidationField(bitsharesAccountNameEdit));
//this.addField(new BitsharesAccountMnemonicValidationField(mnemonicEdit,bitsharesAccountNameEdit)); this.addField(new BitsharesAccountMnemonicValidationField(mnemonicEdit,bitsharesAccountNameEdit));
} }
} }

View file

@ -22,7 +22,7 @@ public class SendTransactionValidator extends UIValidator {
private CryptoNetAccount account; private CryptoNetAccount account;
public SendTransactionValidator(Context context, CryptoNetAccount account, Spinner fromEdit, EditText toEdit, Spinner assetSpinner, EditText amountEdit, EditText memoEdit){ public SendTransactionValidator(Context context, CryptoNetAccount account, MaterialSpinner fromEdit, EditText toEdit, Spinner assetSpinner, EditText amountEdit, EditText memoEdit){
super(context); super(context);
this.account = account; this.account = account;
this.addField(new FromValidationField(fromEdit)); this.addField(new FromValidationField(fromEdit));

View file

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

View file

@ -5,8 +5,6 @@ import android.widget.Spinner;
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.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.CryptoCoinBalance; import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCurrency; import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount; import cy.agorise.crystalwallet.models.CryptoNetAccount;
@ -31,12 +29,7 @@ public class AmountValidationField extends ValidationField {
public void validate(){ public void validate(){
try { try {
final float newAmountValue = Float.parseFloat(amountField.getText().toString()); final float newAmountValue = Float.parseFloat(amountField.getText().toString());
final CryptoCurrency cryptoCurrency; final CryptoCurrency cryptoCurrency = (CryptoCurrency)assetSpinner.getSelectedItem();
if(this.account.getCryptoNet() == CryptoNet.BITSHARES) {
cryptoCurrency = (CryptoCurrency) assetSpinner.getSelectedItem();
}else{
cryptoCurrency = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCurrencyDao().getByNameAndCryptoNet(CryptoCoin.getByCryptoNet(this.account.getCryptoNet()).get(0).getLabel(),this.account.getCryptoNet().name());
}
/* /*
* Validation for the money * Validation for the money
@ -55,12 +48,7 @@ public class AmountValidationField extends ValidationField {
CryptoCoinBalance balance = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCoinBalanceDao().getBalanceFromAccount(this.account.getId(),cryptoCurrency.getId()); CryptoCoinBalance balance = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCoinBalanceDao().getBalanceFromAccount(this.account.getId(),cryptoCurrency.getId());
double balanceDouble = 0; if (newAmountValue > balance.getBalance()){
if(balance != null){
balanceDouble = balance.getBalance();
}
if (newAmountValue > balanceDouble){
setMessageForValue(mixedValues, validator.getContext().getResources().getString(R.string.insufficient_amount)); setMessageForValue(mixedValues, validator.getContext().getResources().getString(R.string.insufficient_amount));
setValidForValue(mixedValues, false); setValidForValue(mixedValues, false);
} else if (newAmountValue == 0){ } else if (newAmountValue == 0){
@ -73,8 +61,6 @@ public class AmountValidationField extends ValidationField {
setLastValue(""); setLastValue("");
setMessageForValue("",validator.getContext().getResources().getString(R.string.please_enter_valid_amount)); setMessageForValue("",validator.getContext().getResources().getString(R.string.please_enter_valid_amount));
setValidForValue("", false); setValidForValue("", false);
} catch (Exception e ){
e.printStackTrace();
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show more