Compare commits

..

1 Commits

Author SHA1 Message Date
Agorise ba8769f266
Update LICENSE 2019-01-01 10:41:29 -06:00
261 changed files with 3537 additions and 8366 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018 AGORISE, LTD.
Copyright (c) 2019 AGORISE, LTD.
An International Business Company, Cyprus Reg# ΗΕ375959
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: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' // add this line
kapt {
generateStubs = true
@ -11,21 +9,15 @@ kapt {
}
}
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
maven { url "https://jitpack.io" }
}
android {
compileSdkVersion 28
compileSdkVersion 27
defaultConfig {
applicationId "cy.agorise.crystalwallet"
minSdkVersion 21
targetSdkVersion 28
versionCode 5
versionName "0.5M.alpha"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
targetSdkVersion 27
versionCode 3
versionName "0.3M.alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
@ -36,9 +28,6 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
resValue("string", "PORT_NUMBER", "8081")
}
}
productFlavors {
@ -55,59 +44,59 @@ android {
exclude 'lib/x86_64/freebsd/libscrypt.so'
exclude 'lib/x86_64/linux/libscrypt.so'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
def lifecycle_version = "2.0.0"
def room_version = "2.1.0-alpha02"
def paging_version = "2.1.0-beta01"
implementation fileTree(dir: 'libs', include: ['*.jar'])
//androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.1-alpha01', {
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
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 "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha01'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.1.60"
//testCompile 'com.android.support.test:runner:1.0.1'
implementation 'com.afollestad.material-dialogs:core:0.9.6.0' //DTVV Thrusday 31 July 2018
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.github.bumptech.glide:glide:4.7.1'
// Glide v4 uses this new annotation processor -- see https://bumptech.github.io/glide/doc/generatedapi.html
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
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:extensions:1.1.1'
implementation 'android.arch.paging:runtime:1.0.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:converter-gson:2.1.0'
implementation 'org.bitcoinj:bitcoinj-core:0.14.3'
implementation 'com.neovisionaries:nv-websocket-client:1.30'
implementation 'org.tukaani:xz:1.6'
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.github.bilthon:graphenej:0.4.6'
implementation 'com.google.zxing:core:3.3.1'
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
// Fix errors related to AndroidX and ButterKnife incompatibility
implementation 'com.jakewharton:butterknife:9.0.0-SNAPSHOT'
kapt 'com.jakewharton:butterknife-compiler:9.0.0-SNAPSHOT'
implementation 'com.github.sjaramillo10:AnimatedTabLayout:1.1.0'
implementation 'com.github.sjaramillo10:AnimatedTabLayout:1.0.3'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
//testCompile 'junit:junit: 4.12'
testImplementation 'org.mockito:mockito-core:1.10.19'
implementation 'android.arch.persistence.room:runtime:1.1.0'
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.paging:paging-runtime:$paging_version"
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'
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'
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 'id.zelory:compressor:2.1.0'
implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.7'
@ -119,18 +108,6 @@ dependencies {
exclude group: 'org.json', module: 'json'
}
// Glide dependencies
implementation 'com.github.bumptech.glide:glide:4.8.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'
testImplementation 'org.mockito:mockito-core:2.19.0'
//testCompile 'junit:junit: 4.12'
//testCompile 'com.android.support.test:runner:1.0.1'
kapt "android.arch.lifecycle:compiler:1.1.1"
kapt "android.arch.persistence.room:compiler:1.1.0"
}

View File

@ -23,10 +23,3 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-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

@ -1,8 +1,8 @@
package cy.agorise.crystalwallet.Assertions;
import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.ViewAssertion;
import androidx.recyclerview.widget.RecyclerView;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.ViewAssertion;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import static org.hamcrest.MatcherAssert.assertThat;

View File

@ -6,19 +6,20 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import java.util.List;
import cy.agorise.crystalwallet.Assertions.RecyclerViewItemsCountAssertion;
import cy.agorise.crystalwallet.activities.IntroActivity;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
/**

View File

@ -7,7 +7,6 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:name=".application.CrystalApplication"
@ -40,10 +39,6 @@
</activity>
<activity android:name=".activities.AccountSeedsManagementActivity" >
</activity>
<activity android:name=".activities.AccountSeedSettingsActivity"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan">
</activity>
<activity android:name=".activities.ImportSeedActivity" >
</activity>
<activity android:name=".activities.SendTransactionActivity" >

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -1,130 +0,0 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.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.GeneralAccountSeedCoinSettingsFragment;
import cy.agorise.crystalwallet.fragments.GeneralAccountSeedFragment;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
/**
* 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

@ -1,11 +1,11 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import java.util.List;
@ -14,6 +14,7 @@ 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.viewmodels.AccountSeedListViewModel;
import cy.agorise.crystalwallet.views.AccountSeedListView;

View File

@ -1,20 +1,19 @@
package cy.agorise.crystalwallet.activities;
import android.media.MediaPlayer;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
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.view.SurfaceHolder;
import android.view.SurfaceView;
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;
@ -38,13 +37,12 @@ public class AccountSettingsActivity extends AppCompatActivity{
public SettingsPagerAdapter settingsPagerAdapter;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.tvBuildVersion)
public TextView tvBuildVersion;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -54,11 +52,27 @@ public class AccountSettingsActivity extends AppCompatActivity{
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);
// Appbar animation
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//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());
mPager.setAdapter(settingsPagerAdapter);

View File

@ -1,27 +1,32 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.app.Activity;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.FileObserver;
import androidx.annotation.Nullable;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.esafirm.imagepicker.features.ImagePicker;
import com.esafirm.imagepicker.model.Image;
import com.thekhaeng.pushdownanim.PushDownAnim;
//import com.nicdahlquist.pngquant.LibPngQuant;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
@ -29,13 +34,16 @@ import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountListViewModel;
import cy.agorise.crystalwallet.views.AccountSeedListView;
import cy.agorise.crystalwallet.views.CryptoNetAccountListView;
import de.hdodenhof.circleimageview.CircleImageView;
import id.zelory.compressor.Compressor;
/**
* Created by Seven on 1/9/18.
* Created by xd on 1/9/18.
*
*/
@ -47,11 +55,8 @@ public class AccountsActivity extends AppCompatActivity {
@BindView(R.id.tvClose)
TextView tvClose;
//@BindView(R.id.vAccountList)
//CryptoNetAccountListView vAccountList;
@BindView(R.id.vAccountSeedList)
AccountSeedListView vAccountSeedList;
@BindView(R.id.vAccountList)
CryptoNetAccountListView vAccountList;
@BindView(R.id.user_img)
CircleImageView userImg;
@ -69,29 +74,14 @@ public class AccountsActivity extends AppCompatActivity {
setContentView(R.layout.activity_accounts);
ButterKnife.bind(this);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(fabAddAccount)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
goToAddAccount();
}
CryptoNetAccountListViewModel crytpoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
LiveData<List<CryptoNetAccount>> accountData = crytpoNetAccountListViewModel.getCryptoNetAccounts();
vAccountList.setData(null);
} );
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>>() {
accountData.observe(this, new Observer<List<CryptoNetAccount>>() {
@Override
public void onChanged(List<AccountSeed> accountsSeeds) {
vAccountSeedList.setData(accountsSeeds);
public void onChanged(List<CryptoNetAccount> cryptoNetAccounts) {
vAccountList.setData(cryptoNetAccounts);
}
});

View File

@ -1,27 +1,24 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
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.fragments.BackupsSettingsFragment;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
@ -32,12 +29,10 @@ public class BackupSeedActivity extends AppCompatActivity {
@BindView(R.id.tvBrainKey)
TextView textfieldBrainkey;
@BindView(R.id.btnOK)
@BindView(R.id.btnCancel)
Button btnOk;
@BindView(R.id.btnCopy)
Button btnCopy;
@BindView(R.id.btnCancel)
Button btnCancel;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -46,42 +41,6 @@ public class BackupSeedActivity extends AppCompatActivity {
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);
if (seedId > -1) {
@ -97,14 +56,6 @@ public class BackupSeedActivity extends AppCompatActivity {
accountSeedViewModel.loadSeed(seedId);
} 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();
}
}

View File

@ -1,26 +1,37 @@
package cy.agorise.crystalwallet.activities;
import android.app.ActivityOptions;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface;
import android.media.MediaPlayer;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.widget.Toolbar;
import android.support.design.widget.FloatingActionButton;
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.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
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.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
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.SendTransactionFragment;
import cy.agorise.crystalwallet.fragments.TransactionsFragment;
import cy.agorise.crystalwallet.views.natives.GIFView;
import de.hdodenhof.circleimageview.CircleImageView;
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
@ -61,8 +73,8 @@ public class BoardActivity extends CustomActivity {
@BindView(R.id.fabAddContact)
public FloatingActionButton fabAddContact;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@BindView(R.id.imagevieGIF)
public GIFView imagevieGIF;
public BoardPagerAdapter boardAdapter;
@ -72,6 +84,9 @@ public class BoardActivity extends CustomActivity {
*/
long cryptoNetAccountId;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.toolbar_user_img)
public CircleImageView userImage;
@ -95,11 +110,82 @@ public class BoardActivity extends CustomActivity {
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);
/*
* Set the bubbles animation
* */
//imagevieGIF.centerCrop();
//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());
mPager.setAdapter(boardAdapter);

View File

@ -1,15 +1,15 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.annotation.Nullable;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import androidx.appcompat.app.AppCompatActivity;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;

View File

@ -3,17 +3,18 @@ package cy.agorise.crystalwallet.activities
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.google.android.material.textfield.TextInputEditText
import android.text.Editable
import android.text.TextWatcher
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import com.thekhaeng.pushdownanim.PushDownAnim
import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.OnTextChanged
import com.vincent.filepicker.ToastUtil
import cy.agorise.crystalwallet.R
import cy.agorise.crystalwallet.dialogs.material.*
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests
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.validationFields.BitsharesAccountNameValidation
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation.OnAccountExist
@ -38,6 +39,11 @@ class CreateSeedActivity : CustomActivity() {
* */
setContentView(R.layout.create_seed)
/*
* Initialice butterknife MVC
* */
ButterKnife.bind(this)
/*
* Add the controls to the validator
* */
@ -45,14 +51,6 @@ class CreateSeedActivity : CustomActivity() {
this.fieldsValidator.add(tietPinConfirmation)
this.fieldsValidator.add(tietAccountName)
/*
* Integration of library with button effects
* */
PushDownAnim.setPushDownAnimTo(btnCancel)
.setOnClickListener { finish() }
PushDownAnim.setPushDownAnimTo(btnCreate)
.setOnClickListener { createSeed() }
/*
* 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)
// Listener for the validation for success or fail
/*
* Listener for the validation for success or fail
* */
tietPin?.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 onAccountExist = object : OnAccountExist {
override fun onAccountExists() {
@ -110,49 +114,58 @@ class CreateSeedActivity : CustomActivity() {
tietAccountName?.setUiValidator(bitsharesAccountNameValidation)
/*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()
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(tilPin, InputMethodManager.SHOW_IMPLICIT)
tietPin.afterTextChanged {
this.fieldsValidator.validate()
validateFieldsToContinue()
}
tietPinConfirmation.afterTextChanged {
this.fieldsValidator.validate()
validateFieldsToContinue()
}
tietAccountName.afterTextChanged {
this.fieldsValidator.validate()
validateFieldsToContinue()
}
btnCancel.setOnClickListener { finish() }
btnCreate.setOnClickListener { createSeed() }
}
/**
* 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) {
}
@OnTextChanged(value = R.id.tietPin, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
internal fun afterPinChanged(editable: Editable) {
this.fieldsValidator.validate()
/*
* Validate continue to create account
* */
validateFieldsToContinue()
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
})
}
@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()
}
@OnTextChanged(value = R.id.tietAccountName, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
internal fun afterAccountNameChanged(editable: Editable) {
this.fieldsValidator.validate()
/*
* Validate continue to create account
* */
validateFieldsToContinue()
}
@OnClick(R.id.btnCancel)
fun cancel() {
/*
* Exit of the activity
* */
this.finish()
}
@OnClick(R.id.btnCreate)
fun createSeed() {
/*
@ -168,10 +181,11 @@ class CreateSeedActivity : CustomActivity() {
questionDialog.setOnPositive(object : PositiveResponse{
override fun onPositive() {
// Make request to create a bitshares account
// Make request to create a bitshare account
var accountName:String = tietAccountName?.getText().toString().trim()
val request = ValidateCreateBitsharesAccountRequest(accountName, applicationContext)
//DTVV: Friday 27 July 2018
//Makes dialog to tell the user that the account is been created
val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
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)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intent.putExtra("SEED_ID", accountSeed.id)
intent.putExtra("newAccount", true)
startActivity(intent)
}
else if (request.status == ValidateCreateBitsharesAccountRequest.StatusCode.ACCOUNT_EXIST) {
ToastUtil.getInstance(globalActivity).showToast(globalActivity.getString(R.string.Account_already_exists))
btnCreate.isEnabled = false
disableCreate()
}
else {
fieldsValidator.validate()
@ -200,7 +213,10 @@ class CreateSeedActivity : CustomActivity() {
(object : Thread() {
override fun run() {
/* Run thread*/
/*
*
* Run thread*/
CryptoNetInfoRequests.getInstance().addRequest(request)
}
}).start()
@ -226,7 +242,85 @@ class CreateSeedActivity : CustomActivity() {
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

@ -1,12 +1,16 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.text.SimpleDateFormat;
import butterknife.BindView;
@ -43,7 +47,7 @@ public class CryptoCoinTransactionReceiptActivity extends AppCompatActivity {
if (this.cryptoCoinTransactionId != -1) {
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>() {
@Override

View File

@ -1,31 +1,32 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.media.MediaPlayer;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
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.view.SurfaceHolder;
import android.view.SurfaceView;
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.BackupsSettingsFragment;
import cy.agorise.crystalwallet.fragments.BitsharesSettingsFragment;
import cy.agorise.crystalwallet.fragments.GeneralCryptoNetAccountSettingsFragment;
import cy.agorise.crystalwallet.fragments.GeneralSettingsFragment;
import cy.agorise.crystalwallet.fragments.SecuritySettingsFragment;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
@ -44,6 +45,8 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
public SettingsPagerAdapter settingsPagerAdapter;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.tvBuildVersion)
public TextView tvBuildVersion;
@ -53,9 +56,6 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
private CryptoNetAccount cryptoNetAccount;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -93,11 +93,27 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
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);
// Appbar animation
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//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 {

View File

@ -2,7 +2,7 @@ package cy.agorise.crystalwallet.activities
import android.app.Activity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.support.v7.app.AppCompatActivity
import cy.agorise.crystalwallet.util.FieldsValidator
/*

View File

@ -1,13 +1,17 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import java.util.ArrayList;
import java.util.Collections;
@ -20,8 +24,14 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnItemSelected;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.models.GrapheneAccount;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.views.CryptoCurrencyAdapter;
public class GeneralSettingsActivity extends AppCompatActivity {

View File

@ -1,35 +1,34 @@
package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.thekhaeng.pushdownanim.PushDownAnim;
import org.jetbrains.annotations.NotNull;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dialogs.material.CrystalLoading;
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.enums.CryptoNet;
import cy.agorise.crystalwallet.enums.SeedType;
import cy.agorise.crystalwallet.manager.BitsharesAccountManager;
import cy.agorise.crystalwallet.models.AccountSeed;
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.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.CryptoNetAccountViewModel;
import cy.agorise.crystalwallet.viewmodels.GrapheneAccountInfoViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator;
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
@ -41,30 +40,23 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@BindView(R.id.etPin)
EditText etPin;
@BindView(R.id.txtErrorPIN)
TextView txtErrorPIN;
@BindView(R.id.txtErrorAccount)
TextView txtErrorAccount;
//@BindView(R.id.tvPinError)
//TextView tvPinError;
@BindView(R.id.tvPinError)
TextView tvPinError;
@BindView(R.id.etPinConfirmation)
EditText etPinConfirmation;
//@BindView(R.id.tvPinConfirmationError)
//TextView tvPinConfirmationError;
@BindView(R.id.tvPinConfirmationError)
TextView tvPinConfirmationError;
@BindView(R.id.etSeedWords)
EditText etSeedWords;
//@BindView(R.id.tvSeedWordsError)
//TextView tvSeedWordsError;
@BindView(R.id.tvSeedWordsError)
TextView tvSeedWordsError;
@BindView (R.id.etAccountName)
EditText etAccountName;
//@BindView(R.id.tvAccountNameError)
//TextView tvAccountNameError;
@BindView(R.id.tvAccountNameError)
TextView tvAccountNameError;
@BindView(R.id.btnImport)
Button btnImport;
@ -72,16 +64,6 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@BindView(R.id.btnCancel)
Button btnCancel;
final Activity activity = this;
/*
* Flag to check correct PIN equality
* */
private boolean pinsOK = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -89,213 +71,12 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
ButterKnife.bind(this);
/*
* 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();
}
}
});
*/
btnImport.setEnabled(false);
accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class);
importSeedValidator = new ImportSeedValidator(this.getApplicationContext(),etPin,etPinConfirmation,etAccountName,etSeedWords);
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,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterPinChanged(Editable editable) {
@ -313,11 +94,13 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
void afterSeedWordsChanged(Editable editable) {
this.importSeedValidator.validate();
}
/*@OnTextChanged(value = R.id.etAccountName,
@OnTextChanged(value = R.id.etAccountName,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterAccountNameChanged(Editable editable) {
this.importSeedValidator.validate();
}*/
}
@OnClick(R.id.btnCancel)
public void cancel(){
@ -330,142 +113,66 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
if (this.importSeedValidator.isValid()) {
/*
* Question if continue
* */
final QuestionDialog questionDialog = new QuestionDialog(activity);
questionDialog.setText(activity.getString(R.string.question_continue));
questionDialog.setOnNegative(new NegativeResponse() {
final ValidateImportBitsharesAccountRequest validatorRequest =
new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onNegative(@NotNull DialogMaterial dialogMaterial) {
}
});
questionDialog.setOnPositive(new PositiveResponse() {
@Override
public void onPositive() {
public void onCarryOut() {
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
String errorText = "An error ocurred attempting to import the account";
/*
* 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));
}
switch (validatorRequest.getStatus()){
case PETITION_FAILED:
case NO_INTERNET:
case NO_SERVER_CONNECTION:
errorText = "There was an error with the connection. Try again later";
break;
case ACCOUNT_DOESNT_EXIST:
errorText = "The account doesn't exists";
break;
case BAD_SEED:
errorText = "The seed is not valid";
break;
case NO_ACCOUNT_DATA:
errorText = "The account doesn't have any data";
break;
}
});
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() {
@Override
public void onCarryOut() {
/*
* Hide the loading dialog
* */
crystalLoading.dismiss();
if (!validatorRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
switch (validatorRequest.getStatus()){
case PETITION_FAILED:
case NO_INTERNET:
case NO_SERVER_CONNECTION:
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.NO_SERVER_CONNECTION));
}
});
break;
case ACCOUNT_DOESNT_EXIST:
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.ACCOUNT_DOESNT_EXIST));
}
});
break;
case BAD_SEED:
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.BAD_SEED));
}
});
break;
case NO_ACCOUNT_DATA:
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setText(activity.getResources().getString(R.string.NO_ACCOUNT_DATA));
}
});
break;
default:
txtErrorAccount.setText(activity.getResources().getString(R.string.ERROR_UNRECOGNIZABLE));
Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(thisActivity, BoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
txtErrorAccount.setVisibility(View.VISIBLE);
}
});
//Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(thisActivity, BoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
});
});
/*CryptoNetInfoRequests.getInstance().addRequest(validatorRequest);
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);
}
}
@Override
@ -476,19 +183,19 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
public void run() {
if (field.getView() == etPin) {
//tvPinError.setText("");
tvPinError.setText("");
} else if (field.getView() == etPinConfirmation){
//tvPinConfirmationError.setText("");
tvPinConfirmationError.setText("");
} else if (field.getView() == etAccountName){
//tvAccountNameError.setText("");
tvAccountNameError.setText("");
} else if (field.getView() == etSeedWords){
//tvSeedWordsError.setText("");
tvSeedWordsError.setText("");
}
if (activity.importSeedValidator.isValid()){
enableCreate();
btnImport.setEnabled(true);
} else {
disableCreate();
btnImport.setEnabled(false);
}
}
@ -498,40 +205,13 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@Override
public void onValidationFailed(ValidationField field) {
if (field.getView() == etPin) {
//tvPinError.setText(field.getMessage());
tvPinError.setText(field.getMessage());
} else if (field.getView() == etPinConfirmation){
//tvPinConfirmationError.setText(field.getMessage());
tvPinConfirmationError.setText(field.getMessage());
} else if (field.getView() == etAccountName){
//tvAccountNameError.setText(field.getMessage());
tvAccountNameError.setText(field.getMessage());
} 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

@ -1,44 +1,56 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
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.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.thekhaeng.pushdownanim.PushDownAnim;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
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.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.TransactionListViewModel;
import cy.agorise.crystalwallet.views.TransactionListView;
public class IntroActivity extends CustomActivity {
@BindView(R.id.ivAnimation)
ImageView ivAnimation;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.btnCreateAccount)
Button btnCreateAccount;
public Button btnCreateAccount;
@BindView(R.id.btnImportAccount)
Button btnImportAccount;
/*
* For the window animation
* */
// private MediaPlayer mediaPlayer;
public Button btnImportAccount;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -47,49 +59,50 @@ public class IntroActivity extends CustomActivity {
ButterKnife.bind(this);
Glide.with(this)
.load(R.drawable.appbar_background)
.apply(new RequestOptions().centerCrop())
.into(ivAnimation);
// Appbar animation
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//Log.d(TAG,"surfaceCreated");
MediaPlayer mediaPlayer = MediaPlayer.create(IntroActivity.this, R.raw.appbar_background);
mediaPlayer.setDisplay(mSurfaceView.getHolder());
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
/*
* Integration of library with button effects
* */
PushDownAnim.setPushDownAnimTo(btnCreateAccount)
.setOnClickListener( new View.OnClickListener(){
@Override
public void onClick( View view ){
createAccount();
}
} );
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));
//Checks if the user has any seed created
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);
if (accountSeedListViewModel.accountSeedsCount() == 0) {
//If the user doesn't have any seeds created, then
//send the user to create/import an account
//Intent intent = new Intent(this, AccountSeedsManagementActivity.class);
//Intent intent = new Intent(this, ImportSeedActivity.class);
//Intent intent = new Intent(this, CreateSeedActivity.class);
//startActivity(intent);
} else {
//Intent intent = new Intent(this, CreateSeedActivity.class);
Intent intent = new Intent(this, BoardActivity.class);
//Intent intent = new Intent(this, PocketRequestActivity.class);
startActivity(intent);
finish();
}
//Checks if the user has any seed created
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);
if (accountSeedListViewModel.accountSeedsCount() == 0) {
//If the user doesn't have any seeds created, then
//send the user to create/import an account
//Intent intent = new Intent(this, AccountSeedsManagementActivity.class);
//Intent intent = new Intent(this, ImportSeedActivity.class);
//Intent intent = new Intent(this, CreateSeedActivity.class);
//startActivity(intent);
} else {
//Intent intent = new Intent(this, CreateSeedActivity.class);
Intent intent = new Intent(this, BoardActivity.class);
//Intent intent = new Intent(this, PocketRequestActivity.class);
startActivity(intent);
finish();
}
/*CrystalDatabase db = CrystalDatabase.getAppDatabase(getApplicationContext());
List<AccountSeed> seeds = RandomSeedGenerator.generateSeeds(2);

View File

@ -2,36 +2,26 @@ package cy.agorise.crystalwallet.activities;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;
import android.widget.Button;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalApplication;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.network.CryptoNetManager;
public class LicenseActivity extends AppCompatActivity {
@BindView(R.id.wvEULA) WebView wvEULA;
@BindView(R.id.btnDisagree)
Button btnDisAgree;
@BindView(R.id.btnAgree)
Button btnAgree;
CrystalDatabase db;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -39,23 +29,10 @@ public class LicenseActivity extends AppCompatActivity {
ButterKnife.bind(this);
/*
* Integration of library with button efects
* */
PushDownAnim.setPushDownAnimTo(btnDisAgree)
.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();
}
} );
// TODO check if license has been agreed
String html = getString(R.string.licence_html);
wvEULA.loadData(html, "text/html", "UTF-8");
db = CrystalDatabase.getAppDatabase(this.getApplicationContext());
int licenseVersion = getResources().getInteger(R.integer.license_version);
@ -66,14 +43,6 @@ public class LicenseActivity extends AppCompatActivity {
startActivity(intent);
finish();
}
else{
/*
* Load the licence only if it is necesarry
* */
String html = getString(R.string.licence_html);
wvEULA.loadData(html, "text/html", "UTF-8");
}
}
@OnClick(R.id.btnAgree)
@ -91,7 +60,7 @@ public class LicenseActivity extends AppCompatActivity {
finish();
}
@OnClick(R.id.btnDisagree)
@OnClick(R.id.btnDisAgree)
public void onDisagree() {
finish();
}

View File

@ -1,62 +1,31 @@
package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.graphics.Color;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.widget.EditText;
import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
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.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
public class PatternRequestActivity extends AppCompatActivity {
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
public void onBackPressed() {
//Do nothing to prevent the user to use the back button
@ -65,15 +34,12 @@ public class PatternRequestActivity extends AppCompatActivity {
@BindView(R.id.patternLockView)
PatternLockView patternLockView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pattern_request);
ButterKnife.bind(this);
//onResponse = null;
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
@ -105,26 +71,13 @@ public class PatternRequestActivity extends AppCompatActivity {
public void onComplete(List<PatternLockView.Dot> pattern) {
if (PasswordManager.checkPassword(patternEncrypted,patternToString(pattern))){
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
//CrystalSecurityMonitor.getInstance(null).call2ndFactor(thisActivity);
thisActivity.finish();
/*if(onResponse != null){
onResponse.onSuccess();
}*/
CrystalSecurityMonitor.getInstance(null).call2ndFactor(thisActivity);
} else {
thisActivity.finish();
/*if(onResponse != null){
onResponse.onSuccess();
}*/
}
} else {
incorrect();
/*if(onResponse != null){
onResponse.onFailed();
}*/
patternLockView.clearPattern();
patternLockView.requestFocus();
}
}
@ -142,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){
String patternString = "";
for (PatternLockView.Dot nextDot : pattern){

View File

@ -1,30 +1,22 @@
package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.graphics.Color;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
@ -32,29 +24,6 @@ import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
public class PinRequestActivity extends AppCompatActivity {
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
public void onBackPressed() {
//Do nothing to prevent the user to use the back button
@ -69,13 +38,6 @@ public class PinRequestActivity extends AppCompatActivity {
setContentView(R.layout.activity_pin_request);
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);
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
generalSettingsLiveData.observe(this, new Observer<List<GeneralSetting>>() {
@ -97,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,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterPasswordChanged(Editable editable) {
/*
* If it is valid length enable button
* */
if(etPassword.getText().length()>=6){
btnOK.setEnabled(true);
}
else{
btnOK.setEnabled(false);
if (PasswordManager.checkPassword(passwordEncrypted, etPassword.getText().toString())) {
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
CrystalSecurityMonitor.getInstance(null).call2ndFactor(this);
} else {
this.finish();
}
}
}
}
}

View File

@ -1,9 +1,9 @@
package cy.agorise.crystalwallet.activities;
import android.app.PendingIntent;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
@ -12,20 +12,35 @@ import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NdefFormatable;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
import java.nio.ByteBuffer;
import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener;
import org.apache.commons.codec.binary.Base32;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.util.yubikey.Algorithm;
import cy.agorise.crystalwallet.util.yubikey.OathType;
import cy.agorise.crystalwallet.util.yubikey.TOTP;
import cy.agorise.crystalwallet.util.yubikey.YkOathApi;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
public class PocketRequestActivity extends AppCompatActivity {

View File

@ -1,10 +1,10 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import java.util.ArrayList;

View File

@ -1,17 +1,18 @@
package cy.agorise.crystalwallet.activities;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.appcompat.app.AppCompatActivity;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.jaredrummler.materialspinner.MaterialSpinner;
import java.util.ArrayList;
import java.util.List;
@ -37,7 +38,7 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
SendTransactionValidator sendTransactionValidator;
@BindView(R.id.spFrom)
Spinner spFrom;
MaterialSpinner spFrom;
@BindView(R.id.tvFromError)
TextView tvFromError;
@BindView(R.id.etTo)
@ -61,9 +62,6 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
//@BindView(R.id.btnCancel)
Button btnCancel;
@BindView(R.id.fabCloseCamera)
FloatingActionButton btnCloseCamera;
private long cryptoNetAccountId;
private CryptoNetAccount cryptoNetAccount;
private GrapheneAccount grapheneAccount;
@ -148,15 +146,6 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
this.finish();
}
@OnClick(R.id.fabCloseCamera)
public void onClicCloseCamera(){
}
//@OnClick(R.id.btnSend)
public void importSend(){
if (this.sendTransactionValidator.isValid()) {

View File

@ -1,19 +1,19 @@
package cy.agorise.crystalwallet.activities;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
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.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.sjaramillo10.animatedtablayout.AnimatedTabLayout;
import butterknife.BindView;
@ -42,15 +42,14 @@ public class SettingsActivity extends AppCompatActivity{
public SettingsPagerAdapter settingsPagerAdapter;
@BindView(R.id.surface_view)
public SurfaceView mSurfaceView;
@BindView(R.id.tvBuildVersion)
public TextView tvBuildVersion;
private SecuritySettingsFragment securitySettingsFragment;
@BindView(R.id.ivAppBarAnimation)
ImageView ivAppBarAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -60,11 +59,27 @@ public class SettingsActivity extends AppCompatActivity{
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);
// Appbar animation
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//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());
mPager.setAdapter(settingsPagerAdapter);

View File

@ -1,6 +1,7 @@
package cy.agorise.crystalwallet.apigenerator;
import android.content.Context;
import android.util.Log;
import java.io.Serializable;
import java.util.ArrayList;
@ -8,6 +9,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
import cy.agorise.crystalwallet.dao.BitsharesAssetDao;
import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao;
import cy.agorise.crystalwallet.dao.CryptoCurrencyDao;
@ -80,32 +82,13 @@ public abstract class GrapheneApiGenerator {
*/
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
*
* @param accountId The accountId to retrieve
* @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,
new WitnessResponseListener() {
@Override
@ -126,7 +109,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -136,37 +119,25 @@ public abstract class GrapheneApiGenerator {
* @param address The address to retrieve
* @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,
new WitnessResponseListener() {
@Override
public void onSuccess(WitnessResponse response) {
try {
final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result;
if (resp.size() > 0) {
List<UserAccount> accounts = resp.get(0);
if (accounts.size() > 0) {
for (UserAccount account : accounts) {
request.getListener().success(account, request.getId());
break;
}
}else{
request.getListener().fail(request.getId());
}
} else {
request.getListener().fail(request.getId());
}
}catch(Exception e){
e.printStackTrace();
request.getListener().fail(request.getId());
}
final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result;
if(resp.size() > 0){
List<UserAccount> accounts = resp.get(0);
if(accounts.size() > 0){
for(UserAccount account : accounts) {
request.getListener().success(account,request.getId());}}}
request.getListener().fail(request.getId());
}
@Override
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -181,7 +152,7 @@ public abstract class GrapheneApiGenerator {
* @param request The Api request object, to answer this petition
*/
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),
start, limit, stop, new WitnessResponseListener() {
@Override
@ -193,7 +164,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -203,7 +174,7 @@ public abstract class GrapheneApiGenerator {
* @param accountName The account Name to find
* @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,
new WitnessResponseListener() {
@Override
@ -220,7 +191,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -230,7 +201,7 @@ public abstract class GrapheneApiGenerator {
* @param accountName The account Name to find
* @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,
new WitnessResponseListener() {
@Override
@ -247,7 +218,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -281,7 +252,7 @@ public abstract class GrapheneApiGenerator {
* @param assetNames The list of the names of the assets to be retrieve
* @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,
new WitnessResponseListener() {
@ -316,7 +287,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -325,7 +296,7 @@ public abstract class GrapheneApiGenerator {
* @param assetIds The list of the ids to retrieve
* @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<>();
for(String assetId : assetIds){
Asset asset = new Asset(assetId);
@ -364,7 +335,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -398,7 +369,7 @@ public abstract class GrapheneApiGenerator {
if(operation instanceof TransferOperation){
final TransferOperation tOperation = (TransferOperation) operation;
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();
transaction.setAccountId(accountId);
transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue());
@ -436,7 +407,7 @@ public abstract class GrapheneApiGenerator {
});
ArrayList<String> assets = new ArrayList<>();
assets.add(tOperation.getAssetAmount().getAsset().getObjectId());
GrapheneApiGenerator.getAssetById(assets,CryptoNet.BITSHARES,assetRequest);
GrapheneApiGenerator.getAssetById(assets,assetRequest);
}else{
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
* @param transaction The transaction db object
@ -592,7 +470,7 @@ public abstract class GrapheneApiGenerator {
* @param context The android context of this application
*/
public static void getAccountBalance(final long accountId, final String accountGrapheneId,
final CryptoNet cryptoNet, final Context context){
final Context context){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final CryptoCoinBalanceDao balanceDao = db.cryptoCoinBalanceDao();
@ -638,7 +516,7 @@ public abstract class GrapheneApiGenerator {
public void fail(int idPetition) {
}
});
getAssetById(idAssets,cryptoNet,getAssetRequest);
getAssetById(idAssets,getAssetRequest);
}else {
@ -652,7 +530,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
@ -664,7 +542,7 @@ public abstract class GrapheneApiGenerator {
* @param blockHeader The block header to retrieve the date time
* @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() {
@Override
public void onSuccess(WitnessResponse response) {
@ -679,7 +557,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId());
}
}),CryptoNetManager.getURL(cryptoNet));
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start();
}
@ -747,7 +625,7 @@ public abstract class GrapheneApiGenerator {
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName,CryptoNet.BITSHARES.name());
CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName);
BitsharesAssetInfo info = null;
if(baseCurrency != null){
info = db.bitsharesAssetDao().getBitsharesAssetInfo(baseCurrency.getId());
@ -782,7 +660,7 @@ public abstract class GrapheneApiGenerator {
});
ArrayList<String> names = new ArrayList<>();
names.add(baseAssetName);
GrapheneApiGenerator.getAssetByName(names,CryptoNet.BITSHARES,getAssetRequest);
GrapheneApiGenerator.getAssetByName(names,getAssetRequest);
}else {
BitsharesAsset baseAsset = new BitsharesAsset(baseCurrency);

View File

@ -1,81 +1,49 @@
package cy.agorise.crystalwallet.apigenerator;
import android.content.Context;
import java.util.HashMap;
import cy.agorise.crystalwallet.apigenerator.insightapi.AddressesActivityWatcher;
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
import cy.agorise.crystalwallet.apigenerator.insightapi.GetEstimateFee;
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;
public class InsightApiGenerator {
private static HashMap<CryptoCoin,GetTransactionByAddress> transactionGetters = new HashMap();
private static HashMap<CryptoCoin,AddressesActivityWatcher> transactionFollowers = new HashMap();
private static HashMap<CryptoNet,BroadcastTransaction> broadcaster = new HashMap();
private static HashMap<CryptoNet,GetTransactionByAddress> transactionGetters = new HashMap();
private static HashMap<CryptoNet,GetTransactionData> transacitonFollowers = new HashMap();
private static final String PATH = "api";
/**
* Fecth all the transaciton for a giving address
* @param cryptoCoin the crypto net of the address
* @param address The address String
* @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));
public static void getTransactionFromAddress(CryptoNet cryptoNet, String address,
ApiRequest request, Context context,
boolean subscribe){
if(!transactionGetters.containsKey(cryptoNet)){
//TODO change this line
transactionGetters.put(cryptoNet,new GetTransactionByAddress(null,CryptoNetManager.getURL(cryptoNet),context));
}
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();
}
}
/**
* Broadcast an insight api transaction
* @param cryptoCoin The cryptoNet of the transaction
* @param rawtx the transaction to be broadcasted
*/
public static void broadcastTransaction(CryptoCoin cryptoCoin, String rawtx, final ApiRequest request){
BroadcastTransaction bTransaction = new BroadcastTransaction(rawtx,
CryptoNetManager.getURL(cryptoCoin.getCryptoNet()), PATH, new BroadcastTransaction.BroadCastTransactionListener() {
public static void getEstimateFee(CryptoNet cryptoNet, final ApiRequest request){
GetEstimateFee.getEstimateFee(CryptoNetManager.getURL(cryptoNet), new GetEstimateFee.estimateFeeListener() {
@Override
public void onSuccess() {
request.getListener().success(true,request.getId());
}
@Override
public void onFailure(String msg) {
request.getListener().fail(request.getId());
}
@Override
public void onConnecitonFailure() {
request.getListener().fail(request.getId());
}
});
bTransaction.start();
}
/**
* Fetch the estimated fee for a transaction
*/
public static void getEstimateFee(CryptoCoin cryptoCoin, final ApiRequest request){
GetEstimateFee.getEstimateFee(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),
new GetEstimateFee.estimateFeeListener() {
@Override
public void estimateFee(double value) {
public void estimateFee(long value) {
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.Logger;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
import io.socket.client.IO;
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
*/
@ -36,9 +38,12 @@ public class AddressesActivityWatcher {
* the Socket.IO
*/
private Socket mSocket;
/**
* This app mContext, used to save on the DB
*/
private final Context mContext;
private final String mServerUrl;
private final String mPath;
/**
* Handles the address/transaction notification.
@ -50,9 +55,9 @@ public class AddressesActivityWatcher {
try {
System.out.println("Receive accountActivtyWatcher " + os[0].toString() );
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) {
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() {
@Override
public void call(Object... os) {
try {
Thread.sleep(60000);
} catch (InterruptedException ignore) {}
System.out.println("Disconnected to accountActivityWatcher");
mSocket.connect();
}
};
@ -96,21 +99,19 @@ public class AddressesActivityWatcher {
for(Object ob : os) {
System.out.println("accountActivityWatcher " + ob.toString());
}
try {
Thread.sleep(60000);
} catch (InterruptedException ignore) {}
mSocket.connect();
}
};
/**
* Basic constructor
*
* @param mAccount The mAccount to be monitor
* @param mContext This app mContext
*/
public AddressesActivityWatcher(String serverUrl, String path, CryptoCoin cryptoCoin) {
this.mPath = path;
public AccountActivityWatcher(String serverUrl, GeneralCoinAccount mAccount, Context mContext) {
this.mServerUrl = serverUrl;
this.cryptoCoin = cryptoCoin;
this.mAccount = mAccount;
this.mContext = mContext;
try {
this.mSocket = IO.socket(serverUrl);
this.mSocket.on(Socket.EVENT_CONNECT, onConnect);
@ -140,11 +141,13 @@ public class AddressesActivityWatcher {
* Connects the Socket
*/
public void connect() {
//TODO change to use log
System.out.println("accountActivityWatcher connecting");
try{
if(this.mSocket == null || !this.mSocket.connected()) {
this.mSocket.connect();
}
}catch(Exception ignore){
this.mSocket.connect();
}catch(Exception e){
//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
*/
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 BroadCastTransactionListener listener;
private String serverUrl;
/**
* Basic Consturctor
* @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.mContext = context;
this.mRawTx = RawTx;
this.listener = listener;
this.mPath = path;
this.mAccount = account;
}
/**
@ -46,9 +54,13 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
@Override
public void onResponse(Call<Txi> call, Response<Txi> response) {
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 {
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
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
public void run() {
try {
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
Call<Txi> broadcastTransaction = service.broadcastTransaction(this.mPath, this.mRawTx);
broadcastTransaction.enqueue(this);
}catch(Exception e){
e.printStackTrace();
}
}
public interface BroadCastTransactionListener{
void onSuccess();
void onFailure(String msg);
void onConnecitonFailure();
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
Call<Txi> broadcastTransaction = service.broadcastTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),this.mRawTx);
broadcastTransaction.enqueue(this);
}
}

View File

@ -20,8 +20,6 @@ import retrofit2.Response;
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
* @param serverUrl The url of the insight server
@ -31,11 +29,12 @@ public abstract class GetEstimateFee {
try {
InsightApiServiceGenerator serviceGenerator = new InsightApiServiceGenerator(serverUrl);
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>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
listener.estimateFee((double) (response.body().get("2").getAsDouble()));
listener.estimateFee((long) (answer.get("answer").getAsDouble()));
}
@ -46,13 +45,12 @@ public abstract class GetEstimateFee {
}
});
}catch(Exception e){
e.printStackTrace();
listener.fail();
}
}
public static interface estimateFeeListener{
public void estimateFee(double value);
public void estimateFee(long value);
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;
import android.content.Context;
import android.util.Log;
import java.util.ArrayList;
import java.util.Date;
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.Txi;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.manager.GeneralAccountManager;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
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.Callback;
import retrofit2.Response;
@ -20,40 +25,43 @@ import retrofit2.Response;
*/
public class GetTransactionByAddress extends Thread implements Callback<AddressTxi> {
/**
* The account to be query
*/
private GeneralCoinAccount mAccount;
/**
* The list of address to query
*/
private List<String> mAddresses = new ArrayList<>();
private List<GeneralCoinAddress> mAddresses = new ArrayList<>();
/**
* The serviceGenerator to call
*/
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
* @param account The account to be query
* @param context This app context
*/
public GetTransactionByAddress(CryptoCoin cryptoNet, String serverUrl, String path, InsightApiGenerator.HasTransactionListener listener) {
this.mPath = path;
this.cryptoNet = cryptoNet;
this.mServerUrl = serverUrl;
public GetTransactionByAddress(GeneralCoinAccount account, String serverUrl, Context context) {
this.serverUrl = serverUrl;
this.mAccount = account;
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
this.listener = listener;
this.mContext = context;
}
/**
* add an 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);
}
@ -65,23 +73,110 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
*/
@Override
public void onResponse(Call<AddressTxi> call, Response<AddressTxi> response) {
inProcess = false;
if (response.isSuccessful()) {
boolean changed = false;
AddressTxi addressTxi = response.body();
if(listener != null) {
if (addressTxi.items.length > 0 ) {
listener.hasTransaction(true);
}else{
listener.hasTransaction(false);
for (Txi txi : addressTxi.items) {
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);
}
for (Vout vout : txi.vout) {
if(vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0){
// The address is null, this must be a memo
String hex = vout.scriptPubKey.hex;
int opReturnIndex = hex.indexOf("6a");
if(opReturnIndex >= 0) {
byte[] memoBytes = new byte[Integer.parseInt(hex.substring(opReturnIndex+2,opReturnIndex+4),16)];
for(int i = 0; i < memoBytes.length;i++){
memoBytes[i] = Byte.parseByte(hex.substring(opReturnIndex+4+(i*2),opReturnIndex+6+(i*2)),16);
}
transaction.setMemo(new String(memoBytes));
}
}else {
GTxIO output = new GTxIO();
output.setAmount((long) (vout.value * Math.pow(10, this.mAccount.getCryptoCoin().getPrecision())));
output.setTransaction(transaction);
output.setOut(false);
output.setType(this.mAccount.getCryptoCoin());
String addr = vout.scriptPubKey.addresses[0];
output.setAddressString(addr);
output.setIndex(vout.n);
output.setScriptHex(vout.scriptPubKey.hex);
for (GeneralCoinAddress address : this.mAddresses) {
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
output.setAddress(address);
tempAccount = address.getAccount();
if (!address.hasTransactionInput(output, this.mAccount.getNetworkParam())) {
address.getTransactionInput().add(output);
}
changed = true;
}
}
transaction.getTxOutputs().add(output);
}
}
if(txi.txlock && txi.confirmations< this.mAccount.getCryptoNet().getConfirmationsNeeded()){
transaction.setConfirm(this.mAccount.getCryptoNet().getConfirmationsNeeded());
}
//TODO database
/*SCWallDatabase db = new SCWallDatabase(this.mContext);
long idTransaction = db.getGeneralTransactionId(transaction);
if (idTransaction == -1) {
db.putGeneralTransaction(transaction);
} else {
transaction.setId(idTransaction);
db.updateGeneralTransaction(transaction);
}*/
if (tempAccount != null && transaction.getConfirm() < this.mAccount.getCryptoNet().getConfirmationsNeeded()) {
new GetTransactionData(transaction.getTxid(), tempAccount, this.serverUrl, this.mContext, true).start();
}
for (GeneralCoinAddress address : this.mAddresses) {
if (address.updateTransaction(transaction)) {
break;
}
}
}
for (Txi txi : addressTxi.items) {
GeneralAccountManager.getAccountManager(this.cryptoNet).processTxi(txi);
if(changed) {
this.mAccount.balanceChange();
}
}else{
listener.hasTransaction(false);
}
}
@ -92,7 +187,6 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
*/
@Override
public void onFailure(Call<AddressTxi> call, Throwable t) {
inProcess = false;
Log.e("GetTransactionByAddress", "Error in json format");
}
@ -101,15 +195,14 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
*/
@Override
public void run() {
if (this.mAddresses.size() > 0 && !inProcess) {
inProcess = true;
if (this.mAddresses.size() > 0) {
StringBuilder addressToQuery = new StringBuilder();
for (String address : this.mAddresses) {
addressToQuery.append(address).append(",");
for (GeneralCoinAddress address : this.mAddresses) {
addressToQuery.append(address.getAddressString(this.mAccount.getNetworkParam())).append(",");
}
addressToQuery.deleteCharAt(addressToQuery.length() - 1);
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);
}
}

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.Vin;
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.GeneralCoinAccount;
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
@ -22,6 +20,10 @@ import retrofit2.Response;
*/
public class GetTransactionData extends Thread implements Callback<Txi> {
/**
* The account to be query
*/
private final GeneralCoinAccount mAccount;
/**
* The transaction txid to be query
*/
@ -30,38 +32,41 @@ public class GetTransactionData extends Thread implements Callback<Txi> {
* The serviceGenerator to call
*/
private InsightApiServiceGenerator mServiceGenerator;
/**
* This app context, used to save on the DB
*/
private Context mContext;
private String mServerUrl;
private String mPath;
/**
* If has to wait for another confirmation
*/
private boolean mMustWait = false;
private CryptoCoin cryptoCoin;
/**
* Constructor used to query for a transaction with unknown confirmations
* @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) {
this(txid, serverUrl, path, cryptoCoin, false);
public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context) {
this(txid, account, serverUrl, context, false);
}
/**
* Consturctor to be used qhen the confirmations of the transaction are known
* @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
*/
public GetTransactionData(String txid, String serverUrl, String path, CryptoCoin cryptoCoin, boolean mustWait) {
this.mPath = path;
public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context, boolean mustWait) {
this.mServerUrl = serverUrl;
this.mAccount = account;
this.mTxId= txid;
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
this.mContext = context;
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);
Call<Txi> txiCall = service.getTransaction(this.mPath,this.mTxId);
Call<Txi> txiCall = service.getTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),this.mTxId);
txiCall.enqueue(this);
}
@Override
public void onResponse(Call<Txi> call, Response<Txi> response) {
if (response.isSuccessful()) {
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
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")
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

@ -17,7 +17,6 @@ import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.BitsharesAsset;
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
import cy.agorise.crystalwallet.models.GeneralSetting;
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
public static BitsharesAsset bitEURAsset = new BitsharesAsset("EUR",4,"1.3.120",BitsharesAsset.Type.SMART_COIN);
public static final String BITCOIN_SERVER_URLS[] ={
"https://test-insight.bitpay.com",
//"https://testnet.blockexplorer.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
public void onCreate() {
super.onCreate();
@ -84,10 +62,10 @@ public class CrystalApplication extends Application {
//This is for testing the equivalent values on the testnet TODO remove
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);
}
long idCurrency = db.cryptoCurrencyDao().getByName(bitEURAsset.getName(),bitEURAsset.getCryptoNet().name()).getId();
long idCurrency = db.cryptoCurrencyDao().getByName(bitEURAsset.getName()).getId();
BitsharesAssetInfo info = new BitsharesAssetInfo(bitEURAsset);
info.setCryptoCurrencyId(idCurrency);
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
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);
}
long idCurrency = db.cryptoCurrencyDao().getByName(bitUSDAsset.getName(),bitUSDAsset.getCryptoNet().name()).getId();
long idCurrency = db.cryptoCurrencyDao().getByName(bitUSDAsset.getName()).getId();
BitsharesAssetInfo info = new BitsharesAssetInfo(bitUSDAsset);
info.setCryptoCurrencyId(idCurrency);
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
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);
if (generalSettingPreferredLanguage != null) {
@ -137,11 +105,6 @@ public class CrystalApplication extends Application {
resources.updateConfiguration(configuration, dm);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class);
startService(intent);
}

View File

@ -3,16 +3,21 @@ package cy.agorise.crystalwallet.application;
import android.app.Activity;
import android.app.Application;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.FragmentActivity;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import java.util.List;
import cy.agorise.crystalwallet.activities.PatternRequestActivity;
import cy.agorise.crystalwallet.activities.PinRequestActivity;
import cy.agorise.crystalwallet.activities.PocketRequestActivity;
import cy.agorise.crystalwallet.interfaces.OnResponse;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.notifiers.CrystalWalletNotifier;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
/**
@ -124,7 +129,7 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
public void onActivityStarted(Activity activity) {
if (numStarted == 0) {
if (!actualSecurity().equals("")){
callPasswordRequest(activity,null);
callPasswordRequest(activity);
}
}
numStarted++;
@ -135,41 +140,18 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
numStarted--;
if (numStarted == 0) {
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"))) {
Intent intent = null;
if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) {
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(""))) {
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) {
intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST");
@ -215,4 +197,7 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
public void onActivityDestroyed(Activity activity) {
//
}
}
}

View File

@ -32,7 +32,7 @@ public abstract class BitsharesConstant {
//testnet faucet
//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 BitsharesAsset[] SMARTCOINS = new BitsharesAsset[]{
@ -74,10 +74,10 @@ public abstract class BitsharesConstant {
public static void addSmartCoins(Context context){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
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);
}
long idCurrency = db.cryptoCurrencyDao().getByName(smartcoin.getName(),CryptoNet.BITSHARES.name()).getId();
long idCurrency = db.cryptoCurrencyDao().getByName(smartcoin.getName()).getId();
BitsharesAssetInfo info = new BitsharesAssetInfo(smartcoin);
info.setCryptoCurrencyId(idCurrency);
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);

View File

@ -1,14 +1,16 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
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.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetBalance;
/**
* Created by Henry Varona on 10/9/2017.

View File

@ -1,40 +0,0 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import cy.agorise.crystalwallet.models.BitcoinAddress;
/**
* 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 androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.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

@ -1,14 +1,15 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
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.BitsharesAccountNameCache;
import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
/**
* Created by Henry Varona on 6/15/2018.

View File

@ -1,10 +1,10 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
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;

View File

@ -1,18 +1,20 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.paging.DataSource;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;
import android.arch.lifecycle.LiveData;
import android.arch.paging.DataSource;
import android.arch.paging.LivePagedListProvider;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;
import java.util.List;
import cy.agorise.crystalwallet.models.Contact;
import cy.agorise.crystalwallet.models.ContactAddress;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
/**
* Created by Henry Varona on 1/17/2018.

View File

@ -1,15 +1,17 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
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.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.CryptoNetBalance;
import cy.agorise.crystalwallet.enums.CryptoNet;
/**
* Created by Henry Varona on 10/9/2017.

View File

@ -1,10 +1,10 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
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;
@ -23,9 +23,6 @@ public interface CryptoCurrencyDao {
@Query("SELECT * FROM crypto_currency WHERE id = :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")
CryptoCurrency getByNameAndCryptoNet(String name,String cryptoNet);
@ -35,8 +32,8 @@ public interface CryptoCurrencyDao {
@Query("SELECT * FROM crypto_currency WHERE name = :name")
LiveData<CryptoCurrency> getLiveDataByName(String name);
@Query("SELECT * FROM crypto_currency WHERE name = :name and crypto_net = :cryptoNet")
CryptoCurrency getByName(String name, String cryptoNet);
@Query("SELECT * FROM crypto_currency WHERE name = :name")
CryptoCurrency getByName(String name);
@Insert(onConflict = OnConflictStrategy.IGNORE)
public long[] insertCryptoCurrency(CryptoCurrency... currencies);

View File

@ -1,13 +1,14 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
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.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
/**

View File

@ -1,14 +1,17 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
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.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.CryptoNetBalance;
/**
* Created by Henry Varona on 10/9/2017.
@ -26,9 +29,6 @@ public interface CryptoNetAccountDao {
@Query("SELECT cna.* FROM crypto_net_account cna WHERE seed_id = :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")
LiveData<CryptoNetAccount> getByIdLiveData( long accountId);

View File

@ -1,18 +1,15 @@
package cy.agorise.crystalwallet.dao;
import androidx.sqlite.db.SupportSQLiteDatabase;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import androidx.room.migration.Migration;
import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.arch.persistence.room.TypeConverters;
import android.arch.persistence.room.migration.Migration;
import android.content.Context;
import cy.agorise.crystalwallet.dao.converters.Converters;
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.BitsharesAssetInfo;
import cy.agorise.crystalwallet.models.Contact;
@ -42,11 +39,8 @@ import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
BitsharesAssetInfo.class,
BitsharesAccountNameCache.class,
CryptoCurrencyEquivalence.class,
GeneralSetting.class,
BitcoinTransaction.class,
BitcoinTransactionGTxIO.class,
BitcoinAddress.class
}, version = 6, exportSchema = false)
GeneralSetting.class
}, version = 4, exportSchema = false)
@TypeConverters({Converters.class})
public abstract class CrystalDatabase extends RoomDatabase {
@ -63,8 +57,6 @@ public abstract class CrystalDatabase extends RoomDatabase {
public abstract BitsharesAccountNameCacheDao bitsharesAccountNameCacheDao();
public abstract CryptoCurrencyEquivalenceDao cryptoCurrencyEquivalenceDao();
public abstract GeneralSettingDao generalSettingDao();
public abstract BitcoinTransactionDao bitcoinTransactionDao();
public abstract BitcoinAddressDao bitcoinAddressDao();
public static CrystalDatabase getAppDatabase(Context context) {
if (instance == null) {
@ -72,10 +64,8 @@ public abstract class CrystalDatabase extends RoomDatabase {
Room.databaseBuilder(context,
CrystalDatabase.class, "CrystalWallet.db")
.allowMainThreadQueries()
//.addMigrations(MIGRATION_2_3)
//.addMigrations(MIGRATION_3_4)
//.addMigrations(MIGRATION_4_5)
//.addMigrations(MIGRATION_5_6)
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.build();
}
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

@ -1,14 +1,15 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
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.AccountSeed;
import cy.agorise.crystalwallet.models.GeneralSetting;
/**

View File

@ -1,13 +1,15 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
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.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount;
import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
/**

View File

@ -1,11 +1,12 @@
package cy.agorise.crystalwallet.dao;
import androidx.lifecycle.LiveData;
import androidx.paging.DataSource;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import android.arch.lifecycle.LiveData;
import android.arch.paging.DataSource;
import android.arch.paging.LivePagedListProvider;
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.Date;
import java.util.List;
@ -50,10 +51,7 @@ public interface TransactionDao {
List<CryptoCoinTransaction> getByIdAccount(long idAccount);
@Query("SELECT * FROM crypto_coin_transaction WHERE id = :id")
LiveData<CryptoCoinTransaction> getByIdLiveData(long id);
@Query("SELECT * FROM crypto_coin_transaction WHERE id = :id")
CryptoCoinTransaction getById(long id);
LiveData<CryptoCoinTransaction> getById(long id);
@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);

View File

@ -1,6 +1,6 @@
package cy.agorise.crystalwallet.dao.converters;
import androidx.room.TypeConverter;
import android.arch.persistence.room.TypeConverter;
import java.util.Date;
@ -10,6 +10,8 @@ import cy.agorise.crystalwallet.enums.SeedType;
import cy.agorise.crystalwallet.models.BitsharesAsset;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import static cy.agorise.crystalwallet.R.string.account;
/**
* Created by Henry Varona on 13/9/2017.
*/

View File

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

View File

@ -4,8 +4,6 @@ import java.io.Serializable;
import java.util.HashMap;
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
* 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.
*/
public enum CryptoNet implements Serializable {
UNKNOWN("UNKNOWN",6,-1,android.R.drawable .ic_menu_help),
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);
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);
protected String label;
@ -28,8 +19,6 @@ public enum CryptoNet implements Serializable {
protected int bip44Index;
protected int iconImageResource;
private static Map<Integer, CryptoNet> bip44Map = new HashMap<Integer, CryptoNet>();
static {
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.confirmationsNeeded = confirmationsNeeded;
this.bip44Index = bip44Index;
this.iconImageResource = iconImageResource;
}
public String getLabel(){
@ -56,10 +44,6 @@ public enum CryptoNet implements Serializable {
return this.bip44Index;
}
public int getIconImageResource() {
return this.iconImageResource;
}
public static CryptoNet fromBip44Index(int index){
if (bip44Map.containsKey(index)) {
return bip44Map.get(index);

View File

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

View File

@ -2,20 +2,24 @@ package cy.agorise.crystalwallet.fragments;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.activities.GeneralSettingsActivity;
import cy.agorise.crystalwallet.activities.SettingsActivity;
public class AccountsFragment extends DialogFragment {

View File

@ -1,17 +1,14 @@
package cy.agorise.crystalwallet.fragments;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.support.v4.app.Fragment;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.thekhaeng.pushdownanim.PushDownAnim;
import butterknife.BindView;
import butterknife.ButterKnife;
import cy.agorise.crystalwallet.R;
@ -44,22 +41,6 @@ public class AccountsSettingsFragment extends Fragment {
@BindView(R.id.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
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@ -72,36 +53,6 @@ public class AccountsSettingsFragment extends Fragment {
tvRefresh.setText(makeFirstWordsBold(getResources().getString(R.string.refresh_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;
}

View File

@ -1,20 +1,14 @@
package cy.agorise.crystalwallet.fragments;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.core.content.ContextCompat;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -22,29 +16,29 @@ import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.activities.BackupSeedActivity;
import cy.agorise.crystalwallet.activities.IntroActivity;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.requestmanagers.CreateBackupRequest;
import cy.agorise.crystalwallet.requestmanagers.FileServiceRequest;
import cy.agorise.crystalwallet.requestmanagers.FileServiceRequestListener;
import cy.agorise.crystalwallet.requestmanagers.FileServiceRequests;
/**
* Created by Seven on 1/11/18.
* Created by xd on 1/11/18.
*/
public class BackupsSettingsFragment extends Fragment{
private static final int PERMISSION_REQUEST_CODE = 1;
public BackupsSettingsFragment() {
// Required empty public constructor
}
@ -71,7 +65,6 @@ public class BackupsSettingsFragment extends Fragment{
@BindView(R.id.btnBinFile)
public Button btnBinFile;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@ -79,25 +72,6 @@ public class BackupsSettingsFragment extends Fragment{
View v = inflater.inflate(R.layout.fragment_backups_settings, container, false);
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)));
tvBrainkey.setText(makeFirstWordsBold(getResources().getString(R.string.brainkey_description)));
tvWIFKey.setText(makeFirstWordsBold(getResources().getString(R.string.wif_key_description)));
@ -118,40 +92,12 @@ public class BackupsSettingsFragment extends Fragment{
public void btnBrainOnClick(){
Intent intent = new Intent(getContext(), BackupSeedActivity.class);
intent. putExtra("SEED_ID","");
startActivity(intent);
}
@OnClick(R.id.btnBinFile)
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)) {
LiveData<GeneralSetting> generalSettingLD = CrystalDatabase.getAppDatabase(getContext()).generalSettingDao().getByName(GeneralSetting.SETTING_PASSWORD);
@ -159,13 +105,13 @@ public class BackupsSettingsFragment extends Fragment{
generalSettingLD.observe(this, new Observer<GeneralSetting>() {
@Override
public void onChanged(@Nullable GeneralSetting generalSetting) {
String password = "";
if (generalSetting != null) {
password = generalSetting.getValue();
}
final CreateBackupRequest backupFileRequest = new CreateBackupRequest(getContext(), password);
backupFileRequest.setListener(new FileServiceRequestListener() {
@Override
public void onCarryOut() {
@ -186,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

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

View File

@ -1,26 +1,44 @@
package cy.agorise.crystalwallet.fragments;
import androidx.lifecycle.LiveData;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import com.vincent.filepicker.Constant;
import com.vincent.filepicker.activity.AudioPickActivity;
import com.vincent.filepicker.filter.entity.AudioFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Currency;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnItemSelected;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.Language;
import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.models.GrapheneAccount;
@ -29,6 +47,10 @@ import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesLTMUpgradeRequest;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.views.TimeZoneAdapter;
import static android.app.Activity.RESULT_OK;
import static com.vincent.filepicker.activity.AudioPickActivity.IS_NEED_RECORDER;
/**
@ -51,9 +73,6 @@ public class BitsharesSettingsFragment extends Fragment {
GrapheneAccountInfo grapheneAccountInfo;
GrapheneAccount grapheneAccount;
public BitsharesSettingsFragment() {
if (getArguments() != null) {
long cryptoNetAcountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID", -1);
@ -95,17 +114,6 @@ public class BitsharesSettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_bitshares_settings, container, false);
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();
return v;

View File

@ -1,18 +1,18 @@
package cy.agorise.crystalwallet.fragments;
import android.app.Dialog;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.paging.PagedList;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;

View File

@ -1,20 +1,19 @@
package cy.agorise.crystalwallet.fragments;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.paging.PagedList;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
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.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
@ -28,9 +27,6 @@ public class ContactsFragment extends Fragment {
@BindView(R.id.rvContacts)
RecyclerView rvContacts;
@BindView(R.id.tvNoContacts)
TextView tvNoContacts;
ContactListAdapter adapter;
FloatingActionButton fabAddContact;
@ -90,13 +86,6 @@ public class ContactsFragment extends Fragment {
@Override
public void onChanged(@Nullable PagedList<Contact> 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 androidx.fragment.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 androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.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,121 +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 androidx.fragment.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;
/**
* 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,27 +1,24 @@
package cy.agorise.crystalwallet.fragments;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.arch.lifecycle.LiveData;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
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 java.util.List;
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;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
/**
@ -33,15 +30,9 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
@BindView(R.id.tvMnemonic)
TextView tvMnemonic;
@BindView(R.id.btnCopy)
Button btnCopy;
CryptoNetAccount cryptoNetAccount;
AccountSeed accountSeed;
public GeneralCryptoNetAccountSettingsFragment() {
if (getArguments() != null) {
@ -82,18 +73,6 @@ public class GeneralCryptoNetAccountSettingsFragment extends 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;
@ -104,24 +83,4 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
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,47 +1,52 @@
package cy.agorise.crystalwallet.fragments;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.ThemedSpinnerAdapter;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.thekhaeng.pushdownanim.PushDownAnim;
import com.vincent.filepicker.Constant;
import com.vincent.filepicker.activity.AudioPickActivity;
import com.vincent.filepicker.filter.entity.AudioFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Currency;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnItemSelected;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.Language;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.views.TimeZoneAdapter;
import static android.app.Activity.RESULT_OK;
import static android.content.Context.CONSUMER_IR_SERVICE;
import static com.vincent.filepicker.activity.AudioPickActivity.IS_NEED_RECORDER;
@ -66,8 +71,6 @@ public class GeneralSettingsFragment extends Fragment {
Spinner spDisplayDateTime;
@BindView (R.id.tvReceiveFundsSoundValue)
TextView tvReceiveFundsSound;
@BindView (R.id.btnContact)
Button btnContact;
public GeneralSettingsFragment() {
this.spPreferredLanguageInitialized = false;
@ -96,17 +99,6 @@ public class GeneralSettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_general_settings, container, false);
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);
generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList();

View File

@ -2,20 +2,15 @@ package cy.agorise.crystalwallet.fragments;
import android.app.Activity;
import android.app.Dialog;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.ViewModelProviders;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -24,9 +19,6 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim;
import com.vincent.filepicker.ToastUtil;
import java.net.URISyntaxException;
import butterknife.BindView;
@ -57,10 +49,7 @@ public class ImportAccountOptionsFragment extends DialogFragment {
Button btnClose;
@BindView(R.id.btnImportBackup)
Button btnImportBackup;
@BindView(R.id.btnImportSeed)
Button btnImportSeed;
private static final int PERMISSION_REQUEST_CODE = 1;
/*
Dialog for loading
@ -101,34 +90,6 @@ public class ImportAccountOptionsFragment extends DialogFragment {
View view = inflater.inflate(R.layout.fragment_import_account_options, null);
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();
}
@ -149,88 +110,18 @@ public class ImportAccountOptionsFragment extends DialogFragment {
@OnClick (R.id.btnImportBackup)
public void importBackup(){
Intent fileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
fileIntent.setType("*/*");
fileIntent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(fileIntent, FILE_CONTENT_REQUEST_CODE);
if (Build.VERSION.SDK_INT >= 23) {
if (checkPermission()) {
Intent fileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
fileIntent.setType("*/*");
fileIntent.addCategory(Intent.CATEGORY_OPENABLE);
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)
public void importSeed(){
if (Build.VERSION.SDK_INT >= 23) {
if (checkPermission()) {
Intent intent = new Intent(this.getActivity(), ImportSeedActivity.class);
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;
}
Intent intent = new Intent(this.getActivity(), ImportSeedActivity.class);
startActivity(intent);
}
@Override

View File

@ -1,8 +1,8 @@
package cy.agorise.crystalwallet.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

View File

@ -1,24 +1,23 @@
package cy.agorise.crystalwallet.fragments;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.support.annotation.Nullable;
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.Toast;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
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.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
/**
* Created by xd on 1/18/18.
@ -26,12 +25,6 @@ import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
public class NoneSecurityFragment extends Fragment {
@BindView(R.id.btnOK)
Button btnOK;
public NoneSecurityFragment() {
// Required empty public constructor
}
@ -50,41 +43,14 @@ public class NoneSecurityFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_none_security, container, false);
ButterKnife.bind(this, 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
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
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
CrystalSecurityMonitor.getInstance(null).clearSecurity();
}
}*/
}
}

View File

@ -1,27 +1,35 @@
package cy.agorise.crystalwallet.fragments;
import android.graphics.Color;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.util.ChildViewPager;
import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
/**
* Created by xd on 1/18/18.
@ -34,17 +42,9 @@ public class PatternSecurityFragment extends Fragment {
@BindView(R.id.tvPatternText)
TextView tvPatternText;
/*
* Contains the ChildViewPager to block the viewpager when the user is using the pattern control
* */
private ChildViewPager childViewPager;
private PatternLockViewListener actualPatternListener;
private String patternEntered;
public PatternSecurityFragment() {
// Required empty public constructor
}
@ -77,11 +77,6 @@ public class PatternSecurityFragment extends Fragment {
return patternString;
}
public void setChildViewPager(ChildViewPager childViewPager) {
this.childViewPager = childViewPager;
}
public void removePatternListener(){
if (actualPatternListener != null){
patternLockView.removePatternLockListener(actualPatternListener);
@ -92,12 +87,12 @@ public class PatternSecurityFragment extends Fragment {
public void showNewPatternUI(){
removePatternListener();
patternLockView.clearPattern();
tvPatternText.setTextColor(Color.WHITE);
tvPatternText.setText(getActivity().getResources().getString(R.string.Enter_new_pattern));
tvPatternText.setText("Enter new pattern");
actualPatternListener = new PatternLockViewListener() {
@Override
public void onStarted() {
}
@Override
@ -123,7 +118,7 @@ public class PatternSecurityFragment extends Fragment {
removePatternListener();
patternLockView.clearPattern();
patternLockView.requestFocus();
tvPatternText.setText(getActivity().getResources().getString(R.string.Confirm_new_pattern));
tvPatternText.setText("Confirm new pattern");
actualPatternListener = new PatternLockViewListener() {
@Override
@ -140,9 +135,7 @@ public class PatternSecurityFragment extends Fragment {
public void onComplete(List<PatternLockView.Dot> pattern) {
if (patternEntered.equals(patternToString(pattern))){
savePattern(patternEntered);
}
else{
resetPattern();
showNewPatternUI();
}
}
@ -154,79 +147,9 @@ public class PatternSecurityFragment extends Fragment {
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){
String patternEncripted = PasswordManager.encriptPassword(pattern);
CrystalSecurityMonitor.getInstance(null).setPatternEncrypted(patternEncripted);
/*CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity(), new OnResponse() {
@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);
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
}
}

View File

@ -1,33 +1,24 @@
package cy.agorise.crystalwallet.fragments;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnFocusChange;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
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.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
@ -51,19 +42,6 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
@BindView(R.id.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;
GeneralSetting passwordGeneralSetting;
PinSecurityValidator pinSecurityValidator;
@ -86,117 +64,15 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
View v = inflater.inflate(R.layout.fragment_pin_security, container, false);
ButterKnife.bind(this, v);
/*
* Initially not enabled til it passes validations
* */
btnOK.setEnabled(false);
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
pinSecurityValidator = new PinSecurityValidator(this.getContext(), etNewPin, etConfirmPin);
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;
}
@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,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterNewPinChanged(Editable editable) {
@ -218,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
public void onValidationSucceeded(final ValidationField field) {
final PinSecurityFragment fragment = this;
@ -242,64 +108,29 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
}
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
valid = true;
savePassword(etNewPin.getText().toString());
/*
* 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) {
String passwordEncripted = PasswordManager.encriptPassword(password);
CrystalSecurityMonitor.getInstance(getActivity()).setPasswordSecurity(passwordEncripted);
//CrystalSecurityMonitor.getInstance(getActivity()).callPasswordRequest(this.getActivity());
CrystalSecurityMonitor.getInstance(null).setPasswordSecurity(passwordEncripted);
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
}
@Override
public void onValidationFailed(final ValidationField field) {
//Still false
valid = false;
/*
* Disable til it passes validations
* */
btnOK.setEnabled(false);
this.getActivity().runOnUiThread(new Runnable() {
@Override

View File

@ -1,9 +1,10 @@
package cy.agorise.crystalwallet.fragments;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
@ -12,8 +13,10 @@ import android.widget.EditText;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.util.ChildViewPager;
/**
* Created by henry varona on 4/17/18.

View File

@ -1,33 +1,30 @@
package cy.agorise.crystalwallet.fragments;
import android.app.Dialog;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
@ -35,14 +32,8 @@ import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.journeyapps.barcodescanner.BarcodeEncoder;
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.util.CircularImageView;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountListViewModel;
import cy.agorise.crystalwallet.views.CryptoNetAccountAdapter;
@ -84,8 +75,6 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
TextView tvAssetError;
@BindView(R.id.ivQrCode)
ImageView ivQrCode;
@BindView(R.id.pbQrCode)
ProgressBar pbQrCode;
@BindView(R.id.tvCancel)
TextView tvCancel;
@ -106,10 +95,6 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
private FloatingActionButton fabReceive;
private AsyncTask qrCodeTask;
private Double lastAmount = -1.0;
public static ReceiveTransactionFragment newInstance(long cryptoNetAccountId) {
ReceiveTransactionFragment f = new ReceiveTransactionFragment();
@ -147,13 +132,36 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
db = CrystalDatabase.getAppDatabase(this.getContext());
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);
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter toSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
spTo.setAdapter(toSpinnerAdapter);
spTo.setSelection(0);
setAccountUI();
}
builder.setView(view);
@ -226,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)
public void afterToSelected(Spinner spinner, int position) {
this.cryptoNetAccount = (CryptoNetAccount)spinner.getSelectedItem();
setAccountUI();
this.receiveTransactionValidator.validate();
}
@ -290,10 +247,7 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
@OnItemSelected(R.id.spAsset)
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();
}
@ -341,147 +295,71 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
}
public void createQrCode(){
final Double amount;
Double amount = 0.0;
try{
amount = Double.valueOf(this.etAmount.getText().toString());
} catch(NumberFormatException e){
lastAmount = -1.0;
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.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(toAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(toAccountSelected.getId()));
/*
* this is only for graphene accounts.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(toAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(toAccountSelected.getId()));
this.invoiceItems.clear();
this.invoiceItems.add(
new LineItem("transfer", 1, amount)
);
this.invoiceItems.clear();
this.invoiceItems.add(
new LineItem("transfer", 1, amount)
);
LineItem items[] = new LineItem[this.invoiceItems.size()];
items = this.invoiceItems.toArray(items);
this.invoice.setLineItems(items);
this.invoice.setTo(grapheneAccountSelected.getName());
this.invoice.setCurrency(this.cryptoCurrency.getName());
LineItem items[] = new LineItem[this.invoiceItems.size()];
items = this.invoiceItems.toArray(items);
this.invoice.setLineItems(items);
this.invoice.setTo(grapheneAccountSelected.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 {
final Bitmap bitmap = textToImageEncode(Invoice.toQrCode(invoice));
if (!this.isCancelled()) {
ReceiveTransactionFragment.this.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
ivQrCode.setImageBitmap(bitmap);
pbQrCode.setVisibility(View.GONE);
}
});
}
} catch (WriterException e) {
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();
}
try {
Bitmap bitmap = textToImageEncode(Invoice.toQrCode(invoice));
ivQrCode.setImageBitmap(bitmap);
} catch (WriterException e) {
Log.e("ReceiveFragment", "Error creating QrCode");
}
}
Bitmap textToImageEncode(String Value) throws WriterException {
Bitmap bitmap = null;
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
//TODO: do this in another thread
BitMatrix bitMatrix;
try {
BitMatrix bitMatrix = multiFormatWriter.encode(Value, BarcodeFormat.QR_CODE, ivQrCode.getWidth(), ivQrCode.getHeight());
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
bitmap = barcodeEncoder.createBitmap(bitMatrix);
} catch (WriterException e) {
e.printStackTrace();
bitMatrix = new MultiFormatWriter().encode(
Value,
BarcodeFormat.DATA_MATRIX.QR_CODE,
ivQrCode.getWidth(), ivQrCode.getHeight(), null
);
} 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;
}
}

View File

@ -6,11 +6,14 @@ import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NdefFormatable;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -80,15 +83,10 @@ public class SecuritySettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_security_settings, container, false);
ButterKnife.bind(this, v);
/*
* For now this will not be implemented
* */
sPocketSecurity.setEnabled(false);
securityPagerAdapter = new SecurityPagerAdapter(getChildFragmentManager());
mPager.setAdapter(securityPagerAdapter);
switch(CrystalSecurityMonitor.getInstance(getActivity()).actualSecurity()) {
switch(CrystalSecurityMonitor.getInstance(null).actualSecurity()) {
case GeneralSetting.SETTING_PASSWORD:
mPager.setCurrentItem(1);
break;
@ -98,6 +96,7 @@ public class SecuritySettingsFragment extends Fragment {
default:
mPager.setCurrentItem(0);
}
mPager.setSwipeLocked(true);
TabLayout tabLayout = v.findViewById(R.id.tabs);
@ -118,7 +117,7 @@ public class SecuritySettingsFragment extends Fragment {
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
}
}
@ -135,9 +134,7 @@ public class SecuritySettingsFragment extends Fragment {
case 1:
return new PinSecurityFragment();
case 2:
final PatternSecurityFragment patternSecurityFragment = new PatternSecurityFragment();
patternSecurityFragment.setChildViewPager(mPager);
return patternSecurityFragment;
return new PatternSecurityFragment();
}
return null; //new OnConstructionFragment();

View File

@ -3,50 +3,50 @@ package cy.agorise.crystalwallet.fragments;
import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AlertDialog;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.jaredrummler.materialspinner.MaterialSpinner;
import com.vincent.filepicker.ToastUtil;
import java.io.File;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@ -56,14 +56,6 @@ import butterknife.OnClick;
import butterknife.OnItemSelected;
import butterknife.OnTextChanged;
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.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
@ -85,14 +77,14 @@ import cy.agorise.graphenej.Invoice;
import cy.agorise.graphenej.LineItem;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class SendTransactionFragment extends DialogFragment implements UIValidatorListener, ZXingScannerView.ResultHandler {
import static butterknife.internal.Utils.listOf;
private final String TAG = getClass().getName();
public class SendTransactionFragment extends DialogFragment implements UIValidatorListener, ZXingScannerView.ResultHandler {
SendTransactionValidator sendTransactionValidator;
@BindView(R.id.spFrom)
Spinner spFrom;
MaterialSpinner spFrom;
@BindView(R.id.tvFromError)
TextView tvFromError;
@BindView(R.id.etTo)
@ -101,14 +93,12 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
View viewSend;
@BindView(R.id.tvToError)
TextView tvToError;
@BindView(R.id.fabCloseCamera)
FloatingActionButton btnCloseCamera;
@BindView(R.id.spAsset)
Spinner spAsset;
@BindView(R.id.tvAssetError)
TextView tvAssetError;
//@BindView(R.id.scrollMain)
//ScrollView scrollMain;
@BindView(R.id.scrollMain)
ScrollView scrollMain;
@BindView(R.id.etAmount)
EditText etAmount;
@BindView(R.id.tvAmountError)
@ -119,8 +109,11 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
TextView tvMemoError;
@BindView(R.id.btnSend)
FloatingActionButton btnSend;
@BindView(R.id.btnCancel)
TextView btnCancel;
@BindView(R.id.ivPeople)
ImageView ivPeople;
@BindView(R.id.ivCamera)
ZXingScannerView mScannerView;
@ -129,11 +122,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
@BindView(R.id.gravatar)
CircularImageView userImg;
@BindView(R.id.viewCamera)
View viewCamera;
/* Flag to control when the camera is visible and when is hidden */
private boolean cameraVisible = false;
Button btnScanQrCode;
private long cryptoNetAccountId;
private CryptoNetAccount cryptoNetAccount;
@ -142,10 +131,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
private FloatingActionButton fabSend;
private AlertDialog.Builder builder;
/*
Dialog for loading
*/
private CrystalDialog crystalDialog;
public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
SendTransactionFragment f = new SendTransactionFragment();
@ -177,9 +163,52 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
View view = inflater.inflate(R.layout.send_transaction, null);
ButterKnife.bind(this, view);
this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1);
final Activity activity = getActivity();
/*
* 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);
/*
* Add style to the spinner android
@ -190,57 +219,10 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
db = CrystalDatabase.getAppDatabase(this.getContext());
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);
/*
* If only one account block the control
* */
//if(cryptoNetAccounts.size()==1){
// spFrom.setEnabled(false);
//}
spFrom.setAdapter(fromSpinnerAdapter);
spFrom.setSelection(0);
setAccountUI();
/*
* Custom material spinner implementation
* */
//spFrom.setItems(cryptoNetAccounts);
//spFrom.setSelectedIndex(0);
//spFrom.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<CryptoNetAccount>() {
// @Override
// public void onItemSelected(MaterialSpinner view, int position, long id, CryptoNetAccount item) {
// sendTransactionValidator.validate();
// }
//});
//spFrom.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {
// @Override public void onNothingSelected(MaterialSpinner spinner) {
// }
//});
// etFrom.setText(this.grapheneAccount.getName());
}
loadUserImage();
/* 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.
*
**/
this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
@ -254,93 +236,62 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
}
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);
assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
spAsset.setAdapter(assetAdapter);
}
});
// TODO SendTransactionValidator to accept spFrom
sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
sendTransactionValidator.setListener(this);
} else {
CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
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);
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);
spFrom.setAdapter(fromSpinnerAdapter);
//spFrom.setSelection(0);
// 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);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CAMERA_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("value", "Permission Granted, Now you can use camera .");
getActivity().runOnUiThread(new Runnable(){
public void run() {
Toast.makeText(getActivity(), getActivity().getString(R.string.permission_granted_camera), Toast.LENGTH_LONG).show();
}
});
} else {
Log.e("value", "Permission Denied, You cannot use the camera.");
getActivity().runOnUiThread(new Runnable(){
public void run() {
Toast.makeText(getActivity(), getActivity().getString(R.string.permission_denied_camera), Toast.LENGTH_LONG).show();
}
});
/*
* Custom material spinner implementation
* */
spFrom.setItems(cryptoNetAccounts);
//spFrom.setSelectedIndex(0);
spFrom.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<CryptoNetAccount>() {
@Override
public void onItemSelected(MaterialSpinner view, int position, long id, CryptoNetAccount item) {
sendTransactionValidator.validate();
}
break;
});
spFrom.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {
@Override public void onNothingSelected(MaterialSpinner spinner) {
}
});
// etFrom.setText(this.grapheneAccount.getName());
}
loadUserImage();
try {
verifyCameraPermissions(getActivity());
beginScanQrCode();
}catch(Exception e){
e.printStackTrace();
}
return builder.setView(view).create();
}
@Override
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this);
mScannerView.startCamera();
/*builder.setNeutralButton("Scan QR Code", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
beginScanQrCode();
}
});*/
// Force dialog fragment to use the full width of the screen
Window dialogWindow = getDialog().getWindow();
@ -349,12 +300,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
loadUserImage();
}
@Override
public void onPause() {
super.onPause();
mScannerView.stopCamera();
}
@Override
public void onDestroy() {
super.onDestroy();
@ -383,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) {
this.cryptoNetAccount = (CryptoNetAccount)spinner.getSelectedItem();
setAccountUI();
this.sendTransactionValidator.validate();
}
}*/
@OnTextChanged(value = R.id.etTo,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
@ -408,48 +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 */
viewCamera.setVisibility(View.GONE);
mScannerView.setVisibility(View.VISIBLE);
/* Change icon */
btnCloseCamera.setImageDrawable(getResources().getDrawable(R.drawable.ic_close));
/* Reset variable */
cameraVisible = true;
/* Star the camera again */
beginScanQrCode();
}
/**
* Hides the camera and show the black background
* */
private void hideCamera(){
/* Change visibilities of views */
viewCamera.setVisibility(View.VISIBLE);
mScannerView.setVisibility(View.INVISIBLE);
/* Change icon */
btnCloseCamera.setImageDrawable(getResources().getDrawable(R.drawable.ok));
/* Reset variable */
cameraVisible = false;
}
@OnTextChanged(value = R.id.etMemo,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterMemoChanged(Editable editable) {
@ -507,118 +408,51 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
@OnClick(R.id.btnSend)
public void sendTransaction(){
final SendTransactionFragment thisFragment = this;
final CryptoNetInfoRequest sendRequest;
if (this.sendTransactionValidator.isValid()) {
//CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex());
CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getSelectedItem();
CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex());
if (fromAccountSelected.getCryptoNet() == CryptoNet.BITSHARES) {
/*
* this is only for graphene accounts.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId()));
//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.round(Math.pow(10, ((CryptoCurrency) spAsset.getSelectedItem()).getPrecision())));
/*final ValidateBitsharesSendRequest*/
sendRequest = new ValidateBitsharesSendRequest(
this.getContext(),
grapheneAccountSelected,
this.etTo.getText().toString(),
amount,
((CryptoCurrency) spAsset.getSelectedItem()).getName(),
etMemo.getText().toString()
);
sendRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if (((ValidateBitsharesSendRequest)sendRequest).getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)) {
try {
crystalDialog.dismiss();
thisFragment.dismiss();
//thisFragment.finalize();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
} else {
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 {
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
}
}
});
}
/*
* If exists mode scurity show it and valide events in case of success or fail
* */
CrystalSecurityMonitor.getInstance(this.getActivity()).callPasswordRequest(this.getActivity(), new OnResponse() {
* this is only for graphene accounts.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId()));
//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.round(Math.pow(10,((CryptoCurrency)spAsset.getSelectedItem()).getPrecision())));
final ValidateBitsharesSendRequest sendRequest = new ValidateBitsharesSendRequest(
this.getContext(),
grapheneAccountSelected,
this.etTo.getText().toString(),
amount,
((CryptoCurrency)spAsset.getSelectedItem()).getName(),
etMemo.getText().toString()
);
sendRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onSuccess() {
/*
* Show loading dialog
* */
crystalDialog = new CrystalDialog((Activity) getContext());
crystalDialog.setText("Sending");
crystalDialog.progress();
crystalDialog.show();
CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
}
@Override
public void onFailed() {
public void onCarryOut() {
if (sendRequest.getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)){
try {
this.finalize();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
});
//CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
}
}
public void beginScanQrCode(){
//mScannerView = new ZXingScannerView(getContext());
mScannerView.setFormats(Collections.singletonList(BarcodeFormat.QR_CODE));
mScannerView.setAspectTolerance(0.5f);
mScannerView.setFormats(listOf(BarcodeFormat.QR_CODE));
mScannerView.setAutoFocus(true);
mScannerView.setLaserColor(R.color.colorAccent);
mScannerView.setMaskColor(R.color.colorAccent);
@ -633,6 +467,20 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
};
public static void verifyCameraPermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_CAMERA,
REQUEST_CAMERA_PERMISSION
);
}
}
@Override
public void onValidationSucceeded(final ValidationField field) {
final SendTransactionFragment fragment = this;
@ -686,14 +534,13 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
@Override
public void handleResult(Result result) {
try {
System.out.println("CAMERA result " + result.getText() );
Invoice invoice = Invoice.fromQrCode(result.getText());
Log.d(TAG, "QR Code read: " + invoice.toJsonString());
etTo.setText(invoice.getTo());
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);
break;
}
@ -710,34 +557,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ENGLISH));
etAmount.setText(df.format(amount));
Log.i("SendFragment", result.getText());
return;
}catch(Exception e){
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

@ -1,24 +1,22 @@
package cy.agorise.crystalwallet.fragments;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.paging.PagedList;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
@ -27,30 +25,27 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended;
import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel;
import cy.agorise.crystalwallet.views.TransactionListAdapter;
import cy.agorise.crystalwallet.views.TransactionListView;
import cy.agorise.crystalwallet.views.TransactionOrderSpinnerAdapter;
public class TransactionsFragment extends Fragment {
@BindView(R.id.vTransactionListView)
TransactionListView transactionListView;
@BindView(R.id.spTransactionsOrder)
Spinner spTransactionsOrder;
@BindView(R.id.etTransactionSearch)
EditText etTransactionSearch;
@BindView(R.id.tvNoTransactions)
TextView tvNoTransactions;
@BindView(R.id.rvTransactions)
RecyclerView rvTransactions;
RecyclerView balanceRecyclerView;
FloatingActionButton fabSend;
FloatingActionButton fabReceive;
TransactionListAdapter transactionListAdapter;
TransactionListViewModel transactionListViewModel;
LiveData<PagedList<CryptoCoinTransactionExtended>> transactionsLiveData;
@ -71,22 +66,20 @@ public class TransactionsFragment extends Fragment {
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_transactions, container, false);
ButterKnife.bind(this, view);
rvTransactions.setLayoutManager(new LinearLayoutManager(getContext()));
transactionListAdapter = new TransactionListAdapter(this);
rvTransactions.setAdapter(transactionListAdapter);
// Gets the Balance RecyclerView
balanceRecyclerView = view.findViewById(R.id.transactionListView);
fabSend = getActivity().findViewById(R.id.fabSend);
fabReceive = getActivity().findViewById(R.id.fabReceive);
// 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
rvTransactions.addOnScrollListener(new RecyclerView.OnScrollListener() {
balanceRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx,int dy){
super.onScrolled(recyclerView, dx, dy);
@ -126,17 +119,12 @@ public class TransactionsFragment extends Fragment {
transactionListViewModel.initTransactionList(orderSelected.getField(),etTransactionSearch.getText().toString());
transactionsLiveData = transactionListViewModel.getTransactionList();
final Fragment fragment = this;
transactionsLiveData.observe(this, new Observer<PagedList<CryptoCoinTransactionExtended>>() {
@Override
public void onChanged(@Nullable PagedList<CryptoCoinTransactionExtended> transactions) {
transactionListAdapter.submitList(transactions);
if(transactions != null && transactions.size() > 0){
tvNoTransactions.setVisibility(View.INVISIBLE);
}
else{
tvNoTransactions.setVisibility(View.VISIBLE);
}
public void onChanged(@Nullable PagedList<CryptoCoinTransactionExtended> cryptoCoinTransactions) {
Log.i("Transactions","Transactions have change! Count:"+cryptoCoinTransactions.size());
transactionListView.setData(cryptoCoinTransactions, fragment);
}
});
}
@ -148,7 +136,7 @@ public class TransactionsFragment extends Fragment {
}
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("amount","Amount",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.content.Context;
import android.util.Log;
import com.google.common.primitives.UnsignedLong;
import org.bitcoinj.core.ECKey;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
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.application.constant.BitsharesConstant;
import cy.agorise.crystalwallet.dao.AccountSeedDao;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
import cy.agorise.crystalwallet.models.seed.BIP39;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetEquivalentRequest;
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.ValidateBitsharesLTMUpgradeRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
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.BlockHeader;
import cy.agorise.graphenej.models.HistoricalTransfer;
import cy.agorise.graphenej.objects.Memo;
import cy.agorise.graphenej.operations.TransferOperationBuilder;
/**
@ -69,6 +64,8 @@ import cy.agorise.graphenej.operations.TransferOperationBuilder;
*/
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 DEFAULT_TIME_ZONE = "GMT";
@ -92,11 +89,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(fetch)[0];
fetch.setId(idAccount);
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);
request.success(fetch);
}
@ -137,11 +129,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
long[] idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
grapheneAccount.setId(idAccount[0]);
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);
}
@ -158,14 +145,8 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
GrapheneAccount fetch = (GrapheneAccount) answer;
grapheneAccount.setName(fetch.getName());
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
grapheneAccount.setId(idAccount);
db.cryptoNetAccountDao().insertCryptoNetAccount(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);
}
@ -176,14 +157,8 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
});
}else {
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
grapheneAccount.setId(idAccount);
db.cryptoNetAccountDao().insertCryptoNetAccount(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);
}
}
@ -204,11 +179,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
info.setAccountId(fetch.getAccountId());
grapheneAccount.setAccountId(fetch.getAccountId());
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);
}
@ -225,11 +195,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
info.setName(fetch.getName());
grapheneAccount.setName(fetch.getName());
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);
}
@ -239,11 +204,6 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
}
});
}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);
}
}
@ -252,7 +212,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
private void subscribeBitsharesAccount(long accountId, String accountBitsharesID, Context context){
GrapheneApiGenerator.subscribeBitsharesAccount(accountId,accountBitsharesID,context);
BitsharesAccountManager.refreshAccountTransactions(accountId,context);
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesID,CryptoNet.BITSHARES,context);
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesID,context);
}
/**
@ -261,103 +221,27 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
*/
@Override
public void onNewRequest(CryptoNetInfoRequest request) {
if(request.getCoin().equals(CryptoCoin.BITSHARES)) {
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 CryptoNetEquivalentRequest) {
this.getEquivalentValue((CryptoNetEquivalentRequest) request);
} else if (request instanceof ValidateCreateBitsharesAccountRequest) {
this.validateCreateAccount((ValidateCreateBitsharesAccountRequest) request);
} else if (request instanceof ValidateBitsharesLTMUpgradeRequest) {
this.validateLTMAccountUpgrade((ValidateBitsharesLTMUpgradeRequest) request);
} else if (request instanceof GetBitsharesAccountNameCacheRequest) {
this.getBitsharesAccountNameCacheRequest((GetBitsharesAccountNameCacheRequest) 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 CryptoNetEquivalentRequest){
this.getEquivalentValue((CryptoNetEquivalentRequest) request);
}else if (request instanceof ValidateCreateBitsharesAccountRequest){
this.validateCreateAccount((ValidateCreateBitsharesAccountRequest) request);
}else if (request instanceof ValidateBitsharesLTMUpgradeRequest){
this.validateLTMAccountUpgrade((ValidateBitsharesLTMUpgradeRequest) request);
}else if (request instanceof GetBitsharesAccountNameCacheRequest){
this.getBitsharesAccountNameCacheRequest((GetBitsharesAccountNameCacheRequest) request);
}else{
//TODO not implemented
System.out.println("Error request not implemented " + request.getClass().getName());
}
//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.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
*/
@ -423,7 +307,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.NO_ACCOUNT_DATA);
}
});
GrapheneApiGenerator.getAccountById((String)answer,CryptoNet.BITSHARES,getAccountInfo);
GrapheneApiGenerator.getAccountById((String)answer,getAccountInfo);
}
@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){
@ -488,7 +372,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
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)))
.setFee(new AssetAmount(UnsignedLong.valueOf(0), feeAsset));
if (sendRequest.getMemo() != null) {
try {
//TODO change authority for memo
Address fromAddress = new Address(fromUserAccount.getActive().getKeyAuthList().get(0).getKey(), "BTS");
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
}
//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());
@ -693,7 +570,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
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);
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);
ArrayList<String> assetNames = new ArrayList<>();
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;
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<>();
assets.add(transfer.getOperation().getAssetAmount().getAsset().getObjectId());
GrapheneApiGenerator.getAssetById(assets,CryptoNet.BITSHARES,assetRequest);
GrapheneApiGenerator.getAssetById(assets,assetRequest);
}else{
saveTransaction(transaction,info,transfer);
@ -842,7 +719,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
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.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.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) {
InputStream in = null;
try {
System.out.println("Bytes: "+Util.bytesToHex(inputBytes));
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048);
if(which == Util.XZ) {

View File

@ -3,74 +3,32 @@ package cy.agorise.crystalwallet.manager;
import android.content.Context;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.AddressFormatException;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionOutPoint;
import org.bitcoinj.crypto.ChildNumber;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.crypto.HDKeyDerivation;
import org.bitcoinj.script.Script;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import cy.agorise.crystalwallet.apigenerator.ApiRequest;
import cy.agorise.crystalwallet.apigenerator.ApiRequestListener;
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
import cy.agorise.crystalwallet.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.apigenerator.insightapi.BroadcastTransaction;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.requestmanagers.BitcoinSendRequest;
import cy.agorise.crystalwallet.requestmanagers.BitcoinUriParseRequest;
import cy.agorise.crystalwallet.requestmanagers.CalculateBitcoinUriRequest;
import cy.agorise.crystalwallet.requestmanagers.CreateBitcoinAccountRequest;
import cy.agorise.crystalwallet.models.GTxIO;
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
import cy.agorise.crystalwallet.models.GeneralTransaction;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
import cy.agorise.crystalwallet.requestmanagers.NextBitcoinAccountAddressRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateBitcoinAddressRequest;
import cy.agorise.crystalwallet.requestmanagers.GeneralAccountSendRequest;
import cy.agorise.graphenej.Util;
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
public void createAccountFromSeed(CryptoNetAccount account, ManagerRequest request, Context context) {
@ -82,333 +40,55 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
}
@Override
public void loadAccountFromDB(final CryptoNetAccount account, Context context) {
final CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
public void loadAccountFromDB(CryptoNetAccount account, Context 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
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);
}
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) {
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(btId);
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){
public void send(final GeneralAccountSendRequest request){
//TODO check server connection
//TODO validate to address
InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() {
InsightApiGenerator.getEstimateFee(request.getAccount().getCryptoNet(),new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
Transaction tx = new Transaction(cryptoCoin.getParameters());
Transaction tx = new Transaction(request.getAccount().getNetworkParam());
long currentAmount = 0;
long fee = -1;
long feeRate = (long)(((double)answer) * Math.pow(10,cryptoCoin.getPrecision()));
long feeRate = (Long) answer;
fee = 226 * feeRate;
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
db.bitcoinTransactionDao();
List<GeneralCoinAddress> addresses = request.getAccount().getAddresses();
List<GTxIO> utxos = new ArrayList();
for(GeneralCoinAddress address : addresses){
List<GTxIO> addrUtxos = address.getUTXos();
for(GTxIO addrUtxo : addrUtxos){
utxos.add(addrUtxo);
currentAmount += addrUtxo.getAmount();
if(currentAmount >= request.getAmount()+ fee){
break;
}
}
if(currentAmount >= request.getAmount() + fee){
break;
}
}
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(),db);
if(currentAmount< request.getAmount() + fee){
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
request.setStatus(GeneralAccountSendRequest.StatusCode.NO_BALANCE);
return;
}
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
//String to an address
Address toAddr = Address.fromBase58(cryptoCoin.getParameters(), request.getToAccount());
Address toAddr = Address.fromBase58(request.getAccount().getNetworkParam(), request.getToAccount());
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr);
/*if(request.getMemo()!= null && !request.getMemo().isEmpty()){
if(request.getMemo()!= null && !request.getMemo().isEmpty()){
String memo = request.getMemo();
if(request.getMemo().length()>40){
memo = memo.substring(0,40);
@ -419,270 +99,47 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
System.arraycopy(memo.getBytes(),0,scriptByte,2,memo.length());
Script memoScript = new Script(scriptByte);
tx.addOutput(Coin.valueOf(0),memoScript);
}*/
}
//Change address
long remain = currentAmount - request.getAmount() - fee;
if( remain > 0 ) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr;
if(btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size()<=0){
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());
}
Address changeAddr = Address.fromBase58(request.getAccount().getNetworkParam(), request.getAccount().getNextChangeAddress());
tx.addOutput(Coin.valueOf(remain), changeAddr);
}
for(BitcoinTransactionGTxIO utxo: utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId());
for(GTxIO utxo: utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getTransaction().getTxid());
Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash);
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress());
ECKey addrKey;
if(btAddress.isChange()){
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
}else{
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
TransactionOutPoint outPoint = new TransactionOutPoint(request.getAccount().getNetworkParam(), utxo.getIndex(), txHash);
if(utxo.getAddress().getKey().isPubKeyOnly()){
if(utxo.getAddress().isIsChange()){
utxo.getAddress().setKey(HDKeyDerivation.deriveChildKey(request.getAccount().getChangeKey(), new ChildNumber(utxo.getAddress().getIndex(), false)));
}else{
utxo.getAddress().setKey(HDKeyDerivation.deriveChildKey(request.getAccount().getExternalKey(), new ChildNumber(utxo.getAddress().getIndex(), false)));
}
}
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
tx.addSignedInput(outPoint, script, utxo.getAddress().getKey(), Transaction.SigHash.ALL, true);
}
InsightApiGenerator.broadcastTransaction(cryptoCoin,Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
InsightApiGenerator.broadcastTransaction(request.getAccount().getCryptoNet(),Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
request.setStatus(GeneralAccountSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
request.setStatus(GeneralAccountSendRequest.StatusCode.PETITION_FAILED);
}
}));
}
@Override
public void fail(int idPetition) {
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
request.setStatus(GeneralAccountSendRequest.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

@ -1,21 +1,20 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import android.accounts.Account;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil;
import org.bitcoinj.core.Base58;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.crypto.HDKeyDerivation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import cy.agorise.crystalwallet.enums.SeedType;
import cy.agorise.crystalwallet.models.seed.BIP39;
@ -116,6 +115,8 @@ public class AccountSeed {
BufferedReader reader = null;
switch (type) {
case BRAINKEY:
try {
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("brainkeydict.txt"), "UTF-8"));
@ -129,7 +130,6 @@ public class AccountSeed {
} catch (IOException e) {
e.printStackTrace();
}
break;
case BIP39:
try {
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("bip39dict.txt"), "UTF-8"));
@ -139,7 +139,6 @@ public class AccountSeed {
} catch (IOException e) {
e.printStackTrace();
}
break;
}
return null;
}
@ -150,15 +149,6 @@ public class AccountSeed {
return new BrainKey(this.mMasterSeed,0).getPrivateKey();
case BIP39:
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;
}

View File

@ -1,93 +0,0 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.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,107 +0,0 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.annotation.NonNull;
/**
* 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,23 +0,0 @@
package cy.agorise.crystalwallet.models;
import androidx.room.Embedded;
import androidx.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 androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
/**
* Represents a Bitcoin alike Transaction Inputs and Outputs
*
* Created by Henry Varona on 10/2/2018.
*/
@Entity(
tableName="bitcoin_transaction_gt_io",
primaryKeys = {"bitcoin_transaction_id", "io_index", "is_output"},
foreignKeys = {
@ForeignKey(
entity = BitcoinTransaction.class,
parentColumns = "crypto_coin_transaction_id",
childColumns = "bitcoin_transaction_id",
onDelete = ForeignKey.CASCADE
)
}
)
public class BitcoinTransactionGTxIO {
/**
* The id of the bitcoin transaction
*/
@ColumnInfo(name="bitcoin_transaction_id")
protected long bitcoinTransactionId;
/**
* The index in the transaction
*/
@ColumnInfo(name="io_index")
protected int index;
/**
* The address of the input or output
*/
@ColumnInfo(name="address")
protected String address;
/**
* determines if this is an input or output
*/
@ColumnInfo(name="is_output")
protected boolean isOutput;
@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

@ -1,12 +1,12 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.annotation.NonNull;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
/**
* Represents a cache of a Bitshares Account name

View File

@ -1,9 +1,9 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.TypeConverters;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.TypeConverters;
import cy.agorise.crystalwallet.dao.converters.Converters;

View File

@ -1,13 +1,14 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
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.ArrayList;
import java.util.List;

View File

@ -1,12 +1,12 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil;
import cy.agorise.crystalwallet.enums.CryptoNet;

View File

@ -1,13 +1,15 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil;
import cy.agorise.crystalwallet.enums.CryptoCoin;
/**
* Represents a balance of a specific asset from a CryptoNet

View File

@ -1,16 +1,18 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Ignore;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
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;
import cy.agorise.crystalwallet.enums.CryptoCoin;
/**
* Represents a generic CryptoNet Transaction
*
@ -18,13 +20,9 @@ import java.util.Date;
*/
@Entity(
tableName="crypto_coin_transaction",
primaryKeys = {
},
indices={
@Index(value={"account_id"}),
@Index(value={"id_currency"}),
@Index(value={"date", "account_id", "id_currency", "from", "to"},unique=true)
@Index(value={"id_currency"})
},
foreignKeys = {
@ForeignKey(
@ -68,7 +66,7 @@ public class CryptoCoinTransaction {
* The id of the account assoiciated, this is used for the foreign key definition
*/
@ColumnInfo(name="account_id")
protected long accountId = -1;
protected long accountId;
/**
* The amount of asset is moved in this transaction
*/

View File

@ -1,10 +1,14 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Embedded;
import androidx.room.Entity;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
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.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;

View File

@ -1,10 +1,10 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import android.arch.persistence.room.TypeConverters;
import cy.agorise.crystalwallet.dao.converters.Converters;
import cy.agorise.crystalwallet.enums.CryptoNet;
@ -45,15 +45,6 @@ public class CryptoCurrency {
@ColumnInfo(name = "precision")
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() {
return mId;
}

View File

@ -1,10 +1,10 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import java.util.Date;

View File

@ -1,14 +1,14 @@
package cy.agorise.crystalwallet.models;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Ignore;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
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 cy.agorise.crystalwallet.enums.CryptoNet;

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