Compare commits
212 commits
Author | SHA1 | Date | |
---|---|---|---|
|
b12b3b9546 | ||
|
d04e847bba | ||
|
fe1068bcdf | ||
|
af4a4aca8b | ||
|
450a7c285b | ||
|
08df53730b | ||
|
618e71a6ac | ||
|
52f75eb3cf | ||
|
4bf1c14bb8 | ||
|
a32f7c9eb0 | ||
|
bfe65ac1a7 | ||
|
ea57899027 | ||
|
2c431ef4e0 | ||
|
a13bbadd2e | ||
|
1514d32457 | ||
|
7ddc2745b2 | ||
|
0dd9aecbf3 | ||
|
56a3c006cc | ||
|
178a0de26b | ||
|
c2575c7ab8 | ||
|
b10b385a83 | ||
|
5ceffbec2f | ||
|
0e2d33848b | ||
|
ddabac3911 | ||
|
a31efc16e4 | ||
|
0ebc6adfe2 | ||
|
93e71887a8 | ||
|
534cee187b | ||
|
469e7b08e4 | ||
|
5b8d12f886 | ||
|
0c8157a659 | ||
|
a0c01d6843 | ||
|
8502272b25 | ||
|
a3c0504265 | ||
|
96881f3292 | ||
|
aec93ddb22 | ||
|
86c96b1c3a | ||
|
c2416e64ad | ||
|
db4827456f | ||
|
0c64e78e89 | ||
|
9a63c25ee4 | ||
|
62541e1863 | ||
|
7367b33bb2 | ||
|
3ac651c0a4 | ||
|
ecf5335ea3 | ||
|
dfca4b8c53 | ||
|
73ba419b66 | ||
|
ce1df325d8 | ||
|
2e2ee01052 | ||
|
5aa7175016 | ||
|
6e4b66a5e3 | ||
|
83c95a35a8 | ||
|
683883ca0e | ||
|
b6cddedbd4 | ||
|
a11f74f6a5 | ||
|
91ef2d0e9a | ||
|
193f426739 | ||
|
719d6769fc | ||
|
0126d6d114 | ||
|
14a405f67c | ||
|
9c6db3a6ea | ||
|
6e81192b37 | ||
|
8ff53de0ae | ||
|
01e67ce258 | ||
|
42c48d31ea | ||
|
0e37879f02 | ||
|
ca4662867d | ||
|
9df1db6669 | ||
|
fa952d9a36 | ||
|
dc6114bb10 | ||
|
e9f77c4981 | ||
|
043325b887 | ||
|
51498192c6 | ||
|
5965528abe | ||
|
6c0d936b67 | ||
|
960dd67394 | ||
|
4cd304d732 | ||
|
36d97e8166 | ||
|
7ae875e208 | ||
|
10cc88c8d3 | ||
|
9a1dc0548d | ||
|
b5bc9e88c7 | ||
|
b426076eea | ||
|
d456ee49a8 | ||
|
c4ac6b4a29 | ||
|
ae3ed3725d | ||
|
71c26c0ddf | ||
|
0bb428a658 | ||
|
753a4a5943 | ||
|
ba96d999ff | ||
|
a21796d2d0 | ||
|
b05cf62daf | ||
|
7889d4f242 | ||
|
2ca94de241 | ||
|
e8ceb88c6e | ||
|
ac95b66511 | ||
|
c216dfa209 | ||
|
04d3a0d2e6 | ||
|
418749ea6a | ||
|
4ba6299822 | ||
|
b3a267fb47 | ||
|
c3c6677faa | ||
|
8e55afad55 | ||
|
41a3b1c172 | ||
|
cd00923ebc | ||
|
2027677956 | ||
|
b3442a511e | ||
|
6b37db9279 | ||
|
4743042c7e | ||
|
0019385827 | ||
|
03e03f2fb1 | ||
|
e24b355281 | ||
|
3c0e2058bb | ||
|
b73c77e86f | ||
|
356300fed4 | ||
|
7681523252 | ||
|
76a53c12e1 | ||
|
8a7b41ad1d | ||
|
3941585740 | ||
|
c554471115 | ||
|
a4c6b1cfb1 | ||
|
d2668bc04e | ||
|
95bdc725c0 | ||
|
91bc799310 | ||
|
ed7dc5424e | ||
|
d367373d8e | ||
|
b8fd519b1a | ||
|
8f2fc92945 | ||
|
319321c94b | ||
|
cd160c9832 | ||
|
013a3b841f | ||
|
3d9d57d0fa | ||
|
f705de8c60 | ||
|
d3a55fae02 | ||
|
ecfe5ce8e5 | ||
|
fe5603c0b7 | ||
|
332eced879 | ||
|
19aa8e6b7f | ||
|
6606e8c238 | ||
|
f403ee22d4 | ||
|
9a75330207 | ||
|
2e13b16a71 | ||
|
3019cc8422 | ||
|
c30fd729be | ||
|
b33bbc11fc | ||
|
ad65111f92 | ||
|
a64c5eff45 | ||
|
9020608a07 | ||
|
046e21d725 | ||
|
b4cc708970 | ||
|
012aea807e | ||
|
074e37076d | ||
|
24dba53c5f | ||
|
09ce271c30 | ||
|
0928a5bc81 | ||
|
bd6a27f15b | ||
|
df04be0a6c | ||
|
4fee5de10b | ||
|
62edb37143 | ||
|
3767483945 | ||
|
7183c0d803 | ||
|
f82b90e0ee | ||
|
64866632d2 | ||
|
493b00c4f8 | ||
|
303011e419 | ||
|
be679e655f | ||
|
d788ceab9a | ||
|
85b1015e9f | ||
|
cf4b1f038d | ||
|
a4819ecd22 | ||
|
ab9df5d786 | ||
|
9fa7ddf178 | ||
|
96feaf31cd | ||
|
62e205ccfe | ||
|
53066696ce | ||
|
86c16bbb7b | ||
|
b55d22324a | ||
|
a54363a9ef | ||
|
1545f0e10b | ||
|
09ae09db1b | ||
|
8b4fb2d69d | ||
|
6a5ac7cc58 | ||
|
f43c6aa1af | ||
|
546db50590 | ||
|
a21446bc7f | ||
|
c1b8c11d74 | ||
|
cc69c2676e | ||
|
5ad7d32bbf | ||
|
05d04b69af | ||
|
d2e388e5de | ||
|
fbfa97754f | ||
|
94267c6cc3 | ||
|
751cb46922 | ||
|
1cc21c73be | ||
|
6b39722f89 | ||
|
d86fe35a6b | ||
|
ad0c14e389 | ||
|
e9a147e344 | ||
|
31f809048f | ||
|
0fc4392a52 | ||
|
17c61b12a7 | ||
|
b1e8e4dfe7 | ||
|
14c307ccbc | ||
|
7db8212ab4 | ||
|
6eab51c89f | ||
|
d16f2d7378 | ||
|
037787afd0 | ||
|
0c583fff18 | ||
|
dae073dc62 | ||
|
2e6c61f88a | ||
|
2c5661c587 | ||
|
53cf2ef25b |
184 changed files with 7638 additions and 2577 deletions
|
@ -1,6 +1,8 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
apply plugin: 'kotlin-kapt' // add this line
|
||||||
|
|
||||||
|
|
||||||
kapt {
|
kapt {
|
||||||
generateStubs = true
|
generateStubs = true
|
||||||
|
@ -9,14 +11,19 @@ kapt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven { url 'https://maven.google.com' }
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 28
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "cy.agorise.crystalwallet"
|
applicationId "cy.agorise.crystalwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 28
|
||||||
versionCode 3
|
versionCode 5
|
||||||
versionName "0.3M.alpha"
|
versionName "0.5M.alpha"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
useSupportLibrary true
|
useSupportLibrary true
|
||||||
|
@ -28,6 +35,9 @@ android {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
resValue("string", "PORT_NUMBER", "8081")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
|
@ -52,51 +62,44 @@ dependencies {
|
||||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
|
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
|
||||||
exclude group: 'com.android.support', module: 'support-annotations'
|
exclude group: 'com.android.support', module: 'support-annotations'
|
||||||
})
|
})
|
||||||
|
implementation( 'com.github.thekhaeng:pushdown-anim-click:1.1.1' ){
|
||||||
|
exclude group: 'com.android.support'
|
||||||
|
}
|
||||||
implementation 'com.jaredrummler:material-spinner:1.2.5'
|
implementation 'com.jaredrummler:material-spinner:1.2.5'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.1.60"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
//testCompile 'com.android.support.test:runner:1.0.1'
|
//testCompile 'com.android.support.test:runner:1.0.1'
|
||||||
implementation 'com.afollestad.material-dialogs:core:0.9.6.0' //DTVV Thrusday 31 July 2018
|
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
|
||||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||||
implementation 'com.github.bumptech.glide:glide:4.7.1'
|
implementation 'com.android.support:support-v4:28.0.0'
|
||||||
// Glide v4 uses this new annotation processor -- see https://bumptech.github.io/glide/doc/generatedapi.html
|
implementation 'com.android.support:design:28.0.0'
|
||||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
|
implementation 'com.android.support:cardview-v7:28.0.0'
|
||||||
implementation 'com.android.support:support-v4:27.1.1'
|
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
||||||
implementation 'com.android.support:design:27.1.1'
|
|
||||||
implementation 'com.android.support:cardview-v7:27.1.1'
|
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
|
||||||
implementation 'android.arch.lifecycle:runtime:1.1.1'
|
implementation 'android.arch.lifecycle:runtime:1.1.1'
|
||||||
implementation 'android.arch.lifecycle:extensions:1.1.1'
|
implementation 'android.arch.lifecycle:extensions:1.1.1'
|
||||||
implementation 'android.arch.paging:runtime:1.0.0'
|
implementation 'android.arch.paging:runtime:1.0.1'
|
||||||
implementation 'com.idescout.sql:sqlscout-server:2.0'
|
implementation 'com.idescout.sql:sqlscout-server:2.0'
|
||||||
implementation 'com.google.code.gson:gson:2.8.0'
|
implementation 'com.google.code.gson:gson:2.8.4'
|
||||||
implementation 'com.squareup.retrofit2:retrofit:2.2.0'
|
implementation 'com.squareup.retrofit2:retrofit:2.2.0'
|
||||||
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
|
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
|
||||||
implementation 'org.bitcoinj:bitcoinj-core:0.14.3'
|
implementation 'org.bitcoinj:bitcoinj-core:0.14.3'
|
||||||
implementation 'com.neovisionaries:nv-websocket-client:1.30'
|
implementation 'com.neovisionaries:nv-websocket-client:1.30'
|
||||||
implementation 'org.tukaani:xz:1.6'
|
|
||||||
implementation 'com.jakewharton:butterknife:8.8.1'
|
implementation 'com.jakewharton:butterknife:8.8.1'
|
||||||
implementation 'com.github.bilthon:graphenej:0.4.6'
|
implementation 'com.github.bilthon:graphenej:0.4.6'
|
||||||
implementation 'com.google.zxing:core:3.3.1'
|
|
||||||
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||||
implementation 'com.github.sjaramillo10:AnimatedTabLayout:1.0.3'
|
|
||||||
|
|
||||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
|
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
|
||||||
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
||||||
|
|
||||||
//testCompile 'junit:junit: 4.12'
|
//testCompile 'junit:junit: 4.12'
|
||||||
testImplementation 'org.mockito:mockito-core:1.10.19'
|
testImplementation 'org.mockito:mockito-core:2.19.0'
|
||||||
implementation 'android.arch.persistence.room:runtime:1.1.0'
|
implementation 'android.arch.persistence.room:runtime:1.1.1'
|
||||||
|
|
||||||
|
kapt 'android.arch.persistence.room:runtime:1.1.1'
|
||||||
|
kapt 'android.arch.persistence.room:compiler:1.1.1'
|
||||||
|
|
||||||
kapt 'android.arch.persistence.room:runtime:1.1.0'
|
|
||||||
annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
|
|
||||||
kapt 'android.arch.lifecycle:compiler:1.1.1'
|
kapt 'android.arch.lifecycle:compiler:1.1.1'
|
||||||
annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
|
|
||||||
kapt 'android.arch.persistence.room:compiler:1.1.0'
|
|
||||||
annotationProcessor 'android.arch.persistence.room:compiler:1.1.0'
|
|
||||||
kapt 'com.jakewharton:butterknife-compiler:8.8.1'
|
kapt 'com.jakewharton:butterknife-compiler:8.8.1'
|
||||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
|
|
||||||
|
|
||||||
implementation 'com.squareup.picasso:picasso:2.5.2'
|
|
||||||
implementation 'com.github.esafirm.android-image-picker:imagepicker:1.11.1'
|
implementation 'com.github.esafirm.android-image-picker:imagepicker:1.11.1'
|
||||||
implementation 'id.zelory:compressor:2.1.0'
|
implementation 'id.zelory:compressor:2.1.0'
|
||||||
implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.7'
|
implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.7'
|
||||||
|
@ -108,6 +111,14 @@ dependencies {
|
||||||
exclude group: 'org.json', module: 'json'
|
exclude group: 'org.json', module: 'json'
|
||||||
}
|
}
|
||||||
|
|
||||||
kapt "android.arch.lifecycle:compiler:1.1.1"
|
// Glide dependencies
|
||||||
kapt "android.arch.persistence.room:compiler:1.1.0"
|
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'
|
||||||
}
|
}
|
||||||
|
|
7
app/proguard-rules.pro
vendored
7
app/proguard-rules.pro
vendored
|
@ -23,3 +23,10 @@
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||||
|
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||||
|
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||||
|
**[] $VALUES;
|
||||||
|
public *;
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.NFC" />
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".application.CrystalApplication"
|
android:name=".application.CrystalApplication"
|
||||||
|
@ -39,6 +40,10 @@
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".activities.AccountSeedsManagementActivity" >
|
<activity android:name=".activities.AccountSeedsManagementActivity" >
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity android:name=".activities.AccountSeedSettingsActivity"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
|
android:windowSoftInputMode="adjustPan">
|
||||||
|
</activity>
|
||||||
<activity android:name=".activities.ImportSeedActivity" >
|
<activity android:name=".activities.ImportSeedActivity" >
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".activities.SendTransactionActivity" >
|
<activity android:name=".activities.SendTransactionActivity" >
|
||||||
|
|
1
app/src/main/assets/crystal_eula.html
Normal file
1
app/src/main/assets/crystal_eula.html
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 30 KiB |
|
@ -0,0 +1,134 @@
|
||||||
|
package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.arch.lifecycle.Observer;
|
||||||
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.design.widget.TabLayout;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.FragmentManager;
|
||||||
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.fragments.BitsharesSettingsFragment;
|
||||||
|
import cy.agorise.crystalwallet.fragments.GeneralAccountSeedCoinSettingsFragment;
|
||||||
|
import cy.agorise.crystalwallet.fragments.GeneralAccountSeedFragment;
|
||||||
|
import cy.agorise.crystalwallet.fragments.GeneralCryptoNetAccountSettingsFragment;
|
||||||
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
|
||||||
|
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by henry varona on 10/29/18.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AccountSeedSettingsActivity extends AppCompatActivity{
|
||||||
|
|
||||||
|
@BindView(R.id.ivGoBack)
|
||||||
|
public ImageView ivGoBack;
|
||||||
|
|
||||||
|
@BindView(R.id.pager)
|
||||||
|
public ViewPager mPager;
|
||||||
|
|
||||||
|
public SettingsPagerAdapter settingsPagerAdapter;
|
||||||
|
|
||||||
|
|
||||||
|
@BindView(R.id.tvBuildVersion)
|
||||||
|
public TextView tvBuildVersion;
|
||||||
|
|
||||||
|
@BindView(R.id.tabs)
|
||||||
|
public TabLayout tabs;
|
||||||
|
|
||||||
|
private AccountSeed accountSeed;
|
||||||
|
|
||||||
|
@BindView(R.id.ivAppBarAnimation)
|
||||||
|
ImageView ivAppBarAnimation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.account_seed_activity_settings);
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
final AccountSeedSettingsActivity thisActivity = this;
|
||||||
|
|
||||||
|
long accountSeedId = getIntent().getLongExtra("SEED_ID",-1);
|
||||||
|
|
||||||
|
if (accountSeedId > -1) {
|
||||||
|
AccountSeedViewModel accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class);
|
||||||
|
accountSeedViewModel.loadSeed(accountSeedId);
|
||||||
|
LiveData<AccountSeed> accountSeedLiveData = accountSeedViewModel.getAccountSeed();
|
||||||
|
|
||||||
|
accountSeedLiveData.observe(this, new Observer<AccountSeed>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable AccountSeed accountSeed) {
|
||||||
|
thisActivity.accountSeed = accountSeed;
|
||||||
|
|
||||||
|
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
|
||||||
|
mPager.setAdapter(settingsPagerAdapter);
|
||||||
|
|
||||||
|
TabLayout tabLayout = findViewById(R.id.tabs);
|
||||||
|
|
||||||
|
mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
|
||||||
|
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
// Sets AppBar animation
|
||||||
|
Glide.with(this)
|
||||||
|
.load(R.drawable.appbar_background)
|
||||||
|
.apply(new RequestOptions().centerCrop())
|
||||||
|
.into(ivAppBarAnimation);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SettingsPagerAdapter extends FragmentStatePagerAdapter {
|
||||||
|
SettingsPagerAdapter(FragmentManager fm) {
|
||||||
|
super(fm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
switch (position){
|
||||||
|
case 0:
|
||||||
|
return GeneralAccountSeedFragment.newInstance(accountSeed.getId());
|
||||||
|
case 1:
|
||||||
|
return GeneralAccountSeedCoinSettingsFragment.newInstance(accountSeed.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
int tabCount = 2;
|
||||||
|
|
||||||
|
return tabCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.ivGoBack)
|
||||||
|
public void goBack(){
|
||||||
|
onBackPressed();
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,9 @@ import android.view.SurfaceView;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
@ -37,12 +40,13 @@ public class AccountSettingsActivity extends AppCompatActivity{
|
||||||
|
|
||||||
public SettingsPagerAdapter settingsPagerAdapter;
|
public SettingsPagerAdapter settingsPagerAdapter;
|
||||||
|
|
||||||
@BindView(R.id.surface_view)
|
|
||||||
public SurfaceView mSurfaceView;
|
|
||||||
|
|
||||||
@BindView(R.id.tvBuildVersion)
|
@BindView(R.id.tvBuildVersion)
|
||||||
public TextView tvBuildVersion;
|
public TextView tvBuildVersion;
|
||||||
|
|
||||||
|
@BindView(R.id.ivAppBarAnimation)
|
||||||
|
ImageView ivAppBarAnimation;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -52,27 +56,11 @@ public class AccountSettingsActivity extends AppCompatActivity{
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
// Appbar animation
|
// Sets AppBar animation
|
||||||
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
Glide.with(this)
|
||||||
@Override
|
.load(R.drawable.appbar_background)
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
.apply(new RequestOptions().centerCrop())
|
||||||
//Log.d(TAG,"surfaceCreated");
|
.into(ivAppBarAnimation);
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(AccountSettingsActivity.this, R.raw.appbar_background);
|
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
|
||||||
mediaPlayer.setLooping(true);
|
|
||||||
mediaPlayer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
|
||||||
//Log.d(TAG,"surfaceChanged");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
||||||
//Log.d(TAG,"surfaceDestroyed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
|
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
|
||||||
mPager.setAdapter(settingsPagerAdapter);
|
mPager.setAdapter(settingsPagerAdapter);
|
||||||
|
|
|
@ -18,10 +18,12 @@ import android.provider.MediaStore;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.esafirm.imagepicker.features.ImagePicker;
|
import com.esafirm.imagepicker.features.ImagePicker;
|
||||||
import com.esafirm.imagepicker.model.Image;
|
import com.esafirm.imagepicker.model.Image;
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
//import com.nicdahlquist.pngquant.LibPngQuant;
|
//import com.nicdahlquist.pngquant.LibPngQuant;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -55,8 +57,11 @@ public class AccountsActivity extends AppCompatActivity {
|
||||||
@BindView(R.id.tvClose)
|
@BindView(R.id.tvClose)
|
||||||
TextView tvClose;
|
TextView tvClose;
|
||||||
|
|
||||||
@BindView(R.id.vAccountList)
|
//@BindView(R.id.vAccountList)
|
||||||
CryptoNetAccountListView vAccountList;
|
//CryptoNetAccountListView vAccountList;
|
||||||
|
|
||||||
|
@BindView(R.id.vAccountSeedList)
|
||||||
|
AccountSeedListView vAccountSeedList;
|
||||||
|
|
||||||
@BindView(R.id.user_img)
|
@BindView(R.id.user_img)
|
||||||
CircleImageView userImg;
|
CircleImageView userImg;
|
||||||
|
@ -74,14 +79,29 @@ public class AccountsActivity extends AppCompatActivity {
|
||||||
setContentView(R.layout.activity_accounts);
|
setContentView(R.layout.activity_accounts);
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
CryptoNetAccountListViewModel crytpoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
|
/*
|
||||||
LiveData<List<CryptoNetAccount>> accountData = crytpoNetAccountListViewModel.getCryptoNetAccounts();
|
* Integration of library with button efects
|
||||||
vAccountList.setData(null);
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(fabAddAccount)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
goToAddAccount();
|
||||||
|
}
|
||||||
|
|
||||||
accountData.observe(this, new Observer<List<CryptoNetAccount>>() {
|
} );
|
||||||
|
|
||||||
|
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);
|
||||||
|
LiveData<List<AccountSeed>> accountSeedLD = accountSeedListViewModel.getAccountSeedList();
|
||||||
|
|
||||||
|
//CryptoNetAccountListViewModel crytpoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
|
||||||
|
//LiveData<List<CryptoNetAccount>> accountData = crytpoNetAccountListViewModel.getCryptoNetAccounts();
|
||||||
|
vAccountSeedList.setData(null);
|
||||||
|
|
||||||
|
accountSeedLD.observe(this, new Observer<List<AccountSeed>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(List<CryptoNetAccount> cryptoNetAccounts) {
|
public void onChanged(List<AccountSeed> accountsSeeds) {
|
||||||
vAccountList.setData(cryptoNetAccounts);
|
vAccountSeedList.setData(accountsSeeds);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,14 @@ import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
@ -29,10 +33,12 @@ public class BackupSeedActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@BindView(R.id.tvBrainKey)
|
@BindView(R.id.tvBrainKey)
|
||||||
TextView textfieldBrainkey;
|
TextView textfieldBrainkey;
|
||||||
@BindView(R.id.btnCancel)
|
@BindView(R.id.btnOK)
|
||||||
Button btnOk;
|
Button btnOk;
|
||||||
@BindView(R.id.btnCopy)
|
@BindView(R.id.btnCopy)
|
||||||
Button btnCopy;
|
Button btnCopy;
|
||||||
|
@BindView(R.id.btnCancel)
|
||||||
|
Button btnCancel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -41,6 +47,42 @@ public class BackupSeedActivity extends AppCompatActivity {
|
||||||
|
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCancel)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
btnCancelClick();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnOk)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
btnOkClick();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCopy)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
btnCopyClick();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
/*
|
||||||
|
* If comes from new account creation hide the cancel button
|
||||||
|
* */
|
||||||
|
Bundle b = getIntent().getExtras();
|
||||||
|
boolean newAccount = b.getBoolean("newAccount");
|
||||||
|
if(newAccount ){
|
||||||
|
ViewGroup layout = (ViewGroup) btnOk.getParent();
|
||||||
|
if(null!=layout) //for safety only as you are doing onClick
|
||||||
|
layout.removeView(btnOk);
|
||||||
|
//btnOk.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
long seedId = getIntent().getLongExtra("SEED_ID",-1);
|
long seedId = getIntent().getLongExtra("SEED_ID",-1);
|
||||||
|
|
||||||
if (seedId > -1) {
|
if (seedId > -1) {
|
||||||
|
@ -56,6 +98,14 @@ public class BackupSeedActivity extends AppCompatActivity {
|
||||||
accountSeedViewModel.loadSeed(seedId);
|
accountSeedViewModel.loadSeed(seedId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* The first time you create the account, the "seed" is showed propertly in this window,
|
||||||
|
* but when you want to check it again the "seed" does not exist anymore and
|
||||||
|
* for this cause the program gets into this point and finish the window
|
||||||
|
*
|
||||||
|
* */
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,6 @@ import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Typeface;
|
|
||||||
import android.media.MediaPlayer;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.design.widget.TabLayout;
|
import android.support.design.widget.TabLayout;
|
||||||
|
@ -20,18 +17,10 @@ import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.Spannable;
|
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.style.ForegroundColorSpan;
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.animation.LinearInterpolator;
|
import android.view.animation.LinearInterpolator;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
@ -48,7 +37,6 @@ import cy.agorise.crystalwallet.fragments.MerchantsFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.ReceiveTransactionFragment;
|
import cy.agorise.crystalwallet.fragments.ReceiveTransactionFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.SendTransactionFragment;
|
import cy.agorise.crystalwallet.fragments.SendTransactionFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.TransactionsFragment;
|
import cy.agorise.crystalwallet.fragments.TransactionsFragment;
|
||||||
import cy.agorise.crystalwallet.views.natives.GIFView;
|
|
||||||
import de.hdodenhof.circleimageview.CircleImageView;
|
import de.hdodenhof.circleimageview.CircleImageView;
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
|
||||||
|
|
||||||
|
@ -73,8 +61,8 @@ public class BoardActivity extends CustomActivity {
|
||||||
@BindView(R.id.fabAddContact)
|
@BindView(R.id.fabAddContact)
|
||||||
public FloatingActionButton fabAddContact;
|
public FloatingActionButton fabAddContact;
|
||||||
|
|
||||||
@BindView(R.id.imagevieGIF)
|
@BindView(R.id.ivAppBarAnimation)
|
||||||
public GIFView imagevieGIF;
|
ImageView ivAppBarAnimation;
|
||||||
|
|
||||||
public BoardPagerAdapter boardAdapter;
|
public BoardPagerAdapter boardAdapter;
|
||||||
|
|
||||||
|
@ -84,9 +72,6 @@ public class BoardActivity extends CustomActivity {
|
||||||
*/
|
*/
|
||||||
long cryptoNetAccountId;
|
long cryptoNetAccountId;
|
||||||
|
|
||||||
@BindView(R.id.surface_view)
|
|
||||||
public SurfaceView mSurfaceView;
|
|
||||||
|
|
||||||
@BindView(R.id.toolbar_user_img)
|
@BindView(R.id.toolbar_user_img)
|
||||||
public CircleImageView userImage;
|
public CircleImageView userImage;
|
||||||
|
|
||||||
|
@ -110,82 +95,11 @@ public class BoardActivity extends CustomActivity {
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
/*
|
// Sets AppBar animation
|
||||||
* Set the bubbles animation
|
Glide.with(this)
|
||||||
* */
|
.load(R.drawable.appbar_background)
|
||||||
//imagevieGIF.centerCrop();
|
.apply(new RequestOptions().centerCrop())
|
||||||
//imagevieGIF.load(R.raw.burbujas);
|
.into(ivAppBarAnimation);
|
||||||
|
|
||||||
/*
|
|
||||||
* Listener tabLayout to resalt text when clicked
|
|
||||||
* */
|
|
||||||
final TabLayout tabLayoutFinal = tabLayout;
|
|
||||||
// tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onTabSelected(final TabLayout.Tab tab) {
|
|
||||||
//
|
|
||||||
// globalActivity.runOnUiThread(new Runnable() {
|
|
||||||
// @Override
|
|
||||||
// public void run() {
|
|
||||||
//
|
|
||||||
// LinearLayout tabLayout = (LinearLayout)((ViewGroup) tabLayoutFinal.getChildAt(0)).getChildAt(tab.getPosition());
|
|
||||||
// tabLayout.setBackgroundColor(Color.TRANSPARENT);
|
|
||||||
// TextView tabTextView = (TextView) tabLayout.getChildAt(1);
|
|
||||||
// //tabTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP ,50);
|
|
||||||
// Spannable WordtoSpan = new SpannableString(tabTextView.getText());
|
|
||||||
// WordtoSpan.setSpan(new ForegroundColorSpan(Color.WHITE), 0, tabTextView.getText().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
// tabTextView.setText(WordtoSpan);
|
|
||||||
// tabTextView.setTypeface(tabTextView.getTypeface(), Typeface.BOLD);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onTabUnselected(final TabLayout.Tab tab) {
|
|
||||||
//
|
|
||||||
// globalActivity.runOnUiThread(new Runnable() {
|
|
||||||
// @Override
|
|
||||||
// public void run() {
|
|
||||||
//
|
|
||||||
// LinearLayout tabLayout = (LinearLayout)((ViewGroup) tabLayoutFinal.getChildAt(0)).getChildAt(tab.getPosition());
|
|
||||||
// TextView tabTextView = (TextView) tabLayout.getChildAt(1);
|
|
||||||
// //tabTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP ,50);
|
|
||||||
// Spannable WordtoSpan = new SpannableString(tabTextView.getText());
|
|
||||||
// WordtoSpan.setSpan(new ForegroundColorSpan(globalActivity.getResources().getColor(R.color.lightGrayClear)), 0, tabTextView.getText().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
// tabTextView.setText(WordtoSpan);
|
|
||||||
// tabTextView.setTypeface(tabTextView.getTypeface(), Typeface.NORMAL);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onTabReselected(TabLayout.Tab tab) {
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Appbar animation
|
|
||||||
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
|
||||||
@Override
|
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
|
||||||
//Log.d(TAG,"surfaceCreated");
|
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(BoardActivity.this, R.raw.appbar_background);
|
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
|
||||||
mediaPlayer.setLooping(true);
|
|
||||||
mediaPlayer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
|
||||||
//Log.d(TAG,"surfaceChanged");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
||||||
//Log.d(TAG,"surfaceDestroyed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
boardAdapter = new BoardPagerAdapter(getSupportFragmentManager());
|
boardAdapter = new BoardPagerAdapter(getSupportFragmentManager());
|
||||||
mPager.setAdapter(boardAdapter);
|
mPager.setAdapter(boardAdapter);
|
||||||
|
|
|
@ -3,18 +3,17 @@ package cy.agorise.crystalwallet.activities
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.support.design.widget.TextInputEditText
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import butterknife.ButterKnife
|
import com.thekhaeng.pushdownanim.PushDownAnim
|
||||||
import butterknife.OnClick
|
|
||||||
import butterknife.OnTextChanged
|
|
||||||
import com.vincent.filepicker.ToastUtil
|
import com.vincent.filepicker.ToastUtil
|
||||||
import cy.agorise.crystalwallet.R
|
import cy.agorise.crystalwallet.R
|
||||||
import cy.agorise.crystalwallet.dialogs.material.*
|
import cy.agorise.crystalwallet.dialogs.material.*
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest
|
import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateExistBitsharesAccountRequest
|
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.interfaces.UIValidatorListener
|
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.interfaces.UIValidatorListener
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation
|
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation.OnAccountExist
|
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation.OnAccountExist
|
||||||
|
@ -39,11 +38,6 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
* */
|
* */
|
||||||
setContentView(R.layout.create_seed)
|
setContentView(R.layout.create_seed)
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialice butterknife MVC
|
|
||||||
* */
|
|
||||||
ButterKnife.bind(this)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the controls to the validator
|
* Add the controls to the validator
|
||||||
* */
|
* */
|
||||||
|
@ -51,6 +45,14 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
this.fieldsValidator.add(tietPinConfirmation)
|
this.fieldsValidator.add(tietPinConfirmation)
|
||||||
this.fieldsValidator.add(tietAccountName)
|
this.fieldsValidator.add(tietAccountName)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button effects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCancel)
|
||||||
|
.setOnClickListener { finish() }
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCreate)
|
||||||
|
.setOnClickListener { createSeed() }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validations listener
|
* Validations listener
|
||||||
* */
|
* */
|
||||||
|
@ -87,20 +89,14 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
//Create the pin double validation
|
||||||
* Create the pin double validation
|
|
||||||
* */
|
|
||||||
val pinDoubleConfirmationValidationField = PinDoubleConfirmationValidationField(this, tietPin, tietPinConfirmation, uiValidatorListener)
|
val pinDoubleConfirmationValidationField = PinDoubleConfirmationValidationField(this, tietPin, tietPinConfirmation, uiValidatorListener)
|
||||||
|
|
||||||
/*
|
// Listener for the validation for success or fail
|
||||||
* Listener for the validation for success or fail
|
|
||||||
* */
|
|
||||||
tietPin?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field
|
tietPin?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field
|
||||||
tietPinConfirmation?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field
|
tietPinConfirmation?.setUiValidator(pinDoubleConfirmationValidationField) //Validator for the field
|
||||||
|
|
||||||
/*
|
// Account name validator
|
||||||
* Account name validator
|
|
||||||
* */
|
|
||||||
val bitsharesAccountNameValidation = BitsharesAccountNameValidation(this, tietAccountName, uiValidatorListener)
|
val bitsharesAccountNameValidation = BitsharesAccountNameValidation(this, tietAccountName, uiValidatorListener)
|
||||||
val onAccountExist = object : OnAccountExist {
|
val onAccountExist = object : OnAccountExist {
|
||||||
override fun onAccountExists() {
|
override fun onAccountExists() {
|
||||||
|
@ -114,58 +110,49 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
tietAccountName?.setUiValidator(bitsharesAccountNameValidation)
|
tietAccountName?.setUiValidator(bitsharesAccountNameValidation)
|
||||||
|
|
||||||
/*This button should not be enabled till all the fields be correctly filled*/
|
/*This button should not be enabled till all the fields be correctly filled*/
|
||||||
disableCreate()
|
btnCreate.isEnabled = false
|
||||||
|
|
||||||
/*
|
// Set the focus on the first field and show keyboard
|
||||||
* Set the focus on the fisrt field and show keyboard
|
|
||||||
* */
|
|
||||||
tilPin?.requestFocus()
|
tilPin?.requestFocus()
|
||||||
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
imm.showSoftInput(tilPin, InputMethodManager.SHOW_IMPLICIT)
|
imm.showSoftInput(tilPin, InputMethodManager.SHOW_IMPLICIT)
|
||||||
|
|
||||||
|
tietPin.afterTextChanged {
|
||||||
|
this.fieldsValidator.validate()
|
||||||
|
validateFieldsToContinue()
|
||||||
|
}
|
||||||
|
|
||||||
|
tietPinConfirmation.afterTextChanged {
|
||||||
|
this.fieldsValidator.validate()
|
||||||
|
validateFieldsToContinue()
|
||||||
|
}
|
||||||
|
|
||||||
|
tietAccountName.afterTextChanged {
|
||||||
|
this.fieldsValidator.validate()
|
||||||
|
validateFieldsToContinue()
|
||||||
|
}
|
||||||
|
|
||||||
|
btnCancel.setOnClickListener { finish() }
|
||||||
|
btnCreate.setOnClickListener { createSeed() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.tietPin, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
/**
|
||||||
internal fun afterPinChanged(editable: Editable) {
|
* Extension function to easily add a text watcher
|
||||||
this.fieldsValidator.validate()
|
*/
|
||||||
|
fun TextInputEditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
|
||||||
/*
|
this.addTextChangedListener(object :TextWatcher {
|
||||||
* Validate continue to create account
|
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||||
* */
|
}
|
||||||
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() {
|
fun createSeed() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -181,11 +168,10 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
questionDialog.setOnPositive(object : PositiveResponse{
|
questionDialog.setOnPositive(object : PositiveResponse{
|
||||||
override fun onPositive() {
|
override fun onPositive() {
|
||||||
|
|
||||||
// Make request to create a bitshare account
|
// Make request to create a bitshares account
|
||||||
var accountName:String = tietAccountName?.getText().toString().trim()
|
var accountName:String = tietAccountName?.getText().toString().trim()
|
||||||
val request = ValidateCreateBitsharesAccountRequest(accountName, applicationContext)
|
val request = ValidateCreateBitsharesAccountRequest(accountName, applicationContext)
|
||||||
|
|
||||||
//DTVV: Friday 27 July 2018
|
|
||||||
//Makes dialog to tell the user that the account is been created
|
//Makes dialog to tell the user that the account is been created
|
||||||
val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
|
val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
|
||||||
creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_DialogMessage))
|
creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_DialogMessage))
|
||||||
|
@ -200,11 +186,12 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
val intent = Intent(applicationContext, BackupSeedActivity::class.java)
|
val intent = Intent(applicationContext, BackupSeedActivity::class.java)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
intent.putExtra("SEED_ID", accountSeed.id)
|
intent.putExtra("SEED_ID", accountSeed.id)
|
||||||
|
intent.putExtra("newAccount", true)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
else if (request.status == ValidateCreateBitsharesAccountRequest.StatusCode.ACCOUNT_EXIST) {
|
else if (request.status == ValidateCreateBitsharesAccountRequest.StatusCode.ACCOUNT_EXIST) {
|
||||||
ToastUtil.getInstance(globalActivity).showToast(globalActivity.getString(R.string.Account_already_exists))
|
ToastUtil.getInstance(globalActivity).showToast(globalActivity.getString(R.string.Account_already_exists))
|
||||||
disableCreate()
|
btnCreate.isEnabled = false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fieldsValidator.validate()
|
fieldsValidator.validate()
|
||||||
|
@ -213,10 +200,7 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
|
|
||||||
(object : Thread() {
|
(object : Thread() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
|
/* Run thread*/
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Run thread*/
|
|
||||||
CryptoNetInfoRequests.getInstance().addRequest(request)
|
CryptoNetInfoRequests.getInstance().addRequest(request)
|
||||||
}
|
}
|
||||||
}).start()
|
}).start()
|
||||||
|
@ -242,85 +226,7 @@ class CreateSeedActivity : CustomActivity() {
|
||||||
result = true //Validation is correct
|
result = true //Validation is correct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the result is true so the user can continue to the creation of the account
|
||||||
/*
|
btnCreate.isEnabled = result
|
||||||
* If the result is true so the user can continue to the creation of the account
|
|
||||||
* */
|
|
||||||
if (result) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Show the dialog for connection with the server
|
|
||||||
* */
|
|
||||||
val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
|
|
||||||
creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_Server_validation))
|
|
||||||
creatingAccountMaterialDialog.progress()
|
|
||||||
creatingAccountMaterialDialog.show()
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Validate the account does not exists
|
|
||||||
* */
|
|
||||||
val request = ValidateExistBitsharesAccountRequest(tietAccountName?.text.toString())
|
|
||||||
request.setListener {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dismiss the dialog of loading
|
|
||||||
* */
|
|
||||||
creatingAccountMaterialDialog.dismiss()
|
|
||||||
|
|
||||||
if (request.accountExists) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The account exists and is not valid
|
|
||||||
* */
|
|
||||||
tietAccountName.fieldValidatorModel.setInvalid()
|
|
||||||
tietAccountName.fieldValidatorModel.message = tietAccountName.resources.getString(R.string.account_name_already_exist)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Disaible button create
|
|
||||||
* */
|
|
||||||
disableCreate()
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Passed all validations
|
|
||||||
* */
|
|
||||||
tietAccountName.fieldValidatorModel.setValid()
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable button create
|
|
||||||
* */
|
|
||||||
enableCreate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CryptoNetInfoRequests.getInstance().addRequest(request)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Disaible button create
|
|
||||||
* */
|
|
||||||
disableCreate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable create button
|
|
||||||
* */
|
|
||||||
private fun enableCreate() {
|
|
||||||
runOnUiThread(Runnable {
|
|
||||||
btnCreate?.setBackgroundColor(resources.getColor(R.color.colorPrimary))
|
|
||||||
btnCreate?.setEnabled(true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Disable create button
|
|
||||||
* */
|
|
||||||
private fun disableCreate() {
|
|
||||||
runOnUiThread(Runnable {
|
|
||||||
btnCreate?.setEnabled(false)
|
|
||||||
btnCreate?.setBackground(resources.getDrawable(R.drawable.disable_style))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,15 +2,11 @@ package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.w3c.dom.Text;
|
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
|
@ -47,7 +43,7 @@ public class CryptoCoinTransactionReceiptActivity extends AppCompatActivity {
|
||||||
|
|
||||||
if (this.cryptoCoinTransactionId != -1) {
|
if (this.cryptoCoinTransactionId != -1) {
|
||||||
db = CrystalDatabase.getAppDatabase(this);
|
db = CrystalDatabase.getAppDatabase(this);
|
||||||
this.cryptoCoinTransactionLiveData = db.transactionDao().getById(this.cryptoCoinTransactionId);
|
this.cryptoCoinTransactionLiveData = db.transactionDao().getByIdLiveData(this.cryptoCoinTransactionId);
|
||||||
|
|
||||||
this.cryptoCoinTransactionLiveData.observe(this, new Observer<CryptoCoinTransaction>() {
|
this.cryptoCoinTransactionLiveData.observe(this, new Observer<CryptoCoinTransaction>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,12 +18,16 @@ import android.view.SurfaceView;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.fragments.BackupsSettingsFragment;
|
import cy.agorise.crystalwallet.fragments.BackupsSettingsFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.BitsharesSettingsFragment;
|
import cy.agorise.crystalwallet.fragments.BitsharesSettingsFragment;
|
||||||
|
import cy.agorise.crystalwallet.fragments.CryptoNetAccountActivationSettingsFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.GeneralCryptoNetAccountSettingsFragment;
|
import cy.agorise.crystalwallet.fragments.GeneralCryptoNetAccountSettingsFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.GeneralSettingsFragment;
|
import cy.agorise.crystalwallet.fragments.GeneralSettingsFragment;
|
||||||
import cy.agorise.crystalwallet.fragments.SecuritySettingsFragment;
|
import cy.agorise.crystalwallet.fragments.SecuritySettingsFragment;
|
||||||
|
@ -45,8 +49,6 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
|
||||||
|
|
||||||
public SettingsPagerAdapter settingsPagerAdapter;
|
public SettingsPagerAdapter settingsPagerAdapter;
|
||||||
|
|
||||||
@BindView(R.id.surface_view)
|
|
||||||
public SurfaceView mSurfaceView;
|
|
||||||
|
|
||||||
@BindView(R.id.tvBuildVersion)
|
@BindView(R.id.tvBuildVersion)
|
||||||
public TextView tvBuildVersion;
|
public TextView tvBuildVersion;
|
||||||
|
@ -56,6 +58,9 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
|
||||||
|
|
||||||
private CryptoNetAccount cryptoNetAccount;
|
private CryptoNetAccount cryptoNetAccount;
|
||||||
|
|
||||||
|
@BindView(R.id.ivAppBarAnimation)
|
||||||
|
ImageView ivAppBarAnimation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -93,27 +98,11 @@ public class CryptoNetAccountSettingsActivity extends AppCompatActivity{
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
// Appbar animation
|
// Sets AppBar animation
|
||||||
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
Glide.with(this)
|
||||||
@Override
|
.load(R.drawable.appbar_background)
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
.apply(new RequestOptions().centerCrop())
|
||||||
//Log.d(TAG,"surfaceCreated");
|
.into(ivAppBarAnimation);
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(CryptoNetAccountSettingsActivity.this, R.raw.appbar_background);
|
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
|
||||||
mediaPlayer.setLooping(true);
|
|
||||||
mediaPlayer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
|
||||||
//Log.d(TAG,"surfaceChanged");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
||||||
//Log.d(TAG,"surfaceDestroyed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,34 +1,35 @@
|
||||||
package cy.agorise.crystalwallet.activities;
|
package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.enums.CryptoNet;
|
import cy.agorise.crystalwallet.dialogs.material.CrystalLoading;
|
||||||
import cy.agorise.crystalwallet.enums.SeedType;
|
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
|
||||||
import cy.agorise.crystalwallet.manager.BitsharesAccountManager;
|
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
|
||||||
import cy.agorise.crystalwallet.models.AccountSeed;
|
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
|
||||||
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
|
||||||
import cy.agorise.crystalwallet.models.GrapheneAccount;
|
|
||||||
import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
|
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ImportBackupRequest;
|
import cy.agorise.crystalwallet.requestmanagers.ImportBitsharesAccountRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
|
|
||||||
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
|
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
|
|
||||||
import cy.agorise.crystalwallet.viewmodels.GrapheneAccountInfoViewModel;
|
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator;
|
import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator;
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
|
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
|
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
|
||||||
|
@ -40,23 +41,30 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
|
|
||||||
@BindView(R.id.etPin)
|
@BindView(R.id.etPin)
|
||||||
EditText etPin;
|
EditText etPin;
|
||||||
@BindView(R.id.tvPinError)
|
|
||||||
TextView tvPinError;
|
@BindView(R.id.txtErrorPIN)
|
||||||
|
TextView txtErrorPIN;
|
||||||
|
|
||||||
|
@BindView(R.id.txtErrorAccount)
|
||||||
|
TextView txtErrorAccount;
|
||||||
|
|
||||||
|
//@BindView(R.id.tvPinError)
|
||||||
|
//TextView tvPinError;
|
||||||
|
|
||||||
@BindView(R.id.etPinConfirmation)
|
@BindView(R.id.etPinConfirmation)
|
||||||
EditText etPinConfirmation;
|
EditText etPinConfirmation;
|
||||||
@BindView(R.id.tvPinConfirmationError)
|
//@BindView(R.id.tvPinConfirmationError)
|
||||||
TextView tvPinConfirmationError;
|
//TextView tvPinConfirmationError;
|
||||||
|
|
||||||
@BindView(R.id.etSeedWords)
|
@BindView(R.id.etSeedWords)
|
||||||
EditText etSeedWords;
|
EditText etSeedWords;
|
||||||
@BindView(R.id.tvSeedWordsError)
|
//@BindView(R.id.tvSeedWordsError)
|
||||||
TextView tvSeedWordsError;
|
//TextView tvSeedWordsError;
|
||||||
|
|
||||||
@BindView (R.id.etAccountName)
|
@BindView (R.id.etAccountName)
|
||||||
EditText etAccountName;
|
EditText etAccountName;
|
||||||
@BindView(R.id.tvAccountNameError)
|
//@BindView(R.id.tvAccountNameError)
|
||||||
TextView tvAccountNameError;
|
//TextView tvAccountNameError;
|
||||||
|
|
||||||
@BindView(R.id.btnImport)
|
@BindView(R.id.btnImport)
|
||||||
Button btnImport;
|
Button btnImport;
|
||||||
|
@ -64,6 +72,16 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
@BindView(R.id.btnCancel)
|
@BindView(R.id.btnCancel)
|
||||||
Button btnCancel;
|
Button btnCancel;
|
||||||
|
|
||||||
|
final Activity activity = this;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag to check correct PIN equality
|
||||||
|
* */
|
||||||
|
private boolean pinsOK = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -71,12 +89,213 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
|
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
btnImport.setEnabled(false);
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCancel)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnImport)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
importSeed();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initially the button CREATE WALLET should be disabled
|
||||||
|
* */
|
||||||
|
disableCreate();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a text change in any of the fields
|
||||||
|
* */
|
||||||
|
etPin.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate that PINs are equals
|
||||||
|
* */
|
||||||
|
validatePINS();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
* */
|
||||||
|
if(allFieldsAreOK()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
etPinConfirmation.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate that PINs are equals
|
||||||
|
* */
|
||||||
|
validatePINS();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
* */
|
||||||
|
if(allFieldsAreOK()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
etSeedWords.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate that PINs are equals
|
||||||
|
* */
|
||||||
|
validatePINS();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
* */
|
||||||
|
if(allFieldsAreOK()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hide error field
|
||||||
|
* */
|
||||||
|
clearErrors();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
etAccountName.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate that PINs are equals
|
||||||
|
//
|
||||||
|
validatePINS();
|
||||||
|
|
||||||
|
//
|
||||||
|
// If all is ready to continue enable the button, contrarie case disable it
|
||||||
|
//
|
||||||
|
if(allFieldsAreOK()){
|
||||||
|
enableCreate();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
disableCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class);
|
accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class);
|
||||||
importSeedValidator = new ImportSeedValidator(this.getApplicationContext(),etPin,etPinConfirmation,etAccountName,etSeedWords);
|
importSeedValidator = new ImportSeedValidator(this.getApplicationContext(),etPin,etPinConfirmation,etAccountName,etSeedWords);
|
||||||
importSeedValidator.setListener(this);
|
importSeedValidator.setListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void clearErrors(){
|
||||||
|
txtErrorPIN.setVisibility(View.INVISIBLE);
|
||||||
|
txtErrorAccount.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate that PINs are equals
|
||||||
|
* */
|
||||||
|
private void validatePINS(){
|
||||||
|
|
||||||
|
final String pin = etPin.getText().toString().trim();
|
||||||
|
final String confirmoPIN = etPinConfirmation.getText().toString().trim();
|
||||||
|
if(!pin.isEmpty() && !confirmoPIN.isEmpty()){
|
||||||
|
if(pin.compareTo(confirmoPIN)!=0){
|
||||||
|
pinsOK = false;
|
||||||
|
txtErrorPIN.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pinsOK = true;
|
||||||
|
clearErrors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pinsOK = false;
|
||||||
|
clearErrors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method to validate if all the fields are fill and correctly
|
||||||
|
* */
|
||||||
|
private boolean allFieldsAreOK(){
|
||||||
|
|
||||||
|
boolean complete = false;
|
||||||
|
if( etPin.getText().toString().trim().compareTo("")!=0 &&
|
||||||
|
etPinConfirmation.getText().toString().trim().compareTo("")!=0 &&
|
||||||
|
etSeedWords.getText().toString().trim().compareTo("")!=0 /*&&
|
||||||
|
etAccountName.getText().toString().trim().compareTo("")!=0*/){
|
||||||
|
if(pinsOK){
|
||||||
|
complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return complete;
|
||||||
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etPin,
|
@OnTextChanged(value = R.id.etPin,
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||||
void afterPinChanged(Editable editable) {
|
void afterPinChanged(Editable editable) {
|
||||||
|
@ -94,13 +313,11 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
void afterSeedWordsChanged(Editable editable) {
|
void afterSeedWordsChanged(Editable editable) {
|
||||||
this.importSeedValidator.validate();
|
this.importSeedValidator.validate();
|
||||||
}
|
}
|
||||||
|
/*@OnTextChanged(value = R.id.etAccountName,
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etAccountName,
|
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||||
void afterAccountNameChanged(Editable editable) {
|
void afterAccountNameChanged(Editable editable) {
|
||||||
this.importSeedValidator.validate();
|
this.importSeedValidator.validate();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
@OnClick(R.id.btnCancel)
|
@OnClick(R.id.btnCancel)
|
||||||
public void cancel(){
|
public void cancel(){
|
||||||
|
@ -113,68 +330,144 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
|
|
||||||
if (this.importSeedValidator.isValid()) {
|
if (this.importSeedValidator.isValid()) {
|
||||||
|
|
||||||
final ValidateImportBitsharesAccountRequest validatorRequest =
|
/*
|
||||||
new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
|
* Question if continue
|
||||||
|
* */
|
||||||
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
|
final QuestionDialog questionDialog = new QuestionDialog(activity);
|
||||||
|
questionDialog.setText(activity.getString(R.string.question_continue));
|
||||||
|
questionDialog.setOnNegative(new NegativeResponse() {
|
||||||
@Override
|
@Override
|
||||||
public void onCarryOut() {
|
public void onNegative(@NotNull DialogMaterial dialogMaterial) {
|
||||||
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
|
|
||||||
String errorText = "An error ocurred attempting to import the 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
questionDialog.setOnPositive(new PositiveResponse() {
|
||||||
|
@Override
|
||||||
|
public void onPositive() {
|
||||||
|
|
||||||
AccountSeed seed = new AccountSeed();
|
/*
|
||||||
|
* Loading dialog
|
||||||
|
* */
|
||||||
|
final CrystalLoading crystalLoading = new CrystalLoading(activity);
|
||||||
|
crystalLoading.show();
|
||||||
|
|
||||||
//TODO verify if words are already in the db
|
/*
|
||||||
//TODO check if name has been asigned to other seed
|
* Final service connection
|
||||||
seed.setMasterSeed(etSeedWords.getText().toString());
|
* */
|
||||||
seed.setName(etAccountName.getText().toString());
|
finalStep(crystalLoading);
|
||||||
seed.setType(SeedType.BRAINKEY);
|
|
||||||
|
|
||||||
accountSeedViewModel.addSeed(seed);
|
/*
|
||||||
|
* 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)){
|
||||||
|
|
||||||
CryptoNetAccountViewModel cryptoNetAccountViewModel = ViewModelProviders.of(this).get(CryptoNetAccountViewModel.class);
|
//Correct
|
||||||
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();*/
|
finalStep(crystalLoading);
|
||||||
CryptoNetInfoRequests.getInstance().addRequest(validatorRequest);
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
crystalLoading.dismiss();
|
||||||
|
|
||||||
|
txtErrorAccount.setVisibility(View.VISIBLE);
|
||||||
|
txtErrorAccount.setText(activity.getResources().getString(R.string.error_invalid_account));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
CryptoNetInfoRequests.getInstance().addRequest(request);*/
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
questionDialog.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void finalStep(final CrystalLoading crystalLoading){
|
||||||
|
|
||||||
|
final ImportSeedActivity thisActivity = this;
|
||||||
|
|
||||||
|
final ImportBitsharesAccountRequest validatorRequest =
|
||||||
|
new ImportBitsharesAccountRequest(etSeedWords.getText().toString(), getApplicationContext(), true);
|
||||||
|
|
||||||
|
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
|
||||||
|
@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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValidationSucceeded(final ValidationField field) {
|
public void onValidationSucceeded(final ValidationField field) {
|
||||||
final ImportSeedActivity activity = this;
|
final ImportSeedActivity activity = this;
|
||||||
|
@ -183,19 +476,19 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
if (field.getView() == etPin) {
|
if (field.getView() == etPin) {
|
||||||
tvPinError.setText("");
|
//tvPinError.setText("");
|
||||||
} else if (field.getView() == etPinConfirmation){
|
} else if (field.getView() == etPinConfirmation){
|
||||||
tvPinConfirmationError.setText("");
|
//tvPinConfirmationError.setText("");
|
||||||
} else if (field.getView() == etAccountName){
|
} else if (field.getView() == etAccountName){
|
||||||
tvAccountNameError.setText("");
|
//tvAccountNameError.setText("");
|
||||||
} else if (field.getView() == etSeedWords){
|
} else if (field.getView() == etSeedWords){
|
||||||
tvSeedWordsError.setText("");
|
//tvSeedWordsError.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.importSeedValidator.isValid()){
|
if (activity.importSeedValidator.isValid()){
|
||||||
btnImport.setEnabled(true);
|
enableCreate();
|
||||||
} else {
|
} else {
|
||||||
btnImport.setEnabled(false);
|
disableCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -205,13 +498,40 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
|
||||||
@Override
|
@Override
|
||||||
public void onValidationFailed(ValidationField field) {
|
public void onValidationFailed(ValidationField field) {
|
||||||
if (field.getView() == etPin) {
|
if (field.getView() == etPin) {
|
||||||
tvPinError.setText(field.getMessage());
|
//tvPinError.setText(field.getMessage());
|
||||||
} else if (field.getView() == etPinConfirmation){
|
} else if (field.getView() == etPinConfirmation){
|
||||||
tvPinConfirmationError.setText(field.getMessage());
|
//tvPinConfirmationError.setText(field.getMessage());
|
||||||
} else if (field.getView() == etAccountName){
|
} else if (field.getView() == etAccountName){
|
||||||
tvAccountNameError.setText(field.getMessage());
|
//tvAccountNameError.setText(field.getMessage());
|
||||||
} else if (field.getView() == etSeedWords){
|
} else if (field.getView() == etSeedWords){
|
||||||
tvSeedWordsError.setText(field.getMessage());
|
//tvSeedWordsError.setText(field.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable create button
|
||||||
|
* */
|
||||||
|
private void enableCreate() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//btnImport.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
||||||
|
btnImport.setEnabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable create button
|
||||||
|
* */
|
||||||
|
private void disableCreate() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
btnImport.setEnabled(false);
|
||||||
|
//btnImport.setBackground(getDrawable(R.drawable.disable_style));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,55 +2,43 @@ package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.media.MediaPlayer;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.Toast;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import java.util.List;
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.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.application.CrystalSecurityMonitor;
|
||||||
|
import cy.agorise.crystalwallet.fragments.ImportAccountOptionsFragment;
|
||||||
import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel;
|
||||||
import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel;
|
|
||||||
import cy.agorise.crystalwallet.views.TransactionListView;
|
|
||||||
|
|
||||||
public class IntroActivity extends CustomActivity {
|
public class IntroActivity extends CustomActivity {
|
||||||
|
|
||||||
@BindView(R.id.surface_view)
|
@BindView(R.id.ivAnimation)
|
||||||
public SurfaceView mSurfaceView;
|
ImageView ivAnimation;
|
||||||
|
|
||||||
@BindView(R.id.btnCreateAccount)
|
@BindView(R.id.btnCreateAccount)
|
||||||
public Button btnCreateAccount;
|
Button btnCreateAccount;
|
||||||
|
|
||||||
@BindView(R.id.btnImportAccount)
|
@BindView(R.id.btnImportAccount)
|
||||||
public Button btnImportAccount;
|
Button btnImportAccount;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the window animation
|
||||||
|
* */
|
||||||
|
// private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -59,50 +47,49 @@ public class IntroActivity extends CustomActivity {
|
||||||
|
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
// Appbar animation
|
Glide.with(this)
|
||||||
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
.load(R.drawable.appbar_background)
|
||||||
@Override
|
.apply(new RequestOptions().centerCrop())
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
.into(ivAnimation);
|
||||||
//Log.d(TAG,"surfaceCreated");
|
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(IntroActivity.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) {
|
* Integration of library with button effects
|
||||||
//Log.d(TAG,"surfaceChanged");
|
* */
|
||||||
}
|
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 surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
||||||
//Log.d(TAG,"surfaceDestroyed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.getApplication().registerActivityLifecycleCallbacks(CrystalSecurityMonitor.getInstance(this));
|
this.getApplication().registerActivityLifecycleCallbacks(CrystalSecurityMonitor.getInstance(this));
|
||||||
|
|
||||||
|
//Checks if the user has any seed created
|
||||||
|
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);
|
||||||
|
|
||||||
|
if (accountSeedListViewModel.accountSeedsCount() == 0) {
|
||||||
|
//If the user doesn't have any seeds created, then
|
||||||
//Checks if the user has any seed created
|
//send the user to create/import an account
|
||||||
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);
|
//Intent intent = new Intent(this, AccountSeedsManagementActivity.class);
|
||||||
|
//Intent intent = new Intent(this, ImportSeedActivity.class);
|
||||||
if (accountSeedListViewModel.accountSeedsCount() == 0) {
|
//Intent intent = new Intent(this, CreateSeedActivity.class);
|
||||||
//If the user doesn't have any seeds created, then
|
//startActivity(intent);
|
||||||
//send the user to create/import an account
|
} else {
|
||||||
//Intent intent = new Intent(this, AccountSeedsManagementActivity.class);
|
//Intent intent = new Intent(this, CreateSeedActivity.class);
|
||||||
//Intent intent = new Intent(this, ImportSeedActivity.class);
|
Intent intent = new Intent(this, BoardActivity.class);
|
||||||
//Intent intent = new Intent(this, CreateSeedActivity.class);
|
//Intent intent = new Intent(this, PocketRequestActivity.class);
|
||||||
//startActivity(intent);
|
startActivity(intent);
|
||||||
} else {
|
finish();
|
||||||
//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());
|
/*CrystalDatabase db = CrystalDatabase.getAppDatabase(getApplicationContext());
|
||||||
List<AccountSeed> seeds = RandomSeedGenerator.generateSeeds(2);
|
List<AccountSeed> seeds = RandomSeedGenerator.generateSeeds(2);
|
||||||
|
|
|
@ -4,7 +4,11 @@ import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.View;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
@ -20,8 +24,17 @@ public class LicenseActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@BindView(R.id.wvEULA) WebView wvEULA;
|
@BindView(R.id.wvEULA) WebView wvEULA;
|
||||||
|
|
||||||
|
@BindView(R.id.btnDisAgree)
|
||||||
|
Button btnDisAgree;
|
||||||
|
|
||||||
|
@BindView(R.id.btnAgree)
|
||||||
|
Button btnAgree;
|
||||||
|
|
||||||
CrystalDatabase db;
|
CrystalDatabase db;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -29,10 +42,23 @@ public class LicenseActivity extends AppCompatActivity {
|
||||||
|
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
// TODO check if license has been agreed
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
String html = getString(R.string.licence_html);
|
* */
|
||||||
wvEULA.loadData(html, "text/html", "UTF-8");
|
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();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
db = CrystalDatabase.getAppDatabase(this.getApplicationContext());
|
db = CrystalDatabase.getAppDatabase(this.getApplicationContext());
|
||||||
int licenseVersion = getResources().getInteger(R.integer.license_version);
|
int licenseVersion = getResources().getInteger(R.integer.license_version);
|
||||||
|
@ -43,6 +69,9 @@ public class LicenseActivity extends AppCompatActivity {
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
wvEULA.loadUrl("file:///android_asset/crystal_eula.html");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.btnAgree)
|
@OnClick(R.id.btnAgree)
|
||||||
|
|
|
@ -1,31 +1,64 @@
|
||||||
package cy.agorise.crystalwallet.activities;
|
package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.andrognito.patternlockview.PatternLockView;
|
import com.andrognito.patternlockview.PatternLockView;
|
||||||
import com.andrognito.patternlockview.listener.PatternLockViewListener;
|
import com.andrognito.patternlockview.listener.PatternLockViewListener;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
||||||
|
//import cy.agorise.crystalwallet.interfaces.OnResponse;
|
||||||
|
import cy.agorise.crystalwallet.interfaces.OnResponse;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.util.PasswordManager;
|
import cy.agorise.crystalwallet.util.PasswordManager;
|
||||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
|
|
||||||
public class PatternRequestActivity extends AppCompatActivity {
|
public class PatternRequestActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private String patternEncrypted;
|
private String patternEncrypted;
|
||||||
|
|
||||||
|
@BindView(R.id.tvPatternText)
|
||||||
|
TextView tvPatternText;
|
||||||
|
|
||||||
|
@BindView(R.id.txtBadtry)
|
||||||
|
TextView txtBadtry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External listener for success or fail
|
||||||
|
* */
|
||||||
|
private static OnResponse onResponse;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contains the bad tries
|
||||||
|
* */
|
||||||
|
private int tries = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Seconds counter
|
||||||
|
* */
|
||||||
|
private int seconds = 15;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
//Do nothing to prevent the user to use the back button
|
//Do nothing to prevent the user to use the back button
|
||||||
|
@ -34,12 +67,15 @@ public class PatternRequestActivity extends AppCompatActivity {
|
||||||
@BindView(R.id.patternLockView)
|
@BindView(R.id.patternLockView)
|
||||||
PatternLockView patternLockView;
|
PatternLockView patternLockView;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_pattern_request);
|
setContentView(R.layout.activity_pattern_request);
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
|
//onResponse = null;
|
||||||
|
|
||||||
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
||||||
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
||||||
|
|
||||||
|
@ -71,13 +107,26 @@ public class PatternRequestActivity extends AppCompatActivity {
|
||||||
public void onComplete(List<PatternLockView.Dot> pattern) {
|
public void onComplete(List<PatternLockView.Dot> pattern) {
|
||||||
if (PasswordManager.checkPassword(patternEncrypted,patternToString(pattern))){
|
if (PasswordManager.checkPassword(patternEncrypted,patternToString(pattern))){
|
||||||
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
|
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
|
||||||
CrystalSecurityMonitor.getInstance(null).call2ndFactor(thisActivity);
|
//CrystalSecurityMonitor.getInstance(null).call2ndFactor(thisActivity);
|
||||||
|
thisActivity.finish();
|
||||||
|
|
||||||
|
/*if(onResponse != null){
|
||||||
|
onResponse.onSuccess();
|
||||||
|
}*/
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
thisActivity.finish();
|
thisActivity.finish();
|
||||||
|
|
||||||
|
/*if(onResponse != null){
|
||||||
|
onResponse.onSuccess();
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
patternLockView.clearPattern();
|
incorrect();
|
||||||
patternLockView.requestFocus();
|
|
||||||
|
/*if(onResponse != null){
|
||||||
|
onResponse.onFailed();
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +144,104 @@ public class PatternRequestActivity extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setOnResponse(OnResponse onResponse) {
|
||||||
|
PatternRequestActivity.onResponse = onResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void incorrect(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One more bad try
|
||||||
|
* */
|
||||||
|
++tries;
|
||||||
|
|
||||||
|
final Activity activity = this;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User can not go more up to 5 bad tries
|
||||||
|
* */
|
||||||
|
if(tries==4) {
|
||||||
|
tries = 0;
|
||||||
|
|
||||||
|
patternLockView.setEnabled(false);
|
||||||
|
txtBadtry.setVisibility(View.VISIBLE);
|
||||||
|
txtBadtry.setText(txtBadtry.getText().toString().replace("%%",String.valueOf(seconds)));
|
||||||
|
|
||||||
|
final Timer t = new Timer();
|
||||||
|
//Set the schedule function and rate
|
||||||
|
t.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
--seconds;
|
||||||
|
|
||||||
|
if(seconds==0){
|
||||||
|
t.cancel();
|
||||||
|
|
||||||
|
seconds = 15;
|
||||||
|
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
patternLockView.setEnabled(true);
|
||||||
|
txtBadtry.setVisibility(View.INVISIBLE);
|
||||||
|
patternLockView.clearPattern();
|
||||||
|
patternLockView.requestFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
txtBadtry.setText(activity.getResources().getString(R.string.wrong_pin_wait).replace("%%",String.valueOf(seconds)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
//Set how long before to start calling the TimerTask (in milliseconds)
|
||||||
|
1000,
|
||||||
|
//Set the amount of time between each execution (in milliseconds)
|
||||||
|
1000);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show error
|
||||||
|
* */
|
||||||
|
tvPatternText.setText(activity.getResources().getString(R.string.Incorrect_pattern));
|
||||||
|
tvPatternText.setTextColor(Color.RED);
|
||||||
|
tvPatternText.setVisibility(View.VISIBLE);
|
||||||
|
final Timer t = new Timer();
|
||||||
|
t.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
t.cancel();
|
||||||
|
tvPatternText.setVisibility(View.INVISIBLE);
|
||||||
|
patternLockView.clearPattern();
|
||||||
|
patternLockView.requestFocus();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
//Set how long before to start calling the TimerTask (in milliseconds)
|
||||||
|
1000,
|
||||||
|
//Set the amount of time between each execution (in milliseconds)
|
||||||
|
1000);
|
||||||
|
}
|
||||||
|
|
||||||
public String patternToString(List<PatternLockView.Dot> pattern){
|
public String patternToString(List<PatternLockView.Dot> pattern){
|
||||||
String patternString = "";
|
String patternString = "";
|
||||||
for (PatternLockView.Dot nextDot : pattern){
|
for (PatternLockView.Dot nextDot : pattern){
|
||||||
|
|
|
@ -1,21 +1,37 @@
|
||||||
package cy.agorise.crystalwallet.activities;
|
package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
|
||||||
|
import cy.agorise.crystalwallet.interfaces.OnResponse;
|
||||||
import cy.agorise.crystalwallet.models.AccountSeed;
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.util.PasswordManager;
|
import cy.agorise.crystalwallet.util.PasswordManager;
|
||||||
|
@ -24,6 +40,29 @@ import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
public class PinRequestActivity extends AppCompatActivity {
|
public class PinRequestActivity extends AppCompatActivity {
|
||||||
private String passwordEncrypted;
|
private String passwordEncrypted;
|
||||||
|
|
||||||
|
@BindView(R.id.btnOK)
|
||||||
|
Button btnOK;
|
||||||
|
|
||||||
|
@BindView(R.id.txtBadtry)
|
||||||
|
TextView txtBadtry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contains the bad tries
|
||||||
|
* */
|
||||||
|
private int tries = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Seconds counter
|
||||||
|
* */
|
||||||
|
private int seconds = 15;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External listener for success or fail
|
||||||
|
* */
|
||||||
|
private static OnResponse onResponse;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
//Do nothing to prevent the user to use the back button
|
//Do nothing to prevent the user to use the back button
|
||||||
|
@ -38,6 +77,13 @@ public class PinRequestActivity extends AppCompatActivity {
|
||||||
setContentView(R.layout.activity_pin_request);
|
setContentView(R.layout.activity_pin_request);
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
|
//onResponse = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initially the button is disabled till the user type a valid PIN
|
||||||
|
* */
|
||||||
|
btnOK.setEnabled(false);
|
||||||
|
|
||||||
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
||||||
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
||||||
generalSettingsLiveData.observe(this, new Observer<List<GeneralSetting>>() {
|
generalSettingsLiveData.observe(this, new Observer<List<GeneralSetting>>() {
|
||||||
|
@ -59,17 +105,139 @@ public class PinRequestActivity extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etPassword,
|
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
@OnClick(R.id.btnOK)
|
||||||
void afterPasswordChanged(Editable editable) {
|
void okClic(final View view) {
|
||||||
|
|
||||||
if (PasswordManager.checkPassword(passwordEncrypted, etPassword.getText().toString())) {
|
if (PasswordManager.checkPassword(passwordEncrypted, etPassword.getText().toString())) {
|
||||||
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
|
if (CrystalSecurityMonitor.getInstance(null).is2ndFactorSet()) {
|
||||||
CrystalSecurityMonitor.getInstance(null).call2ndFactor(this);
|
CrystalSecurityMonitor.getInstance(null).call2ndFactor(this);
|
||||||
|
|
||||||
|
if(onResponse != null){
|
||||||
|
onResponse.onSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.finish();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,18 @@
|
||||||
package cy.agorise.crystalwallet.activities;
|
package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.jaredrummler.materialspinner.MaterialSpinner;
|
import com.jaredrummler.materialspinner.MaterialSpinner;
|
||||||
|
|
||||||
|
@ -38,7 +41,7 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
|
||||||
SendTransactionValidator sendTransactionValidator;
|
SendTransactionValidator sendTransactionValidator;
|
||||||
|
|
||||||
@BindView(R.id.spFrom)
|
@BindView(R.id.spFrom)
|
||||||
MaterialSpinner spFrom;
|
Spinner spFrom;
|
||||||
@BindView(R.id.tvFromError)
|
@BindView(R.id.tvFromError)
|
||||||
TextView tvFromError;
|
TextView tvFromError;
|
||||||
@BindView(R.id.etTo)
|
@BindView(R.id.etTo)
|
||||||
|
@ -62,6 +65,9 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
|
||||||
//@BindView(R.id.btnCancel)
|
//@BindView(R.id.btnCancel)
|
||||||
Button btnCancel;
|
Button btnCancel;
|
||||||
|
|
||||||
|
@BindView(R.id.fabCloseCamera)
|
||||||
|
FloatingActionButton btnCloseCamera;
|
||||||
|
|
||||||
private long cryptoNetAccountId;
|
private long cryptoNetAccountId;
|
||||||
private CryptoNetAccount cryptoNetAccount;
|
private CryptoNetAccount cryptoNetAccount;
|
||||||
private GrapheneAccount grapheneAccount;
|
private GrapheneAccount grapheneAccount;
|
||||||
|
@ -146,6 +152,15 @@ public class SendTransactionActivity extends AppCompatActivity implements UIVali
|
||||||
this.finish();
|
this.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@OnClick(R.id.fabCloseCamera)
|
||||||
|
public void onClicCloseCamera(){
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//@OnClick(R.id.btnSend)
|
//@OnClick(R.id.btnSend)
|
||||||
public void importSend(){
|
public void importSend(){
|
||||||
if (this.sendTransactionValidator.isValid()) {
|
if (this.sendTransactionValidator.isValid()) {
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
package cy.agorise.crystalwallet.activities;
|
package cy.agorise.crystalwallet.activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.media.MediaPlayer;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.TabLayout;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.SurfaceHolder;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.sjaramillo10.animatedtablayout.AnimatedTabLayout;
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
@ -35,21 +34,22 @@ public class SettingsActivity extends AppCompatActivity{
|
||||||
public ImageView ivGoBack;
|
public ImageView ivGoBack;
|
||||||
|
|
||||||
@BindView(R.id.tabLayout)
|
@BindView(R.id.tabLayout)
|
||||||
public AnimatedTabLayout tabLayout;
|
public TabLayout tabLayout;
|
||||||
|
|
||||||
@BindView(R.id.pager)
|
@BindView(R.id.pager)
|
||||||
public ViewPager mPager;
|
public ViewPager mPager;
|
||||||
|
|
||||||
public SettingsPagerAdapter settingsPagerAdapter;
|
public SettingsPagerAdapter settingsPagerAdapter;
|
||||||
|
|
||||||
@BindView(R.id.surface_view)
|
|
||||||
public SurfaceView mSurfaceView;
|
|
||||||
|
|
||||||
@BindView(R.id.tvBuildVersion)
|
@BindView(R.id.tvBuildVersion)
|
||||||
public TextView tvBuildVersion;
|
public TextView tvBuildVersion;
|
||||||
|
|
||||||
private SecuritySettingsFragment securitySettingsFragment;
|
private SecuritySettingsFragment securitySettingsFragment;
|
||||||
|
|
||||||
|
@BindView(R.id.ivAppBarAnimation)
|
||||||
|
ImageView ivAppBarAnimation;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -59,27 +59,11 @@ public class SettingsActivity extends AppCompatActivity{
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
// Appbar animation
|
// Sets AppBar animation
|
||||||
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
Glide.with(this)
|
||||||
@Override
|
.load(R.drawable.appbar_background)
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
.apply(new RequestOptions().centerCrop())
|
||||||
//Log.d(TAG,"surfaceCreated");
|
.into(ivAppBarAnimation);
|
||||||
MediaPlayer mediaPlayer = MediaPlayer.create(SettingsActivity.this, R.raw.appbar_background);
|
|
||||||
mediaPlayer.setDisplay(mSurfaceView.getHolder());
|
|
||||||
mediaPlayer.setLooping(true);
|
|
||||||
mediaPlayer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
|
||||||
//Log.d(TAG,"surfaceChanged");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
||||||
//Log.d(TAG,"surfaceDestroyed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
|
settingsPagerAdapter = new SettingsPagerAdapter(getSupportFragmentManager());
|
||||||
mPager.setAdapter(settingsPagerAdapter);
|
mPager.setAdapter(settingsPagerAdapter);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package cy.agorise.crystalwallet.apigenerator;
|
package cy.agorise.crystalwallet.apigenerator;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -9,7 +8,6 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
|
|
||||||
import cy.agorise.crystalwallet.dao.BitsharesAssetDao;
|
import cy.agorise.crystalwallet.dao.BitsharesAssetDao;
|
||||||
import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao;
|
import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao;
|
||||||
import cy.agorise.crystalwallet.dao.CryptoCurrencyDao;
|
import cy.agorise.crystalwallet.dao.CryptoCurrencyDao;
|
||||||
|
@ -82,13 +80,32 @@ public abstract class GrapheneApiGenerator {
|
||||||
*/
|
*/
|
||||||
private static HashMap<Long,SubscriptionListener> currentBitsharesListener = new HashMap<>();
|
private static HashMap<Long,SubscriptionListener> currentBitsharesListener = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
// The message broker for Steem
|
||||||
|
private static SubscriptionMessagesHub steemSubscriptionHub = new SubscriptionMessagesHub("", "", true, new NodeErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void onError(BaseResponse.Error error) {
|
||||||
|
//TODO subcription hub error
|
||||||
|
System.out.println("GrapheneAPI error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Steem subscription thread for the real time updates
|
||||||
|
*/
|
||||||
|
private static WebSocketThread steemSubscriptionThread = new WebSocketThread(steemSubscriptionHub, CryptoNetManager.getURL(CryptoNet.STEEM));
|
||||||
|
/**
|
||||||
|
* This is used for manager each Steem listener in the subscription thread
|
||||||
|
*/
|
||||||
|
private static HashMap<Long,SubscriptionListener> currentSteemListener = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the data of an account searching by it's id
|
* Retrieves the data of an account searching by it's id
|
||||||
*
|
*
|
||||||
* @param accountId The accountId to retrieve
|
* @param accountId The accountId to retrieve
|
||||||
* @param request The Api request object, to answer this petition
|
* @param request The Api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getAccountById(String accountId, final ApiRequest request){
|
public static void getAccountById(String accountId, CryptoNet cryptoNet, final ApiRequest request){
|
||||||
WebSocketThread thread = new WebSocketThread(new GetAccounts(accountId,
|
WebSocketThread thread = new WebSocketThread(new GetAccounts(accountId,
|
||||||
new WitnessResponseListener() {
|
new WitnessResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,7 +126,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,25 +136,37 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param address The address to retrieve
|
* @param address The address to retrieve
|
||||||
* @param request The Api request object, to answer this petition
|
* @param request The Api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getAccountByOwnerOrActiveAddress(Address address, final ApiRequest request){
|
public static void getAccountByOwnerOrActiveAddress(Address address, CryptoNet cryptoNet, final ApiRequest request){
|
||||||
WebSocketThread thread = new WebSocketThread(new GetKeyReferences(address, true,
|
WebSocketThread thread = new WebSocketThread(new GetKeyReferences(address, true,
|
||||||
new WitnessResponseListener() {
|
new WitnessResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(WitnessResponse response) {
|
public void onSuccess(WitnessResponse response) {
|
||||||
final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result;
|
try {
|
||||||
if(resp.size() > 0){
|
final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result;
|
||||||
List<UserAccount> accounts = resp.get(0);
|
if (resp.size() > 0) {
|
||||||
if(accounts.size() > 0){
|
List<UserAccount> accounts = resp.get(0);
|
||||||
for(UserAccount account : accounts) {
|
if (accounts.size() > 0) {
|
||||||
request.getListener().success(account,request.getId());}}}
|
for (UserAccount account : accounts) {
|
||||||
request.getListener().fail(request.getId());
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
@ -152,7 +181,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param request The Api request object, to answer this petition
|
* @param request The Api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getAccountTransaction(String accountGrapheneId, int start, int stop,
|
public static void getAccountTransaction(String accountGrapheneId, int start, int stop,
|
||||||
int limit, final ApiRequest request){
|
int limit, CryptoNet cryptoNet, final ApiRequest request){
|
||||||
WebSocketThread thread = new WebSocketThread(new GetRelativeAccountHistory(new UserAccount(accountGrapheneId),
|
WebSocketThread thread = new WebSocketThread(new GetRelativeAccountHistory(new UserAccount(accountGrapheneId),
|
||||||
start, limit, stop, new WitnessResponseListener() {
|
start, limit, stop, new WitnessResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -164,7 +193,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +203,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param accountName The account Name to find
|
* @param accountName The account Name to find
|
||||||
* @param request The Api request object, to answer this petition
|
* @param request The Api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getAccountByName(String accountName, final ApiRequest request){
|
public static void getAccountByName(String accountName, CryptoNet cryptoNet,final ApiRequest request){
|
||||||
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
|
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
|
||||||
new WitnessResponseListener() {
|
new WitnessResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -191,7 +220,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +230,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param accountName The account Name to find
|
* @param accountName The account Name to find
|
||||||
* @param request The Api request object, to answer this petition
|
* @param request The Api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getAccountIdByName(String accountName, final ApiRequest request){
|
public static void getAccountIdByName(String accountName, CryptoNet cryptoNet, final ApiRequest request){
|
||||||
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
|
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
|
||||||
new WitnessResponseListener() {
|
new WitnessResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -218,7 +247,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +281,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param assetNames The list of the names of the assets to be retrieve
|
* @param assetNames The list of the names of the assets to be retrieve
|
||||||
* @param request the api request object, to answer this petition
|
* @param request the api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getAssetByName(ArrayList<String> assetNames, final ApiRequest request){
|
public static void getAssetByName(ArrayList<String> assetNames, CryptoNet cryptoNet,final ApiRequest request){
|
||||||
|
|
||||||
WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assetNames,true,
|
WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assetNames,true,
|
||||||
new WitnessResponseListener() {
|
new WitnessResponseListener() {
|
||||||
|
@ -287,7 +316,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +325,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param assetIds The list of the ids to retrieve
|
* @param assetIds The list of the ids to retrieve
|
||||||
* @param request the api request object, to answer this petition
|
* @param request the api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getAssetById(ArrayList<String> assetIds, final ApiRequest request){
|
public static void getAssetById(ArrayList<String> assetIds, CryptoNet cryptoNet, final ApiRequest request){
|
||||||
ArrayList<Asset> assets = new ArrayList<>();
|
ArrayList<Asset> assets = new ArrayList<>();
|
||||||
for(String assetId : assetIds){
|
for(String assetId : assetIds){
|
||||||
Asset asset = new Asset(assetId);
|
Asset asset = new Asset(assetId);
|
||||||
|
@ -335,7 +364,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +398,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
if(operation instanceof TransferOperation){
|
if(operation instanceof TransferOperation){
|
||||||
final TransferOperation tOperation = (TransferOperation) operation;
|
final TransferOperation tOperation = (TransferOperation) operation;
|
||||||
if(tOperation.getFrom().getObjectId().equals(accountBitsharesId) || tOperation.getTo().getObjectId().equals(accountBitsharesId)){
|
if(tOperation.getFrom().getObjectId().equals(accountBitsharesId) || tOperation.getTo().getObjectId().equals(accountBitsharesId)){
|
||||||
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesId,context);
|
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesId,CryptoNet.BITSHARES,context);
|
||||||
final CryptoCoinTransaction transaction = new CryptoCoinTransaction();
|
final CryptoCoinTransaction transaction = new CryptoCoinTransaction();
|
||||||
transaction.setAccountId(accountId);
|
transaction.setAccountId(accountId);
|
||||||
transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue());
|
transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue());
|
||||||
|
@ -407,7 +436,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
});
|
});
|
||||||
ArrayList<String> assets = new ArrayList<>();
|
ArrayList<String> assets = new ArrayList<>();
|
||||||
assets.add(tOperation.getAssetAmount().getAsset().getObjectId());
|
assets.add(tOperation.getAssetAmount().getAsset().getObjectId());
|
||||||
GrapheneApiGenerator.getAssetById(assets,assetRequest);
|
GrapheneApiGenerator.getAssetById(assets,CryptoNet.BITSHARES,assetRequest);
|
||||||
}else{
|
}else{
|
||||||
saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountBitsharesId,tOperation,context);
|
saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountBitsharesId,tOperation,context);
|
||||||
}
|
}
|
||||||
|
@ -432,6 +461,99 @@ public abstract class GrapheneApiGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe a steem account to receive real time updates
|
||||||
|
*
|
||||||
|
* @param accountId The id opf the database of the account
|
||||||
|
* @param accountSteemId The steem id of the account
|
||||||
|
* @param context The android context of this application
|
||||||
|
*/
|
||||||
|
public static void subscribeSteemAccount(final long accountId, final String accountSteemId,
|
||||||
|
final Context context){
|
||||||
|
if(!currentSteemListener.containsKey(accountId)){
|
||||||
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
|
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
|
||||||
|
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
|
||||||
|
SubscriptionListener balanceListener = new SubscriptionListener() {
|
||||||
|
@Override
|
||||||
|
public ObjectType getInterestObjectType() {
|
||||||
|
return ObjectType.TRANSACTION_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscriptionUpdate(SubscriptionResponse response) {
|
||||||
|
List<Serializable> updatedObjects = (List<Serializable>) response.params.get(1);
|
||||||
|
if(updatedObjects.size() > 0){
|
||||||
|
for(Serializable update : updatedObjects){
|
||||||
|
if(update instanceof BroadcastedTransaction){
|
||||||
|
BroadcastedTransaction transactionUpdate = (BroadcastedTransaction) update;
|
||||||
|
for(BaseOperation operation : transactionUpdate.getTransaction().getOperations()){
|
||||||
|
if(operation instanceof TransferOperation){
|
||||||
|
final TransferOperation tOperation = (TransferOperation) operation;
|
||||||
|
if(tOperation.getFrom().getObjectId().equals(accountSteemId) || tOperation.getTo().getObjectId().equals(accountSteemId)){
|
||||||
|
GrapheneApiGenerator.getAccountBalance(accountId,accountSteemId,CryptoNet.STEEM,context);
|
||||||
|
final CryptoCoinTransaction transaction = new CryptoCoinTransaction();
|
||||||
|
transaction.setAccountId(accountId);
|
||||||
|
transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue());
|
||||||
|
BitsharesAssetInfo info = bitsharesAssetDao.getBitsharesAssetInfoById(tOperation.getAssetAmount().getAsset().getObjectId());
|
||||||
|
if (info == null) {
|
||||||
|
//The cryptoCurrency is not in the database, queringfor its data
|
||||||
|
ApiRequest assetRequest = new ApiRequest(0, new ApiRequestListener() {
|
||||||
|
@Override
|
||||||
|
public void success(Object answer, int idPetition) {
|
||||||
|
ArrayList<BitsharesAsset> assets = (ArrayList<BitsharesAsset>) answer;
|
||||||
|
for(BitsharesAsset asset : assets){
|
||||||
|
|
||||||
|
long currencyId = -1;
|
||||||
|
CryptoCurrency cryptoCurrencyDb = cryptoCurrencyDao.getByNameAndCryptoNet(((BitsharesAsset) answer).getName(),((BitsharesAsset) answer).getCryptoNet().name());
|
||||||
|
|
||||||
|
if (cryptoCurrencyDb != null){
|
||||||
|
currencyId = cryptoCurrencyDb.getId();
|
||||||
|
} else {
|
||||||
|
long idCryptoCurrency = cryptoCurrencyDao.insertCryptoCurrency(asset)[0];
|
||||||
|
currencyId = idCryptoCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitsharesAssetInfo info = new BitsharesAssetInfo(asset);
|
||||||
|
info.setCryptoCurrencyId(currencyId);
|
||||||
|
asset.setId((int)currencyId);
|
||||||
|
bitsharesAssetDao.insertBitsharesAssetInfo(info);
|
||||||
|
saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountSteemId,tOperation,context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fail(int idPetition) {
|
||||||
|
//TODO error retrieving asset
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ArrayList<String> assets = new ArrayList<>();
|
||||||
|
assets.add(tOperation.getAssetAmount().getAsset().getObjectId());
|
||||||
|
GrapheneApiGenerator.getAssetById(assets,CryptoNet.STEEM,assetRequest);
|
||||||
|
}else{
|
||||||
|
saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountSteemId,tOperation,context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
currentSteemListener.put(accountId,balanceListener);
|
||||||
|
steemSubscriptionHub.addSubscriptionListener(balanceListener);
|
||||||
|
|
||||||
|
if(!steemSubscriptionThread.isConnected()){
|
||||||
|
steemSubscriptionThread.start();
|
||||||
|
}else if(!steemSubscriptionHub.isSubscribed()){
|
||||||
|
steemSubscriptionHub.resubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to save a transaction retrieved from the update
|
* Function to save a transaction retrieved from the update
|
||||||
* @param transaction The transaction db object
|
* @param transaction The transaction db object
|
||||||
|
@ -470,7 +592,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param context The android context of this application
|
* @param context The android context of this application
|
||||||
*/
|
*/
|
||||||
public static void getAccountBalance(final long accountId, final String accountGrapheneId,
|
public static void getAccountBalance(final long accountId, final String accountGrapheneId,
|
||||||
final Context context){
|
final CryptoNet cryptoNet, final Context context){
|
||||||
|
|
||||||
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
final CryptoCoinBalanceDao balanceDao = db.cryptoCoinBalanceDao();
|
final CryptoCoinBalanceDao balanceDao = db.cryptoCoinBalanceDao();
|
||||||
|
@ -516,7 +638,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void fail(int idPetition) {
|
public void fail(int idPetition) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
getAssetById(idAssets,getAssetRequest);
|
getAssetById(idAssets,cryptoNet,getAssetRequest);
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
|
|
||||||
|
@ -530,7 +652,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
|
@ -542,7 +664,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
* @param blockHeader The block header to retrieve the date time
|
* @param blockHeader The block header to retrieve the date time
|
||||||
* @param request the api request object, to answer this petition
|
* @param request the api request object, to answer this petition
|
||||||
*/
|
*/
|
||||||
public static void getBlockHeaderTime(long blockHeader, final ApiRequest request){
|
public static void getBlockHeaderTime(long blockHeader, CryptoNet cryptoNet,final ApiRequest request){
|
||||||
WebSocketThread thread = new WebSocketThread(new GetBlockHeader(blockHeader, new WitnessResponseListener() {
|
WebSocketThread thread = new WebSocketThread(new GetBlockHeader(blockHeader, new WitnessResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(WitnessResponse response) {
|
public void onSuccess(WitnessResponse response) {
|
||||||
|
@ -557,7 +679,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
public void onError(BaseResponse.Error error) {
|
public void onError(BaseResponse.Error error) {
|
||||||
request.getListener().fail(request.getId());
|
request.getListener().fail(request.getId());
|
||||||
}
|
}
|
||||||
}),CryptoNetManager.getURL(CryptoNet.BITSHARES));
|
}),CryptoNetManager.getURL(cryptoNet));
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -625,7 +747,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
|
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
|
||||||
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
|
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
|
||||||
CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName);
|
CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName,CryptoNet.BITSHARES.name());
|
||||||
BitsharesAssetInfo info = null;
|
BitsharesAssetInfo info = null;
|
||||||
if(baseCurrency != null){
|
if(baseCurrency != null){
|
||||||
info = db.bitsharesAssetDao().getBitsharesAssetInfo(baseCurrency.getId());
|
info = db.bitsharesAssetDao().getBitsharesAssetInfo(baseCurrency.getId());
|
||||||
|
@ -660,7 +782,7 @@ public abstract class GrapheneApiGenerator {
|
||||||
});
|
});
|
||||||
ArrayList<String> names = new ArrayList<>();
|
ArrayList<String> names = new ArrayList<>();
|
||||||
names.add(baseAssetName);
|
names.add(baseAssetName);
|
||||||
GrapheneApiGenerator.getAssetByName(names,getAssetRequest);
|
GrapheneApiGenerator.getAssetByName(names,CryptoNet.BITSHARES,getAssetRequest);
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
BitsharesAsset baseAsset = new BitsharesAsset(baseCurrency);
|
BitsharesAsset baseAsset = new BitsharesAsset(baseCurrency);
|
||||||
|
|
|
@ -1,49 +1,81 @@
|
||||||
package cy.agorise.crystalwallet.apigenerator;
|
package cy.agorise.crystalwallet.apigenerator;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.apigenerator.insightapi.AddressesActivityWatcher;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.GetEstimateFee;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.GetEstimateFee;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionByAddress;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionByAddress;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.GetTransactionData;
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.enums.CryptoNet;
|
|
||||||
import cy.agorise.crystalwallet.network.CryptoNetManager;
|
import cy.agorise.crystalwallet.network.CryptoNetManager;
|
||||||
|
|
||||||
public class InsightApiGenerator {
|
public class InsightApiGenerator {
|
||||||
|
|
||||||
private static HashMap<CryptoNet,BroadcastTransaction> broadcaster = new HashMap();
|
private static HashMap<CryptoCoin,GetTransactionByAddress> transactionGetters = new HashMap();
|
||||||
private static HashMap<CryptoNet,GetTransactionByAddress> transactionGetters = new HashMap();
|
private static HashMap<CryptoCoin,AddressesActivityWatcher> transactionFollowers = new HashMap();
|
||||||
private static HashMap<CryptoNet,GetTransactionData> transacitonFollowers = new HashMap();
|
|
||||||
|
|
||||||
public static void getTransactionFromAddress(CryptoNet cryptoNet, String address,
|
private static final String PATH = "api";
|
||||||
ApiRequest request, Context context,
|
|
||||||
boolean subscribe){
|
/**
|
||||||
if(!transactionGetters.containsKey(cryptoNet)){
|
* Fecth all the transaciton for a giving address
|
||||||
//TODO change this line
|
* @param cryptoCoin the crypto net of the address
|
||||||
transactionGetters.put(cryptoNet,new GetTransactionByAddress(null,CryptoNetManager.getURL(cryptoNet),context));
|
* @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));
|
||||||
}
|
}
|
||||||
|
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();
|
||||||
|
|
||||||
public static void followTransaction(CryptoNet cryptoNet, String txid, Context context){
|
if(subscribe){
|
||||||
|
if(!transactionFollowers.containsKey(cryptoCoin)){
|
||||||
}
|
transactionFollowers.put(cryptoCoin,new AddressesActivityWatcher(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH,cryptoCoin));
|
||||||
|
}
|
||||||
public static void broadcastTransaction(CryptoNet cryptoNet, String rawtx, ApiRequest request){
|
transactionFollowers.get(cryptoCoin).addAddress(address);
|
||||||
if(!broadcaster.containsKey(cryptoNet)){
|
transactionFollowers.get(cryptoCoin).connect();
|
||||||
//TODO change to multiple broadcast
|
|
||||||
broadcaster.put(cryptoNet,new BroadcastTransaction(rawtx,null,
|
|
||||||
CryptoNetManager.getURL(cryptoNet),null));
|
|
||||||
broadcaster.get(cryptoNet).start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getEstimateFee(CryptoNet cryptoNet, final ApiRequest request){
|
/**
|
||||||
GetEstimateFee.getEstimateFee(CryptoNetManager.getURL(cryptoNet), new GetEstimateFee.estimateFeeListener() {
|
* Broadcast an insight api transaction
|
||||||
|
* @param cryptoCoin The cryptoNet of the transaction
|
||||||
|
* @param rawtx the transaction to be broadcasted
|
||||||
|
*/
|
||||||
|
public static void broadcastTransaction(CryptoCoin cryptoCoin, String rawtx, final ApiRequest request){
|
||||||
|
BroadcastTransaction bTransaction = new BroadcastTransaction(rawtx,
|
||||||
|
CryptoNetManager.getURL(cryptoCoin.getCryptoNet()), PATH, new BroadcastTransaction.BroadCastTransactionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void estimateFee(long value) {
|
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) {
|
||||||
request.listener.success(value,request.getId());
|
request.listener.success(value,request.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,4 +85,8 @@ public class InsightApiGenerator {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface HasTransactionListener{
|
||||||
|
public void hasTransaction(boolean value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
||||||
import io.socket.client.IO;
|
import io.socket.client.IO;
|
||||||
import io.socket.client.Socket;
|
import io.socket.client.Socket;
|
||||||
|
@ -24,12 +25,9 @@ import io.socket.emitter.Emitter;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AccountActivityWatcher {
|
public class AddressesActivityWatcher {
|
||||||
|
|
||||||
/**
|
private final CryptoCoin cryptoCoin;
|
||||||
* The mAccount to be monitor
|
|
||||||
*/
|
|
||||||
private final GeneralCoinAccount mAccount;
|
|
||||||
/**
|
/**
|
||||||
* The list of address to monitor
|
* The list of address to monitor
|
||||||
*/
|
*/
|
||||||
|
@ -38,12 +36,9 @@ public class AccountActivityWatcher {
|
||||||
* the Socket.IO
|
* the Socket.IO
|
||||||
*/
|
*/
|
||||||
private Socket mSocket;
|
private Socket mSocket;
|
||||||
/**
|
|
||||||
* This app mContext, used to save on the DB
|
|
||||||
*/
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
private final String mServerUrl;
|
private final String mServerUrl;
|
||||||
|
private final String mPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the address/transaction notification.
|
* Handles the address/transaction notification.
|
||||||
|
@ -55,9 +50,9 @@ public class AccountActivityWatcher {
|
||||||
try {
|
try {
|
||||||
System.out.println("Receive accountActivtyWatcher " + os[0].toString() );
|
System.out.println("Receive accountActivtyWatcher " + os[0].toString() );
|
||||||
String txid = ((JSONObject) os[0]).getString(InsightApiConstants.sTxTag);
|
String txid = ((JSONObject) os[0]).getString(InsightApiConstants.sTxTag);
|
||||||
new GetTransactionData(txid, mAccount, mServerUrl, mContext).start();
|
new GetTransactionData(txid, mServerUrl, mPath, cryptoCoin).start();
|
||||||
} catch (JSONException ex) {
|
} catch (JSONException ex) {
|
||||||
Logger.getLogger(AccountActivityWatcher.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(AddressesActivityWatcher.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -84,7 +79,9 @@ public class AccountActivityWatcher {
|
||||||
private final Emitter.Listener onDisconnect = new Emitter.Listener() {
|
private final Emitter.Listener onDisconnect = new Emitter.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void call(Object... os) {
|
public void call(Object... os) {
|
||||||
System.out.println("Disconnected to accountActivityWatcher");
|
try {
|
||||||
|
Thread.sleep(60000);
|
||||||
|
} catch (InterruptedException ignore) {}
|
||||||
mSocket.connect();
|
mSocket.connect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -99,19 +96,21 @@ public class AccountActivityWatcher {
|
||||||
for(Object ob : os) {
|
for(Object ob : os) {
|
||||||
System.out.println("accountActivityWatcher " + ob.toString());
|
System.out.println("accountActivityWatcher " + ob.toString());
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(60000);
|
||||||
|
} catch (InterruptedException ignore) {}
|
||||||
|
mSocket.connect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic constructor
|
* Basic constructor
|
||||||
*
|
*
|
||||||
* @param mAccount The mAccount to be monitor
|
|
||||||
* @param mContext This app mContext
|
|
||||||
*/
|
*/
|
||||||
public AccountActivityWatcher(String serverUrl, GeneralCoinAccount mAccount, Context mContext) {
|
public AddressesActivityWatcher(String serverUrl, String path, CryptoCoin cryptoCoin) {
|
||||||
|
this.mPath = path;
|
||||||
this.mServerUrl = serverUrl;
|
this.mServerUrl = serverUrl;
|
||||||
this.mAccount = mAccount;
|
this.cryptoCoin = cryptoCoin;
|
||||||
this.mContext = mContext;
|
|
||||||
try {
|
try {
|
||||||
this.mSocket = IO.socket(serverUrl);
|
this.mSocket = IO.socket(serverUrl);
|
||||||
this.mSocket.on(Socket.EVENT_CONNECT, onConnect);
|
this.mSocket.on(Socket.EVENT_CONNECT, onConnect);
|
||||||
|
@ -141,13 +140,11 @@ public class AccountActivityWatcher {
|
||||||
* Connects the Socket
|
* Connects the Socket
|
||||||
*/
|
*/
|
||||||
public void connect() {
|
public void connect() {
|
||||||
//TODO change to use log
|
|
||||||
System.out.println("accountActivityWatcher connecting");
|
|
||||||
try{
|
try{
|
||||||
this.mSocket.connect();
|
if(this.mSocket == null || !this.mSocket.connected()) {
|
||||||
}catch(Exception e){
|
this.mSocket.connect();
|
||||||
//TODO change exception handler
|
}
|
||||||
System.out.println("accountActivityWatcher exception " + e.getMessage());
|
}catch(Exception ignore){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,29 +22,21 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
* The serviceGenerator to call
|
* The serviceGenerator to call
|
||||||
*/
|
*/
|
||||||
private InsightApiServiceGenerator mServiceGenerator;
|
private InsightApiServiceGenerator mServiceGenerator;
|
||||||
/**
|
|
||||||
* This app context, used to save on the DB
|
|
||||||
*/
|
|
||||||
private Context mContext;
|
|
||||||
/**
|
|
||||||
* The account who sign the transaction
|
|
||||||
*/
|
|
||||||
private GeneralCoinAccount mAccount;
|
|
||||||
|
|
||||||
private String serverUrl;
|
private String mPath;
|
||||||
|
|
||||||
|
private BroadCastTransactionListener listener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic Consturctor
|
* Basic Consturctor
|
||||||
* @param RawTx The RawTX in Hex String
|
* @param RawTx The RawTX in Hex String
|
||||||
* @param account The account who signs the transaction
|
*
|
||||||
* @param context This app context
|
|
||||||
*/
|
*/
|
||||||
public BroadcastTransaction(String RawTx, GeneralCoinAccount account, String serverUrl, Context context){
|
public BroadcastTransaction(String RawTx, String serverUrl, String path, BroadCastTransactionListener listener){
|
||||||
this.serverUrl = serverUrl;
|
|
||||||
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
||||||
this.mContext = context;
|
|
||||||
this.mRawTx = RawTx;
|
this.mRawTx = RawTx;
|
||||||
this.mAccount = account;
|
this.listener = listener;
|
||||||
|
this.mPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,13 +46,9 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
//TODO invalidated send
|
listener.onSuccess();
|
||||||
//TODO call getTransactionData
|
|
||||||
GetTransactionData trData = new GetTransactionData(response.body().txid,this.mAccount, this.serverUrl, this.mContext);
|
|
||||||
trData.start();
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println("SENDTEST: not succesful " + response.message());
|
listener.onFailure(response.message());
|
||||||
//TODO change how to handle invalid transaction
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +57,7 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<Txi> call, Throwable t) {
|
public void onFailure(Call<Txi> call, Throwable t) {
|
||||||
//TODO change how to handle invalid transaction
|
listener.onConnecitonFailure();
|
||||||
System.out.println("SENDTEST: sendError " + t.getMessage() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,8 +65,19 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
try {
|
||||||
Call<Txi> broadcastTransaction = service.broadcastTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),this.mRawTx);
|
|
||||||
broadcastTransaction.enqueue(this);
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import retrofit2.Response;
|
||||||
|
|
||||||
public abstract class GetEstimateFee {
|
public abstract class GetEstimateFee {
|
||||||
|
|
||||||
|
private static String PATH = "api";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The funciton to get the rate for the transaction be included in the next 2 blocks
|
* The funciton to get the rate for the transaction be included in the next 2 blocks
|
||||||
* @param serverUrl The url of the insight server
|
* @param serverUrl The url of the insight server
|
||||||
|
@ -29,28 +31,32 @@ public abstract class GetEstimateFee {
|
||||||
try {
|
try {
|
||||||
InsightApiServiceGenerator serviceGenerator = new InsightApiServiceGenerator(serverUrl);
|
InsightApiServiceGenerator serviceGenerator = new InsightApiServiceGenerator(serverUrl);
|
||||||
InsightApiService service = serviceGenerator.getService(InsightApiService.class);
|
InsightApiService service = serviceGenerator.getService(InsightApiService.class);
|
||||||
Call<JsonObject> call = service.estimateFee(serverUrl);
|
Call<JsonObject> call = service.estimateFee(PATH);
|
||||||
final JsonObject answer = new JsonObject();
|
|
||||||
call.enqueue(new Callback<JsonObject>() {
|
call.enqueue(new Callback<JsonObject>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
listener.estimateFee((long) (answer.get("answer").getAsDouble()));
|
try {
|
||||||
|
listener.estimateFee((double) (response.body().get("2").getAsDouble()));
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
listener.fail();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||||
listener.fail();
|
listener.fail();
|
||||||
listener.estimateFee(-1);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
listener.fail();
|
listener.fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface estimateFeeListener{
|
public static interface estimateFeeListener{
|
||||||
public void estimateFee(long value);
|
public void estimateFee(double value);
|
||||||
public void fail();
|
public void fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,15 @@
|
||||||
package cy.agorise.crystalwallet.apigenerator.insightapi;
|
package cy.agorise.crystalwallet.apigenerator.insightapi;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.AddressTxi;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.AddressTxi;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
|
import cy.agorise.crystalwallet.manager.GeneralAccountManager;
|
||||||
import cy.agorise.crystalwallet.models.GTxIO;
|
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
|
||||||
import cy.agorise.crystalwallet.models.GeneralTransaction;
|
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
@ -25,43 +20,40 @@ import retrofit2.Response;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GetTransactionByAddress extends Thread implements Callback<AddressTxi> {
|
public class GetTransactionByAddress extends Thread implements Callback<AddressTxi> {
|
||||||
/**
|
|
||||||
* The account to be query
|
|
||||||
*/
|
|
||||||
private GeneralCoinAccount mAccount;
|
|
||||||
/**
|
/**
|
||||||
* The list of address to query
|
* The list of address to query
|
||||||
*/
|
*/
|
||||||
private List<GeneralCoinAddress> mAddresses = new ArrayList<>();
|
private List<String> mAddresses = new ArrayList<>();
|
||||||
/**
|
/**
|
||||||
* The serviceGenerator to call
|
* The serviceGenerator to call
|
||||||
*/
|
*/
|
||||||
private InsightApiServiceGenerator mServiceGenerator;
|
private InsightApiServiceGenerator mServiceGenerator;
|
||||||
/**
|
|
||||||
* This app context, used to save on the DB
|
|
||||||
*/
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
private String serverUrl;
|
private String mServerUrl;
|
||||||
|
|
||||||
|
private String mPath;
|
||||||
|
private CryptoCoin cryptoNet;
|
||||||
|
|
||||||
|
private boolean inProcess = false;
|
||||||
|
|
||||||
|
private InsightApiGenerator.HasTransactionListener listener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic consturcotr
|
* Basic consturcotr
|
||||||
* @param account The account to be query
|
|
||||||
* @param context This app context
|
|
||||||
*/
|
*/
|
||||||
public GetTransactionByAddress(GeneralCoinAccount account, String serverUrl, Context context) {
|
public GetTransactionByAddress(CryptoCoin cryptoNet, String serverUrl, String path, InsightApiGenerator.HasTransactionListener listener) {
|
||||||
this.serverUrl = serverUrl;
|
this.mPath = path;
|
||||||
this.mAccount = account;
|
this.cryptoNet = cryptoNet;
|
||||||
|
this.mServerUrl = serverUrl;
|
||||||
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
||||||
this.mContext = context;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add an address to be query
|
* add an address to be query
|
||||||
* @param address the address to be query
|
* @param address the address to be query
|
||||||
*/
|
*/
|
||||||
public void addAddress(GeneralCoinAddress address) {
|
public void addAddress(String address) {
|
||||||
this.mAddresses.add(address);
|
this.mAddresses.add(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,110 +65,23 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<AddressTxi> call, Response<AddressTxi> response) {
|
public void onResponse(Call<AddressTxi> call, Response<AddressTxi> response) {
|
||||||
|
inProcess = false;
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
boolean changed = false;
|
|
||||||
AddressTxi addressTxi = response.body();
|
AddressTxi addressTxi = response.body();
|
||||||
|
if(listener != null) {
|
||||||
|
if (addressTxi.items.length > 0 ) {
|
||||||
|
listener.hasTransaction(true);
|
||||||
|
}else{
|
||||||
|
listener.hasTransaction(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Txi txi : addressTxi.items) {
|
for (Txi txi : addressTxi.items) {
|
||||||
GeneralCoinAccount tempAccount = null;
|
GeneralAccountManager.getAccountManager(this.cryptoNet).processTxi(txi);
|
||||||
GeneralTransaction transaction = new GeneralTransaction();
|
|
||||||
transaction.setAccount(this.mAccount);
|
|
||||||
transaction.setTxid(txi.txid);
|
|
||||||
transaction.setBlock(txi.blockheight);
|
|
||||||
transaction.setDate(new Date(txi.time * 1000));
|
|
||||||
transaction.setFee((long) (txi.fee * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
transaction.setConfirm(txi.confirmations);
|
|
||||||
transaction.setType(this.mAccount.getCryptoCoin());
|
|
||||||
transaction.setBlockHeight(txi.blockheight);
|
|
||||||
|
|
||||||
for (Vin vin : txi.vin) {
|
|
||||||
GTxIO input = new GTxIO();
|
|
||||||
input.setAmount((long) (vin.value * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
input.setTransaction(transaction);
|
|
||||||
input.setOut(true);
|
|
||||||
input.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vin.addr;
|
|
||||||
input.setAddressString(addr);
|
|
||||||
input.setIndex(vin.n);
|
|
||||||
input.setScriptHex(vin.scriptSig.hex);
|
|
||||||
input.setOriginalTxid(vin.txid);
|
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
input.setAddress(address);
|
|
||||||
tempAccount = address.getAccount();
|
|
||||||
|
|
||||||
if (!address.hasTransactionOutput(input, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionOutput().add(input);
|
|
||||||
}
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transaction.getTxInputs().add(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Vout vout : txi.vout) {
|
|
||||||
if(vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0){
|
|
||||||
// The address is null, this must be a memo
|
|
||||||
String hex = vout.scriptPubKey.hex;
|
|
||||||
int opReturnIndex = hex.indexOf("6a");
|
|
||||||
if(opReturnIndex >= 0) {
|
|
||||||
byte[] memoBytes = new byte[Integer.parseInt(hex.substring(opReturnIndex+2,opReturnIndex+4),16)];
|
|
||||||
for(int i = 0; i < memoBytes.length;i++){
|
|
||||||
memoBytes[i] = Byte.parseByte(hex.substring(opReturnIndex+4+(i*2),opReturnIndex+6+(i*2)),16);
|
|
||||||
}
|
|
||||||
transaction.setMemo(new String(memoBytes));
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
GTxIO output = new GTxIO();
|
|
||||||
output.setAmount((long) (vout.value * Math.pow(10, this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
output.setTransaction(transaction);
|
|
||||||
output.setOut(false);
|
|
||||||
output.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vout.scriptPubKey.addresses[0];
|
|
||||||
output.setAddressString(addr);
|
|
||||||
output.setIndex(vout.n);
|
|
||||||
output.setScriptHex(vout.scriptPubKey.hex);
|
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
output.setAddress(address);
|
|
||||||
tempAccount = address.getAccount();
|
|
||||||
|
|
||||||
if (!address.hasTransactionInput(output, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionInput().add(output);
|
|
||||||
}
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.getTxOutputs().add(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(txi.txlock && txi.confirmations< this.mAccount.getCryptoNet().getConfirmationsNeeded()){
|
|
||||||
transaction.setConfirm(this.mAccount.getCryptoNet().getConfirmationsNeeded());
|
|
||||||
}
|
|
||||||
//TODO database
|
|
||||||
/*SCWallDatabase db = new SCWallDatabase(this.mContext);
|
|
||||||
long idTransaction = db.getGeneralTransactionId(transaction);
|
|
||||||
if (idTransaction == -1) {
|
|
||||||
db.putGeneralTransaction(transaction);
|
|
||||||
} else {
|
|
||||||
transaction.setId(idTransaction);
|
|
||||||
db.updateGeneralTransaction(transaction);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (tempAccount != null && transaction.getConfirm() < this.mAccount.getCryptoNet().getConfirmationsNeeded()) {
|
|
||||||
new GetTransactionData(transaction.getTxid(), tempAccount, this.serverUrl, this.mContext, true).start();
|
|
||||||
}
|
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
|
||||||
if (address.updateTransaction(transaction)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(changed) {
|
}else{
|
||||||
this.mAccount.balanceChange();
|
listener.hasTransaction(false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +92,7 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<AddressTxi> call, Throwable t) {
|
public void onFailure(Call<AddressTxi> call, Throwable t) {
|
||||||
|
inProcess = false;
|
||||||
Log.e("GetTransactionByAddress", "Error in json format");
|
Log.e("GetTransactionByAddress", "Error in json format");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,14 +101,15 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (this.mAddresses.size() > 0) {
|
if (this.mAddresses.size() > 0 && !inProcess) {
|
||||||
|
inProcess = true;
|
||||||
StringBuilder addressToQuery = new StringBuilder();
|
StringBuilder addressToQuery = new StringBuilder();
|
||||||
for (GeneralCoinAddress address : this.mAddresses) {
|
for (String address : this.mAddresses) {
|
||||||
addressToQuery.append(address.getAddressString(this.mAccount.getNetworkParam())).append(",");
|
addressToQuery.append(address).append(",");
|
||||||
}
|
}
|
||||||
addressToQuery.deleteCharAt(addressToQuery.length() - 1);
|
addressToQuery.deleteCharAt(addressToQuery.length() - 1);
|
||||||
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
||||||
Call<AddressTxi> addressTxiCall = service.getTransactionByAddress(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),addressToQuery.toString());
|
Call<AddressTxi> addressTxiCall = service.getTransactionByAddress(this.mPath,addressToQuery.toString());
|
||||||
addressTxiCall.enqueue(this);
|
addressTxiCall.enqueue(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Date;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
|
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.manager.GeneralAccountManager;
|
||||||
import cy.agorise.crystalwallet.models.GTxIO;
|
import cy.agorise.crystalwallet.models.GTxIO;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
||||||
|
@ -20,10 +22,6 @@ import retrofit2.Response;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GetTransactionData extends Thread implements Callback<Txi> {
|
public class GetTransactionData extends Thread implements Callback<Txi> {
|
||||||
/**
|
|
||||||
* The account to be query
|
|
||||||
*/
|
|
||||||
private final GeneralCoinAccount mAccount;
|
|
||||||
/**
|
/**
|
||||||
* The transaction txid to be query
|
* The transaction txid to be query
|
||||||
*/
|
*/
|
||||||
|
@ -32,41 +30,38 @@ public class GetTransactionData extends Thread implements Callback<Txi> {
|
||||||
* The serviceGenerator to call
|
* The serviceGenerator to call
|
||||||
*/
|
*/
|
||||||
private InsightApiServiceGenerator mServiceGenerator;
|
private InsightApiServiceGenerator mServiceGenerator;
|
||||||
/**
|
|
||||||
* This app context, used to save on the DB
|
|
||||||
*/
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
private String mServerUrl;
|
private String mServerUrl;
|
||||||
|
|
||||||
|
private String mPath;
|
||||||
/**
|
/**
|
||||||
* If has to wait for another confirmation
|
* If has to wait for another confirmation
|
||||||
*/
|
*/
|
||||||
private boolean mMustWait = false;
|
private boolean mMustWait = false;
|
||||||
|
|
||||||
|
private CryptoCoin cryptoCoin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used to query for a transaction with unknown confirmations
|
* Constructor used to query for a transaction with unknown confirmations
|
||||||
* @param txid The txid of the transaciton to be query
|
* @param txid The txid of the transaciton to be query
|
||||||
* @param account The account to be query
|
|
||||||
* @param context This app Context
|
|
||||||
*/
|
*/
|
||||||
public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context) {
|
public GetTransactionData(String txid, String serverUrl, String path, CryptoCoin cryptoCoin) {
|
||||||
this(txid, account, serverUrl, context, false);
|
this(txid, serverUrl, path, cryptoCoin, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consturctor to be used qhen the confirmations of the transaction are known
|
* Consturctor to be used qhen the confirmations of the transaction are known
|
||||||
* @param txid The txid of the transaciton to be query
|
* @param txid The txid of the transaciton to be query
|
||||||
* @param account The account to be query
|
|
||||||
* @param context This app Context
|
|
||||||
* @param mustWait If there is less confirmation that needed
|
* @param mustWait If there is less confirmation that needed
|
||||||
*/
|
*/
|
||||||
public GetTransactionData(String txid, GeneralCoinAccount account,String serverUrl, Context context, boolean mustWait) {
|
public GetTransactionData(String txid, String serverUrl, String path, CryptoCoin cryptoCoin, boolean mustWait) {
|
||||||
|
this.mPath = path;
|
||||||
this.mServerUrl = serverUrl;
|
this.mServerUrl = serverUrl;
|
||||||
this.mAccount = account;
|
|
||||||
this.mTxId= txid;
|
this.mTxId= txid;
|
||||||
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
|
||||||
this.mContext = context;
|
|
||||||
this.mMustWait = mustWait;
|
this.mMustWait = mustWait;
|
||||||
|
this.cryptoCoin = cryptoCoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,104 +79,19 @@ public class GetTransactionData extends Thread implements Callback<Txi> {
|
||||||
}
|
}
|
||||||
|
|
||||||
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
|
||||||
Call<Txi> txiCall = service.getTransaction(InsightApiConstants.getPath(this.mAccount.getCryptoCoin()),this.mTxId);
|
Call<Txi> txiCall = service.getTransaction(this.mPath,this.mTxId);
|
||||||
txiCall.enqueue(this);
|
txiCall.enqueue(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
public void onResponse(Call<Txi> call, Response<Txi> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
|
|
||||||
Txi txi = response.body();
|
Txi txi = response.body();
|
||||||
|
GeneralAccountManager.getAccountManager(this.cryptoCoin).processTxi(txi);
|
||||||
GeneralTransaction transaction = new GeneralTransaction();
|
if (txi.confirmations < this.cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
|
||||||
transaction.setAccount(this.mAccount);
|
|
||||||
transaction.setTxid(txi.txid);
|
|
||||||
transaction.setBlock(txi.blockheight);
|
|
||||||
transaction.setDate(new Date(txi.time * 1000));
|
|
||||||
transaction.setFee((long) (txi.fee * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
transaction.setConfirm(txi.confirmations);
|
|
||||||
transaction.setType(this.mAccount.getCryptoCoin());
|
|
||||||
transaction.setBlockHeight(txi.blockheight);
|
|
||||||
|
|
||||||
for (Vin vin : txi.vin) {
|
|
||||||
GTxIO input = new GTxIO();
|
|
||||||
input.setAmount((long) (vin.value * Math.pow(10,this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
input.setTransaction(transaction);
|
|
||||||
input.setOut(true);
|
|
||||||
input.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vin.addr;
|
|
||||||
input.setAddressString(addr);
|
|
||||||
input.setIndex(vin.n);
|
|
||||||
input.setScriptHex(vin.scriptSig.hex);
|
|
||||||
input.setOriginalTxid(vin.txid);
|
|
||||||
for (GeneralCoinAddress address : this.mAccount.getAddresses()) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
input.setAddress(address);
|
|
||||||
if (!address.hasTransactionOutput(input, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionOutput().add(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transaction.getTxInputs().add(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Vout vout : txi.vout) {
|
|
||||||
if(vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0){
|
|
||||||
// The address is null, this must be a memo
|
|
||||||
String hex = vout.scriptPubKey.hex;
|
|
||||||
int opReturnIndex = hex.indexOf("6a");
|
|
||||||
if(opReturnIndex >= 0) {
|
|
||||||
byte[] memoBytes = new byte[Integer.parseInt(hex.substring(opReturnIndex+2,opReturnIndex+4),16)];
|
|
||||||
for(int i = 0; i < memoBytes.length;i++){
|
|
||||||
memoBytes[i] = Byte.parseByte(hex.substring(opReturnIndex+4+(i*2),opReturnIndex+6+(i*2)),16);
|
|
||||||
}
|
|
||||||
transaction.setMemo(new String(memoBytes));
|
|
||||||
System.out.println("Memo read : " + transaction.getMemo()); //TODO log this line
|
|
||||||
}
|
|
||||||
|
|
||||||
}else {
|
|
||||||
GTxIO output = new GTxIO();
|
|
||||||
output.setAmount((long) (vout.value * Math.pow(10, this.mAccount.getCryptoCoin().getPrecision())));
|
|
||||||
output.setTransaction(transaction);
|
|
||||||
output.setOut(false);
|
|
||||||
output.setType(this.mAccount.getCryptoCoin());
|
|
||||||
String addr = vout.scriptPubKey.addresses[0];
|
|
||||||
output.setAddressString(addr);
|
|
||||||
output.setIndex(vout.n);
|
|
||||||
output.setScriptHex(vout.scriptPubKey.hex);
|
|
||||||
for (GeneralCoinAddress address : this.mAccount.getAddresses()) {
|
|
||||||
if (address.getAddressString(this.mAccount.getNetworkParam()).equals(addr)) {
|
|
||||||
output.setAddress(address);
|
|
||||||
if (!address.hasTransactionInput(output, this.mAccount.getNetworkParam())) {
|
|
||||||
address.getTransactionInput().add(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transaction.getTxOutputs().add(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is for features like dash instantSend
|
|
||||||
if(txi.txlock && txi.confirmations< this.mAccount.getCryptoNet().getConfirmationsNeeded()){
|
|
||||||
transaction.setConfirm(this.mAccount.getCryptoNet().getConfirmationsNeeded());
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO database
|
|
||||||
/*SCWallDatabase db = new SCWallDatabase(this.mContext);
|
|
||||||
long idTransaction = db.getGeneralTransactionId(transaction);
|
|
||||||
if (idTransaction == -1) {
|
|
||||||
db.putGeneralTransaction(transaction);
|
|
||||||
} else {
|
|
||||||
transaction.setId(idTransaction);
|
|
||||||
db.updateGeneralTransaction(transaction);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
this.mAccount.updateTransaction(transaction);
|
|
||||||
this.mAccount.balanceChange();
|
|
||||||
|
|
||||||
if (transaction.getConfirm() < this.mAccount.getCryptoNet().getConfirmationsNeeded()) {
|
|
||||||
//If transaction weren't confirmed, add the transaction to watch for change on the confirmations
|
//If transaction weren't confirmed, add the transaction to watch for change on the confirmations
|
||||||
new GetTransactionData(this.mTxId, this.mAccount, this.mServerUrl, this.mContext, true).start();
|
new GetTransactionData(this.mTxId, this.mServerUrl, this.mPath, this.cryptoCoin, true).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,4 +49,7 @@ interface InsightApiService {
|
||||||
@GET("{path}/utils/estimatefee?nbBlocks=2")
|
@GET("{path}/utils/estimatefee?nbBlocks=2")
|
||||||
Call<JsonObject> estimateFee(@Path(value = "path", encoded = true) String path);
|
Call<JsonObject> estimateFee(@Path(value = "path", encoded = true) String path);
|
||||||
|
|
||||||
|
@GET("{path}/block-index/0")
|
||||||
|
Call<JsonObject> genesisBlock(@Path(value = "path", encoded = true) String path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,8 +97,8 @@ class InsightApiServiceGenerator {
|
||||||
return chain.proceed(request);
|
return chain.proceed(request);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
sClientBuilder.readTimeout(5, TimeUnit.MINUTES);
|
sClientBuilder.readTimeout(30, TimeUnit.SECONDS);
|
||||||
sClientBuilder.connectTimeout(5, TimeUnit.MINUTES);
|
sClientBuilder.connectTimeout(30, TimeUnit.SECONDS);
|
||||||
OkHttpClient client = sClientBuilder.build();
|
OkHttpClient client = sClientBuilder.build();
|
||||||
Retrofit retrofit = sBuilder.client(client).build();
|
Retrofit retrofit = sBuilder.client(client).build();
|
||||||
return retrofit.create(serviceClass);
|
return retrofit.create(serviceClass);
|
||||||
|
|
|
@ -17,6 +17,7 @@ import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
import cy.agorise.crystalwallet.enums.CryptoNet;
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAsset;
|
import cy.agorise.crystalwallet.models.BitsharesAsset;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
|
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoCurrency;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
|
import cy.agorise.crystalwallet.models.CryptoCurrencyEquivalence;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.network.CryptoNetManager;
|
import cy.agorise.crystalwallet.network.CryptoNetManager;
|
||||||
|
@ -49,6 +50,27 @@ public class CrystalApplication extends Application {
|
||||||
//This is for testing the equivalent values on the testnet TODO remove
|
//This is for testing the equivalent values on the testnet TODO remove
|
||||||
public static BitsharesAsset bitEURAsset = new BitsharesAsset("EUR",4,"1.3.120",BitsharesAsset.Type.SMART_COIN);
|
public static BitsharesAsset bitEURAsset = new BitsharesAsset("EUR",4,"1.3.120",BitsharesAsset.Type.SMART_COIN);
|
||||||
|
|
||||||
|
|
||||||
|
public static final String BITCOIN_SERVER_URLS[] ={
|
||||||
|
"https://testnet.blockexplorer.com/",
|
||||||
|
"https://test-insight.bitpay.com",
|
||||||
|
//"https://insight.bitpay.com/"
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final CryptoCurrency BITCOIN_CURRENCY = new CryptoCurrency("BTC",CryptoNet.BITCOIN,8);
|
||||||
|
|
||||||
|
public static String STEEM_URL[] =
|
||||||
|
{
|
||||||
|
"https://api.steemit.com",
|
||||||
|
"https://api.steemitdev.com",
|
||||||
|
"https://api.steemitstage.com",
|
||||||
|
"https://api.steem.house",
|
||||||
|
"https://appbasetest.timcliff.com",
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
@ -62,10 +84,10 @@ public class CrystalApplication extends Application {
|
||||||
|
|
||||||
//This is for testing the equivalent values on the testnet TODO remove
|
//This is for testing the equivalent values on the testnet TODO remove
|
||||||
if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitEURAsset.getBitsharesId())== null){
|
if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitEURAsset.getBitsharesId())== null){
|
||||||
if(db.cryptoCurrencyDao().getByName(bitEURAsset.getName())== null){
|
if(db.cryptoCurrencyDao().getByName(bitEURAsset.getName(),bitEURAsset.getCryptoNet().name())== null){
|
||||||
db.cryptoCurrencyDao().insertCryptoCurrency(bitEURAsset);
|
db.cryptoCurrencyDao().insertCryptoCurrency(bitEURAsset);
|
||||||
}
|
}
|
||||||
long idCurrency = db.cryptoCurrencyDao().getByName(bitEURAsset.getName()).getId();
|
long idCurrency = db.cryptoCurrencyDao().getByName(bitEURAsset.getName(),bitEURAsset.getCryptoNet().name()).getId();
|
||||||
BitsharesAssetInfo info = new BitsharesAssetInfo(bitEURAsset);
|
BitsharesAssetInfo info = new BitsharesAssetInfo(bitEURAsset);
|
||||||
info.setCryptoCurrencyId(idCurrency);
|
info.setCryptoCurrencyId(idCurrency);
|
||||||
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
|
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
|
||||||
|
@ -74,10 +96,10 @@ public class CrystalApplication extends Application {
|
||||||
|
|
||||||
//This is for testing the equivalent values on the testnet TODO remove
|
//This is for testing the equivalent values on the testnet TODO remove
|
||||||
if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitUSDAsset.getBitsharesId())== null){
|
if(db.bitsharesAssetDao().getBitsharesAssetInfoById(bitUSDAsset.getBitsharesId())== null){
|
||||||
if(db.cryptoCurrencyDao().getByName(bitUSDAsset.getName())== null){
|
if(db.cryptoCurrencyDao().getByName(bitUSDAsset.getName(),bitUSDAsset.getCryptoNet().name())== null){
|
||||||
db.cryptoCurrencyDao().insertCryptoCurrency(bitUSDAsset);
|
db.cryptoCurrencyDao().insertCryptoCurrency(bitUSDAsset);
|
||||||
}
|
}
|
||||||
long idCurrency = db.cryptoCurrencyDao().getByName(bitUSDAsset.getName()).getId();
|
long idCurrency = db.cryptoCurrencyDao().getByName(bitUSDAsset.getName(),bitUSDAsset.getCryptoNet().name()).getId();
|
||||||
BitsharesAssetInfo info = new BitsharesAssetInfo(bitUSDAsset);
|
BitsharesAssetInfo info = new BitsharesAssetInfo(bitUSDAsset);
|
||||||
info.setCryptoCurrencyId(idCurrency);
|
info.setCryptoCurrencyId(idCurrency);
|
||||||
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
|
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
|
||||||
|
@ -93,6 +115,16 @@ public class CrystalApplication extends Application {
|
||||||
// TODO and hoop over the urls if no connection can be established
|
// TODO and hoop over the urls if no connection can be established
|
||||||
CryptoNetManager.addCryptoNetURL(CryptoNet.BITSHARES,BITSHARES_URL);
|
CryptoNetManager.addCryptoNetURL(CryptoNet.BITSHARES,BITSHARES_URL);
|
||||||
|
|
||||||
|
//Adding Bitcoin info
|
||||||
|
CryptoNetManager.addCryptoNetURL(CryptoNet.BITCOIN,BITCOIN_SERVER_URLS);
|
||||||
|
|
||||||
|
if(db.cryptoCurrencyDao().getByName(BITCOIN_CURRENCY.getName(),BITCOIN_CURRENCY.getCryptoNet().name())== null){
|
||||||
|
db.cryptoCurrencyDao().insertCryptoCurrency(BITCOIN_CURRENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoNetManager.addCryptoNetURL(CryptoNet.STEEM,STEEM_URL);
|
||||||
|
|
||||||
|
|
||||||
GeneralSetting generalSettingPreferredLanguage = db.generalSettingDao().getSettingByName(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE);
|
GeneralSetting generalSettingPreferredLanguage = db.generalSettingDao().getSettingByName(GeneralSetting.SETTING_NAME_PREFERRED_LANGUAGE);
|
||||||
|
|
||||||
if (generalSettingPreferredLanguage != null) {
|
if (generalSettingPreferredLanguage != null) {
|
||||||
|
@ -105,6 +137,11 @@ public class CrystalApplication extends Application {
|
||||||
resources.updateConfiguration(configuration, dm);
|
resources.updateConfiguration(configuration, dm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
|
||||||
Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class);
|
Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ import java.util.List;
|
||||||
import cy.agorise.crystalwallet.activities.PatternRequestActivity;
|
import cy.agorise.crystalwallet.activities.PatternRequestActivity;
|
||||||
import cy.agorise.crystalwallet.activities.PinRequestActivity;
|
import cy.agorise.crystalwallet.activities.PinRequestActivity;
|
||||||
import cy.agorise.crystalwallet.activities.PocketRequestActivity;
|
import cy.agorise.crystalwallet.activities.PocketRequestActivity;
|
||||||
|
import cy.agorise.crystalwallet.fragments.PatternSecurityFragment;
|
||||||
|
import cy.agorise.crystalwallet.interfaces.OnResponse;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.notifiers.CrystalWalletNotifier;
|
import cy.agorise.crystalwallet.notifiers.CrystalWalletNotifier;
|
||||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
|
@ -129,7 +131,7 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
||||||
public void onActivityStarted(Activity activity) {
|
public void onActivityStarted(Activity activity) {
|
||||||
if (numStarted == 0) {
|
if (numStarted == 0) {
|
||||||
if (!actualSecurity().equals("")){
|
if (!actualSecurity().equals("")){
|
||||||
callPasswordRequest(activity);
|
callPasswordRequest(activity,null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
numStarted++;
|
numStarted++;
|
||||||
|
@ -140,18 +142,41 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
||||||
numStarted--;
|
numStarted--;
|
||||||
if (numStarted == 0) {
|
if (numStarted == 0) {
|
||||||
if (!actualSecurity().equals("")){
|
if (!actualSecurity().equals("")){
|
||||||
callPasswordRequest(activity);
|
callPasswordRequest(activity,null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void callPasswordRequest(Activity activity){
|
public void callPasswordRequest(Activity activity, final OnResponse onResponsePattern){
|
||||||
if ((!activity.getIntent().hasExtra("ACTIVITY_TYPE")) || (!activity.getIntent().getStringExtra("ACTIVITY_TYPE").equals("PASSWORD_REQUEST"))) {
|
if ((!activity.getIntent().hasExtra("ACTIVITY_TYPE")) || (!activity.getIntent().getStringExtra("ACTIVITY_TYPE").equals("PASSWORD_REQUEST"))) {
|
||||||
Intent intent = null;
|
Intent intent = null;
|
||||||
if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) {
|
if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) {
|
||||||
|
|
||||||
intent = new Intent(activity, PinRequestActivity.class);
|
intent = new Intent(activity, PinRequestActivity.class);
|
||||||
|
|
||||||
|
PinRequestActivity.setOnResponse(null);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connect error and success listeners
|
||||||
|
* */
|
||||||
|
if(onResponsePattern != null){
|
||||||
|
PinRequestActivity.setOnResponse(onResponsePattern);
|
||||||
|
}
|
||||||
|
|
||||||
} else if ((this.patternEncrypted != null) && (!this.patternEncrypted.equals(""))) {
|
} else if ((this.patternEncrypted != null) && (!this.patternEncrypted.equals(""))) {
|
||||||
|
|
||||||
intent = new Intent(activity, PatternRequestActivity.class);
|
intent = new Intent(activity, PatternRequestActivity.class);
|
||||||
|
|
||||||
|
PatternRequestActivity.setOnResponse(null);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connect error and success listeners
|
||||||
|
* */
|
||||||
|
if(onResponsePattern != null){
|
||||||
|
PatternRequestActivity.setOnResponse(onResponsePattern);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onResponsePattern.onSuccess();
|
||||||
}
|
}
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST");
|
intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST");
|
||||||
|
@ -197,7 +222,4 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
||||||
public void onActivityDestroyed(Activity activity) {
|
public void onActivityDestroyed(Activity activity) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -32,7 +32,7 @@ public abstract class BitsharesConstant {
|
||||||
|
|
||||||
//testnet faucet
|
//testnet faucet
|
||||||
//public final static String FAUCET_URL = "http://185.208.208.147:5010";
|
//public final static String FAUCET_URL = "http://185.208.208.147:5010";
|
||||||
public final static String FAUCET_URL = "https://de.palmpay.io";
|
public final static String FAUCET_URL = "https://faucet.palmpay.io";
|
||||||
public final static String EQUIVALENT_URL = "wss://bitshares.openledger.info/ws";
|
public final static String EQUIVALENT_URL = "wss://bitshares.openledger.info/ws";
|
||||||
|
|
||||||
public final static BitsharesAsset[] SMARTCOINS = new BitsharesAsset[]{
|
public final static BitsharesAsset[] SMARTCOINS = new BitsharesAsset[]{
|
||||||
|
@ -74,10 +74,10 @@ public abstract class BitsharesConstant {
|
||||||
public static void addSmartCoins(Context context){
|
public static void addSmartCoins(Context context){
|
||||||
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
for(BitsharesAsset smartcoin : SMARTCOINS){
|
for(BitsharesAsset smartcoin : SMARTCOINS){
|
||||||
if(db.cryptoCurrencyDao().getByName(smartcoin.getName())== null){
|
if(db.cryptoCurrencyDao().getByName(smartcoin.getName(),CryptoNet.BITSHARES.name())== null){
|
||||||
db.cryptoCurrencyDao().insertCryptoCurrency(smartcoin);
|
db.cryptoCurrencyDao().insertCryptoCurrency(smartcoin);
|
||||||
}
|
}
|
||||||
long idCurrency = db.cryptoCurrencyDao().getByName(smartcoin.getName()).getId();
|
long idCurrency = db.cryptoCurrencyDao().getByName(smartcoin.getName(),CryptoNet.BITSHARES.name()).getId();
|
||||||
BitsharesAssetInfo info = new BitsharesAssetInfo(smartcoin);
|
BitsharesAssetInfo info = new BitsharesAssetInfo(smartcoin);
|
||||||
info.setCryptoCurrencyId(idCurrency);
|
info.setCryptoCurrencyId(idCurrency);
|
||||||
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
|
db.bitsharesAssetDao().insertBitsharesAssetInfo(info);
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package cy.agorise.crystalwallet.dao;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.arch.persistence.room.Dao;
|
||||||
|
import android.arch.persistence.room.Insert;
|
||||||
|
import android.arch.persistence.room.OnConflictStrategy;
|
||||||
|
import android.arch.persistence.room.Query;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinAddress;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransaction;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransactionExtended;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Henry Varona on 10/17/2018.
|
||||||
|
*/
|
||||||
|
@Dao
|
||||||
|
public interface BitcoinAddressDao {
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_address")
|
||||||
|
LiveData<BitcoinAddress> getAll();
|
||||||
|
|
||||||
|
@Query("SELECT COUNT(*) FROM bitcoin_address ba WHERE ba.address = :address")
|
||||||
|
Boolean addressExists(String address);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address = :address")
|
||||||
|
BitcoinAddress getdadress(String address);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address_index = :index and ba.is_change = 'true'")
|
||||||
|
BitcoinAddress getChangeByIndex(long index);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address_index = :index and ba.is_change = 'false'")
|
||||||
|
BitcoinAddress getExternalByIndex(long index);
|
||||||
|
|
||||||
|
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'true' ")
|
||||||
|
long getLastChangeAddress(long accountId);
|
||||||
|
|
||||||
|
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'false' ")
|
||||||
|
long getLastExternalAddress(long accountId);
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
public long[] insertBitcoinAddresses(BitcoinAddress... addresses);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package cy.agorise.crystalwallet.dao;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.arch.persistence.room.Dao;
|
||||||
|
import android.arch.persistence.room.Insert;
|
||||||
|
import android.arch.persistence.room.OnConflictStrategy;
|
||||||
|
import android.arch.persistence.room.Query;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransaction;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransactionExtended;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransactionGTxIO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Henry Varona on 10/02/2018.
|
||||||
|
*/
|
||||||
|
@Dao
|
||||||
|
public interface BitcoinTransactionDao {
|
||||||
|
|
||||||
|
@Query("SELECT * FROM crypto_coin_transaction cct, bitcoin_transaction bt WHERE bt.crypto_coin_transaction_id = cct.id")
|
||||||
|
LiveData<BitcoinTransactionExtended> getAll();
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_transaction bt WHERE bt.tx_id = :txid")
|
||||||
|
List<BitcoinTransaction> getTransactionsByTxid(String txid);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_transaction bt WHERE bt.crypto_coin_transaction_id = :idCryptoCoinTransaction")
|
||||||
|
BitcoinTransaction getBitcoinTransactionByCryptoCoinTransaction(long idCryptoCoinTransaction);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_transaction_gt_io bt WHERE bt.bitcoin_transaction_id= :idBitcoinTransaction")
|
||||||
|
List<BitcoinTransactionGTxIO> getGtxIOByTransaction(long idBitcoinTransaction);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM bitcoin_transaction_gt_io bt WHERE bt.address= :address")
|
||||||
|
List<BitcoinTransactionGTxIO> getGtxIOByAddress(String address);
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
public long[] insertBitcoinTransaction(BitcoinTransaction... transactions);
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
public long[] insertBitcoinTransactionGTxIO(BitcoinTransactionGTxIO... transactiongtxios);
|
||||||
|
}
|
|
@ -23,6 +23,9 @@ public interface CryptoCurrencyDao {
|
||||||
@Query("SELECT * FROM crypto_currency WHERE id = :id")
|
@Query("SELECT * FROM crypto_currency WHERE id = :id")
|
||||||
CryptoCurrency getById(long id);
|
CryptoCurrency getById(long id);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM crypto_currency WHERE id = :id")
|
||||||
|
LiveData<CryptoCurrency> getLDById(long id);
|
||||||
|
|
||||||
@Query("SELECT * FROM crypto_currency WHERE name = :name AND crypto_net = :cryptoNet")
|
@Query("SELECT * FROM crypto_currency WHERE name = :name AND crypto_net = :cryptoNet")
|
||||||
CryptoCurrency getByNameAndCryptoNet(String name,String cryptoNet);
|
CryptoCurrency getByNameAndCryptoNet(String name,String cryptoNet);
|
||||||
|
|
||||||
|
@ -32,8 +35,8 @@ public interface CryptoCurrencyDao {
|
||||||
@Query("SELECT * FROM crypto_currency WHERE name = :name")
|
@Query("SELECT * FROM crypto_currency WHERE name = :name")
|
||||||
LiveData<CryptoCurrency> getLiveDataByName(String name);
|
LiveData<CryptoCurrency> getLiveDataByName(String name);
|
||||||
|
|
||||||
@Query("SELECT * FROM crypto_currency WHERE name = :name")
|
@Query("SELECT * FROM crypto_currency WHERE name = :name and crypto_net = :cryptoNet")
|
||||||
CryptoCurrency getByName(String name);
|
CryptoCurrency getByName(String name, String cryptoNet);
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
public long[] insertCryptoCurrency(CryptoCurrency... currencies);
|
public long[] insertCryptoCurrency(CryptoCurrency... currencies);
|
||||||
|
|
|
@ -29,6 +29,9 @@ public interface CryptoNetAccountDao {
|
||||||
@Query("SELECT cna.* FROM crypto_net_account cna WHERE seed_id = :seedId")
|
@Query("SELECT cna.* FROM crypto_net_account cna WHERE seed_id = :seedId")
|
||||||
List<CryptoNetAccount> getAllCryptoNetAccountBySeed( long seedId);
|
List<CryptoNetAccount> getAllCryptoNetAccountBySeed( long seedId);
|
||||||
|
|
||||||
|
@Query("SELECT cna.* FROM crypto_net_account cna WHERE crypto_net == 'BITCOIN'")
|
||||||
|
LiveData<List<CryptoNetAccount>> getAllBitcoins();
|
||||||
|
|
||||||
@Query("SELECT * FROM crypto_net_account WHERE id = :accountId")
|
@Query("SELECT * FROM crypto_net_account WHERE id = :accountId")
|
||||||
LiveData<CryptoNetAccount> getByIdLiveData( long accountId);
|
LiveData<CryptoNetAccount> getByIdLiveData( long accountId);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ import android.content.Context;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.dao.converters.Converters;
|
import cy.agorise.crystalwallet.dao.converters.Converters;
|
||||||
import cy.agorise.crystalwallet.models.AccountSeed;
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinAddress;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransaction;
|
||||||
|
import cy.agorise.crystalwallet.models.BitcoinTransactionGTxIO;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
|
import cy.agorise.crystalwallet.models.BitsharesAssetInfo;
|
||||||
import cy.agorise.crystalwallet.models.Contact;
|
import cy.agorise.crystalwallet.models.Contact;
|
||||||
|
@ -39,8 +42,11 @@ import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
|
||||||
BitsharesAssetInfo.class,
|
BitsharesAssetInfo.class,
|
||||||
BitsharesAccountNameCache.class,
|
BitsharesAccountNameCache.class,
|
||||||
CryptoCurrencyEquivalence.class,
|
CryptoCurrencyEquivalence.class,
|
||||||
GeneralSetting.class
|
GeneralSetting.class,
|
||||||
}, version = 4, exportSchema = false)
|
BitcoinTransaction.class,
|
||||||
|
BitcoinTransactionGTxIO.class,
|
||||||
|
BitcoinAddress.class
|
||||||
|
}, version = 6, exportSchema = false)
|
||||||
@TypeConverters({Converters.class})
|
@TypeConverters({Converters.class})
|
||||||
public abstract class CrystalDatabase extends RoomDatabase {
|
public abstract class CrystalDatabase extends RoomDatabase {
|
||||||
|
|
||||||
|
@ -57,6 +63,8 @@ public abstract class CrystalDatabase extends RoomDatabase {
|
||||||
public abstract BitsharesAccountNameCacheDao bitsharesAccountNameCacheDao();
|
public abstract BitsharesAccountNameCacheDao bitsharesAccountNameCacheDao();
|
||||||
public abstract CryptoCurrencyEquivalenceDao cryptoCurrencyEquivalenceDao();
|
public abstract CryptoCurrencyEquivalenceDao cryptoCurrencyEquivalenceDao();
|
||||||
public abstract GeneralSettingDao generalSettingDao();
|
public abstract GeneralSettingDao generalSettingDao();
|
||||||
|
public abstract BitcoinTransactionDao bitcoinTransactionDao();
|
||||||
|
public abstract BitcoinAddressDao bitcoinAddressDao();
|
||||||
|
|
||||||
public static CrystalDatabase getAppDatabase(Context context) {
|
public static CrystalDatabase getAppDatabase(Context context) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
|
@ -64,8 +72,10 @@ public abstract class CrystalDatabase extends RoomDatabase {
|
||||||
Room.databaseBuilder(context,
|
Room.databaseBuilder(context,
|
||||||
CrystalDatabase.class, "CrystalWallet.db")
|
CrystalDatabase.class, "CrystalWallet.db")
|
||||||
.allowMainThreadQueries()
|
.allowMainThreadQueries()
|
||||||
.addMigrations(MIGRATION_2_3)
|
//.addMigrations(MIGRATION_2_3)
|
||||||
.addMigrations(MIGRATION_3_4)
|
//.addMigrations(MIGRATION_3_4)
|
||||||
|
//.addMigrations(MIGRATION_4_5)
|
||||||
|
//.addMigrations(MIGRATION_5_6)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -91,4 +101,41 @@ 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)");
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,10 @@ public interface TransactionDao {
|
||||||
List<CryptoCoinTransaction> getByIdAccount(long idAccount);
|
List<CryptoCoinTransaction> getByIdAccount(long idAccount);
|
||||||
|
|
||||||
@Query("SELECT * FROM crypto_coin_transaction WHERE id = :id")
|
@Query("SELECT * FROM crypto_coin_transaction WHERE id = :id")
|
||||||
LiveData<CryptoCoinTransaction> getById(long id);
|
LiveData<CryptoCoinTransaction> getByIdLiveData(long id);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM crypto_coin_transaction WHERE id = :id")
|
||||||
|
CryptoCoinTransaction getById(long id);
|
||||||
|
|
||||||
@Query("SELECT * FROM crypto_coin_transaction WHERE date = :date and 'from' = :from and 'to' = :to and amount = :amount ")
|
@Query("SELECT * FROM crypto_coin_transaction WHERE date = :date and 'from' = :from and 'to' = :to and amount = :amount ")
|
||||||
CryptoCoinTransaction getByTransaction(Date date, String from, String to, long amount);
|
CryptoCoinTransaction getByTransaction(Date date, String from, String to, long amount);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package cy.agorise.crystalwallet.enums;
|
package cy.agorise.crystalwallet.enums;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.NetworkParameters;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -11,21 +13,26 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public enum CryptoCoin implements Serializable {
|
public enum CryptoCoin implements Serializable {
|
||||||
BITCOIN(CryptoNet.BITCOIN,"BTC",8),
|
BITCOIN(CryptoNet.BITCOIN,"BTC",8,0,NetworkParameters.fromID(NetworkParameters.ID_TESTNET)),
|
||||||
BITCOIN_TEST(CryptoNet.BITCOIN_TEST,"BTC",8),
|
BITCOIN_TEST(CryptoNet.BITCOIN_TEST,"BTC",8,1,NetworkParameters.fromID(NetworkParameters.ID_TESTNET)),
|
||||||
LITECOIN(CryptoNet.LITECOIN,"LTC",8),
|
LITECOIN(CryptoNet.LITECOIN,"LTC",8,2,null),
|
||||||
DASH(CryptoNet.DASH,"DASH",8),
|
DASH(CryptoNet.DASH,"DASH",8,5,null),
|
||||||
DOGECOIN(CryptoNet.DOGECOIN,"DOGE",8),
|
DOGECOIN(CryptoNet.DOGECOIN,"DOGE",8,3,null),
|
||||||
BITSHARES(CryptoNet.BITSHARES,"BTS",5);
|
BITSHARES(CryptoNet.BITSHARES,"BTS",5,0,null),
|
||||||
|
STEEM(CryptoNet.STEEM,"BTS",5,0,null);
|
||||||
|
|
||||||
protected CryptoNet cryptoNet;
|
protected CryptoNet cryptoNet;
|
||||||
protected String label;
|
protected String label;
|
||||||
protected int precision;
|
protected int precision;
|
||||||
|
protected int coinNumber;
|
||||||
|
protected NetworkParameters parameters;
|
||||||
|
|
||||||
CryptoCoin(CryptoNet cryptoNet, String label, int precision){
|
CryptoCoin(CryptoNet cryptoNet, String label, int precision, int coinNumber, NetworkParameters parameters){
|
||||||
this.cryptoNet = cryptoNet;
|
this.cryptoNet = cryptoNet;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.precision = precision;
|
this.precision = precision;
|
||||||
|
this.coinNumber = coinNumber;
|
||||||
|
this.parameters = parameters;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +45,14 @@ public enum CryptoCoin implements Serializable {
|
||||||
public int getPrecision(){
|
public int getPrecision(){
|
||||||
return this.precision;
|
return this.precision;
|
||||||
}
|
}
|
||||||
|
public NetworkParameters getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCoinNumber() {
|
||||||
|
return coinNumber;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<CryptoCoin> getByCryptoNet(CryptoNet cryptoNet){
|
public static List<CryptoCoin> getByCryptoNet(CryptoNet cryptoNet){
|
||||||
List<CryptoCoin> result = new ArrayList<CryptoCoin>();
|
List<CryptoCoin> result = new ArrayList<CryptoCoin>();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CryptoNet Enumeration, a Crypto Net is define as the net where a CryptoCoin works, iniside the
|
* CryptoNet Enumeration, a Crypto Net is define as the net where a CryptoCoin works, iniside the
|
||||||
* CrypotNet is where the transaction and balance works, using the CryptoCoin Assets
|
* CrypotNet is where the transaction and balance works, using the CryptoCoin Assets
|
||||||
|
@ -11,7 +13,14 @@ import java.util.Map;
|
||||||
* Created by Henry Varona on 12/9/2017.
|
* Created by Henry Varona on 12/9/2017.
|
||||||
*/
|
*/
|
||||||
public enum CryptoNet implements Serializable {
|
public enum CryptoNet implements Serializable {
|
||||||
UNKNOWN("UNKNOWN",6,-1), 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);
|
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);
|
||||||
|
|
||||||
protected String label;
|
protected String label;
|
||||||
|
|
||||||
|
@ -19,6 +28,8 @@ public enum CryptoNet implements Serializable {
|
||||||
|
|
||||||
protected int bip44Index;
|
protected int bip44Index;
|
||||||
|
|
||||||
|
protected int iconImageResource;
|
||||||
|
|
||||||
private static Map<Integer, CryptoNet> bip44Map = new HashMap<Integer, CryptoNet>();
|
private static Map<Integer, CryptoNet> bip44Map = new HashMap<Integer, CryptoNet>();
|
||||||
static {
|
static {
|
||||||
for (CryptoNet cryptoNetEnum : CryptoNet.values()) {
|
for (CryptoNet cryptoNetEnum : CryptoNet.values()) {
|
||||||
|
@ -26,10 +37,11 @@ public enum CryptoNet implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptoNet(String label,int confirmationsNeeded, int bip44Index){
|
CryptoNet(String label,int confirmationsNeeded, int bip44Index, int iconImageResource){
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.confirmationsNeeded = confirmationsNeeded;
|
this.confirmationsNeeded = confirmationsNeeded;
|
||||||
this.bip44Index = bip44Index;
|
this.bip44Index = bip44Index;
|
||||||
|
this.iconImageResource = iconImageResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLabel(){
|
public String getLabel(){
|
||||||
|
@ -44,6 +56,10 @@ public enum CryptoNet implements Serializable {
|
||||||
return this.bip44Index;
|
return this.bip44Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getIconImageResource() {
|
||||||
|
return this.iconImageResource;
|
||||||
|
}
|
||||||
|
|
||||||
public static CryptoNet fromBip44Index(int index){
|
public static CryptoNet fromBip44Index(int index){
|
||||||
if (bip44Map.containsKey(index)) {
|
if (bip44Map.containsKey(index)) {
|
||||||
return bip44Map.get(index);
|
return bip44Map.get(index);
|
||||||
|
|
|
@ -6,5 +6,6 @@ package cy.agorise.crystalwallet.enums;
|
||||||
|
|
||||||
public enum SeedType {
|
public enum SeedType {
|
||||||
BIP39,
|
BIP39,
|
||||||
BRAINKEY
|
BRAINKEY,
|
||||||
|
WIF
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,11 @@ import android.text.SpannableStringBuilder;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
|
@ -41,6 +44,22 @@ public class AccountsSettingsFragment extends Fragment {
|
||||||
@BindView(R.id.tvRemove)
|
@BindView(R.id.tvRemove)
|
||||||
public TextView tvRemove;
|
public TextView tvRemove;
|
||||||
|
|
||||||
|
@BindView(R.id.btnUpgrade)
|
||||||
|
public Button btnUpgrade;
|
||||||
|
|
||||||
|
@BindView(R.id.btnImport)
|
||||||
|
public Button btnImport;
|
||||||
|
|
||||||
|
@BindView(R.id.btnRefresh)
|
||||||
|
public Button btnRefresh;
|
||||||
|
|
||||||
|
@BindView(R.id.btnRemove)
|
||||||
|
public Button btnRemove;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
@ -53,6 +72,36 @@ public class AccountsSettingsFragment extends Fragment {
|
||||||
tvRefresh.setText(makeFirstWordsBold(getResources().getString(R.string.refresh_description)));
|
tvRefresh.setText(makeFirstWordsBold(getResources().getString(R.string.refresh_description)));
|
||||||
tvRemove.setText(makeFirstWordsBold(getResources().getString(R.string.remove_description)));
|
tvRemove.setText(makeFirstWordsBold(getResources().getString(R.string.remove_description)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnUpgrade)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnImport)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnRefresh)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnRemove)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
package cy.agorise.crystalwallet.fragments;
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -16,6 +23,8 @@ import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
@ -39,6 +48,11 @@ import cy.agorise.crystalwallet.requestmanagers.FileServiceRequests;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class BackupsSettingsFragment extends Fragment{
|
public class BackupsSettingsFragment extends Fragment{
|
||||||
|
|
||||||
|
private static final int PERMISSION_REQUEST_CODE = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public BackupsSettingsFragment() {
|
public BackupsSettingsFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
@ -65,6 +79,7 @@ public class BackupsSettingsFragment extends Fragment{
|
||||||
@BindView(R.id.btnBinFile)
|
@BindView(R.id.btnBinFile)
|
||||||
public Button btnBinFile;
|
public Button btnBinFile;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
@ -72,6 +87,25 @@ public class BackupsSettingsFragment extends Fragment{
|
||||||
View v = inflater.inflate(R.layout.fragment_backups_settings, container, false);
|
View v = inflater.inflate(R.layout.fragment_backups_settings, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnBinFile)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
makeBackupFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnBrainkey)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
btnBrainOnClick();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
tvBinFile.setText(makeFirstWordsBold(getResources().getString(R.string.bin_file_description)));
|
tvBinFile.setText(makeFirstWordsBold(getResources().getString(R.string.bin_file_description)));
|
||||||
tvBrainkey.setText(makeFirstWordsBold(getResources().getString(R.string.brainkey_description)));
|
tvBrainkey.setText(makeFirstWordsBold(getResources().getString(R.string.brainkey_description)));
|
||||||
tvWIFKey.setText(makeFirstWordsBold(getResources().getString(R.string.wif_key_description)));
|
tvWIFKey.setText(makeFirstWordsBold(getResources().getString(R.string.wif_key_description)));
|
||||||
|
@ -92,12 +126,40 @@ public class BackupsSettingsFragment extends Fragment{
|
||||||
public void btnBrainOnClick(){
|
public void btnBrainOnClick(){
|
||||||
|
|
||||||
Intent intent = new Intent(getContext(), BackupSeedActivity.class);
|
Intent intent = new Intent(getContext(), BackupSeedActivity.class);
|
||||||
|
intent. putExtra("SEED_ID","");
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@OnClick(R.id.btnBinFile)
|
@OnClick(R.id.btnBinFile)
|
||||||
public void makeBackupFile(){
|
public void makeBackupFile(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for WRITE_EXTERNAL_STORAGE permission
|
||||||
|
* */
|
||||||
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
|
if (checkPermission()) {
|
||||||
|
// Code for above or equal 23 API Oriented Device
|
||||||
|
// Your Permission granted already .Do next code
|
||||||
|
|
||||||
|
makeBackupfileAfterPermission();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
requestPermission(); // Code for permission
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Code for Below 23 API Oriented Device
|
||||||
|
// Do next code
|
||||||
|
|
||||||
|
makeBackupfileAfterPermission();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void makeBackupfileAfterPermission(){
|
||||||
|
|
||||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
|
|
||||||
LiveData<GeneralSetting> generalSettingLD = CrystalDatabase.getAppDatabase(getContext()).generalSettingDao().getByName(GeneralSetting.SETTING_PASSWORD);
|
LiveData<GeneralSetting> generalSettingLD = CrystalDatabase.getAppDatabase(getContext()).generalSettingDao().getByName(GeneralSetting.SETTING_PASSWORD);
|
||||||
|
@ -105,13 +167,13 @@ public class BackupsSettingsFragment extends Fragment{
|
||||||
generalSettingLD.observe(this, new Observer<GeneralSetting>() {
|
generalSettingLD.observe(this, new Observer<GeneralSetting>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(@Nullable GeneralSetting generalSetting) {
|
public void onChanged(@Nullable GeneralSetting generalSetting) {
|
||||||
|
|
||||||
String password = "";
|
String password = "";
|
||||||
if (generalSetting != null) {
|
if (generalSetting != null) {
|
||||||
password = generalSetting.getValue();
|
password = generalSetting.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
final CreateBackupRequest backupFileRequest = new CreateBackupRequest(getContext(), password);
|
final CreateBackupRequest backupFileRequest = new CreateBackupRequest(getContext(), password);
|
||||||
|
|
||||||
backupFileRequest.setListener(new FileServiceRequestListener() {
|
backupFileRequest.setListener(new FileServiceRequestListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCarryOut() {
|
public void onCarryOut() {
|
||||||
|
@ -132,4 +194,40 @@ 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,15 @@ package cy.agorise.crystalwallet.fragments;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.Context;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -17,15 +19,20 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.models.CryptoNetBalance;
|
import cy.agorise.crystalwallet.models.CryptoNetBalance;
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoCoinBalanceListViewModel;
|
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
|
||||||
import cy.agorise.crystalwallet.views.CryptoNetBalanceListView;
|
import cy.agorise.crystalwallet.views.CryptoNetBalanceListAdapter;
|
||||||
|
|
||||||
public class BalanceFragment extends Fragment {
|
public class BalanceFragment extends Fragment {
|
||||||
|
|
||||||
CryptoNetBalanceListViewModel cryptoNetBalanceListViewModel;
|
CryptoNetBalanceListViewModel cryptoNetBalanceListViewModel;
|
||||||
|
|
||||||
@BindView(R.id.vCryptoNetBalanceListView)
|
@BindView(R.id.tvNoBalances)
|
||||||
CryptoNetBalanceListView vCryptoNetBalanceListView;
|
TextView tvNoBalances;
|
||||||
|
|
||||||
|
@BindView(R.id.rvBalances)
|
||||||
|
RecyclerView rvBalances;
|
||||||
|
|
||||||
|
CryptoNetBalanceListAdapter balancesAdapter;
|
||||||
|
|
||||||
public BalanceFragment() {
|
public BalanceFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
|
@ -44,22 +51,33 @@ public class BalanceFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
View view = inflater.inflate(R.layout.fragment_balance, container, false);
|
View view = inflater.inflate(R.layout.fragment_balance, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
cryptoNetBalanceListViewModel = ViewModelProviders.of(this).get(CryptoNetBalanceListViewModel.class);
|
// Configure RecyclerView and its adapter
|
||||||
LiveData<List<CryptoNetBalance>> cryptoNetBalanceData = cryptoNetBalanceListViewModel.getCryptoNetBalanceList();
|
rvBalances.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
vCryptoNetBalanceListView.setData(null, this);
|
balancesAdapter = new CryptoNetBalanceListAdapter(this);
|
||||||
|
rvBalances.setAdapter(balancesAdapter);
|
||||||
|
|
||||||
final Fragment fragment = this;
|
//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();
|
||||||
|
|
||||||
cryptoNetBalanceData.observe(this, new Observer<List<CryptoNetBalance>>() {
|
cryptoNetBalanceData.observe(this, new Observer<List<CryptoNetBalance>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(List<CryptoNetBalance> cryptoNetBalances) {
|
public void onChanged(List<CryptoNetBalance> cryptoNetBalances) {
|
||||||
vCryptoNetBalanceListView.setData(cryptoNetBalances, fragment);
|
balancesAdapter.submitList(cryptoNetBalances);
|
||||||
|
|
||||||
|
if(cryptoNetBalances != null && cryptoNetBalances.size() > 0) {
|
||||||
|
tvNoBalances.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
tvNoBalances.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
import com.vincent.filepicker.Constant;
|
import com.vincent.filepicker.Constant;
|
||||||
import com.vincent.filepicker.activity.AudioPickActivity;
|
import com.vincent.filepicker.activity.AudioPickActivity;
|
||||||
import com.vincent.filepicker.filter.entity.AudioFile;
|
import com.vincent.filepicker.filter.entity.AudioFile;
|
||||||
|
@ -73,6 +74,9 @@ public class BitsharesSettingsFragment extends Fragment {
|
||||||
GrapheneAccountInfo grapheneAccountInfo;
|
GrapheneAccountInfo grapheneAccountInfo;
|
||||||
GrapheneAccount grapheneAccount;
|
GrapheneAccount grapheneAccount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public BitsharesSettingsFragment() {
|
public BitsharesSettingsFragment() {
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
long cryptoNetAcountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID", -1);
|
long cryptoNetAcountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID", -1);
|
||||||
|
@ -114,6 +118,17 @@ public class BitsharesSettingsFragment extends Fragment {
|
||||||
View v = inflater.inflate(R.layout.fragment_bitshares_settings, container, false);
|
View v = inflater.inflate(R.layout.fragment_bitshares_settings, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnUpgradeToLtm)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
upgradeAccountToLtm();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
initAlreadyLtm();
|
initAlreadyLtm();
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
|
|
@ -14,6 +14,7 @@ import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
@ -27,6 +28,9 @@ public class ContactsFragment extends Fragment {
|
||||||
@BindView(R.id.rvContacts)
|
@BindView(R.id.rvContacts)
|
||||||
RecyclerView rvContacts;
|
RecyclerView rvContacts;
|
||||||
|
|
||||||
|
@BindView(R.id.tvNoContacts)
|
||||||
|
TextView tvNoContacts;
|
||||||
|
|
||||||
ContactListAdapter adapter;
|
ContactListAdapter adapter;
|
||||||
|
|
||||||
FloatingActionButton fabAddContact;
|
FloatingActionButton fabAddContact;
|
||||||
|
@ -86,6 +90,13 @@ public class ContactsFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(@Nullable PagedList<Contact> contacts) {
|
public void onChanged(@Nullable PagedList<Contact> contacts) {
|
||||||
adapter.submitList(contacts);
|
adapter.submitList(contacts);
|
||||||
|
|
||||||
|
if(contacts != null && contacts.size() > 0){
|
||||||
|
tvNoContacts.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
tvNoContacts.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by xd on 12/28/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CryptoNetAccountActivationSettingsFragment extends Fragment {
|
||||||
|
|
||||||
|
@BindView(R.id.tvMnemonic)
|
||||||
|
TextView tvMnemonic;
|
||||||
|
|
||||||
|
@BindView(R.id.btnCopy)
|
||||||
|
Button btnCopy;
|
||||||
|
|
||||||
|
CryptoNetAccount cryptoNetAccount;
|
||||||
|
AccountSeed accountSeed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public CryptoNetAccountActivationSettingsFragment() {
|
||||||
|
|
||||||
|
if (getArguments() != null) {
|
||||||
|
long cryptoNetAcountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID", -1);
|
||||||
|
|
||||||
|
if (cryptoNetAcountId > -1) {
|
||||||
|
this.cryptoNetAccount = CrystalDatabase.getAppDatabase(getContext()).cryptoNetAccountDao().getById(cryptoNetAcountId);
|
||||||
|
this.accountSeed = CrystalDatabase.getAppDatabase(getContext()).accountSeedDao().findById(this.cryptoNetAccount.getSeedId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CryptoNetAccountActivationSettingsFragment newInstance(long cryptoNetAccountId) {
|
||||||
|
CryptoNetAccountActivationSettingsFragment fragment = new CryptoNetAccountActivationSettingsFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong("CRYPTO_NET_ACCOUNT_ID", cryptoNetAccountId);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
|
||||||
|
|
||||||
|
if (cryptoNetAccountId > -1){
|
||||||
|
fragment.cryptoNetAccount = CrystalDatabase.getAppDatabase(fragment.getContext()).cryptoNetAccountDao().getById(cryptoNetAccountId);
|
||||||
|
fragment.accountSeed = CrystalDatabase.getAppDatabase(fragment.getContext()).accountSeedDao().findById(fragment.cryptoNetAccount.getSeedId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false);
|
||||||
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCopy)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
btnCopyClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
initAlreadyLtm();
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initAlreadyLtm(){
|
||||||
|
if (this.cryptoNetAccount != null) {
|
||||||
|
tvMnemonic.setText(this.accountSeed.getMasterSeed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clic on button copy to clipboard
|
||||||
|
* */
|
||||||
|
@OnClick(R.id.btnCopy)
|
||||||
|
public void btnCopyClick(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save to clipboard the brainkey chain
|
||||||
|
* */
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText(tvMnemonic.getText(), tvMnemonic.getText().toString());
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Success message
|
||||||
|
* */
|
||||||
|
Toast.makeText(activity,getResources().getString(R.string.window_seed_toast_clipboard), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoNetSelection;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CreateBitcoinAccountRequest;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
|
import cy.agorise.crystalwallet.views.CryptoNetSelectionListAdapter;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by xd on 12/28/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GeneralAccountSeedCoinSettingsFragment extends Fragment implements CryptoNetSelectionListAdapter.CryptoNetSelectionListener {
|
||||||
|
|
||||||
|
@BindView(R.id.rvCoinSelection)
|
||||||
|
RecyclerView rvCoinSelection;
|
||||||
|
|
||||||
|
AccountSeed accountSeed;
|
||||||
|
|
||||||
|
ArrayList<CryptoNetSelection> cryptoNetSelectionList;
|
||||||
|
|
||||||
|
public GeneralAccountSeedCoinSettingsFragment() {
|
||||||
|
|
||||||
|
if (getArguments() != null) {
|
||||||
|
long accountSeedId = getArguments().getLong("SEED_ID", -1);
|
||||||
|
|
||||||
|
if (accountSeedId > -1) {
|
||||||
|
this.accountSeed = CrystalDatabase.getAppDatabase(getContext()).accountSeedDao().findById(accountSeedId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cryptoNetSelectionList = new ArrayList<CryptoNetSelection>();
|
||||||
|
CryptoNetSelection nextCryptoNetSelection;
|
||||||
|
for (CryptoNet nextCryptoNet : CryptoNet.values()){
|
||||||
|
|
||||||
|
if ((nextCryptoNet != CryptoNet.UNKNOWN) && (nextCryptoNet != CryptoNet.BITCOIN_TEST)) {
|
||||||
|
nextCryptoNetSelection = new CryptoNetSelection(nextCryptoNet, false);
|
||||||
|
cryptoNetSelectionList.add(nextCryptoNetSelection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GeneralAccountSeedCoinSettingsFragment newInstance(long accountSeedId) {
|
||||||
|
GeneralAccountSeedCoinSettingsFragment fragment = new GeneralAccountSeedCoinSettingsFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong("SEED_ID", accountSeedId);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
|
||||||
|
|
||||||
|
if (accountSeedId > -1){
|
||||||
|
fragment.accountSeed = CrystalDatabase.getAppDatabase(fragment.getContext()).accountSeedDao().findById(accountSeedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
View v = inflater.inflate(R.layout.fragment_general_account_seed_coin_settings, container, false);
|
||||||
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
CryptoNetSelectionListAdapter cryptoNetSelectionListAdapter = new CryptoNetSelectionListAdapter(this.cryptoNetSelectionList);
|
||||||
|
cryptoNetSelectionListAdapter.addListener(this);
|
||||||
|
rvCoinSelection.setAdapter(cryptoNetSelectionListAdapter);
|
||||||
|
LinearLayoutManager llm = new LinearLayoutManager(this.getContext());
|
||||||
|
llm.setOrientation(LinearLayoutManager.VERTICAL);
|
||||||
|
rvCoinSelection.setLayoutManager(llm);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCryptoNetSelectionChecked(CryptoNetSelection source) {
|
||||||
|
//Toast.makeText(this.getContext(),"the coin "+source.getCryptoNet().name()+" was "+(source.getSelected()?"selected":"unselected"),Toast.LENGTH_LONG).show();
|
||||||
|
List<CryptoCoin> cryptoCoins = CryptoCoin.getByCryptoNet(source.getCryptoNet());
|
||||||
|
|
||||||
|
|
||||||
|
final CreateBitcoinAccountRequest request = new CreateBitcoinAccountRequest(this.accountSeed,this.getContext(),cryptoCoins.get(0));
|
||||||
|
|
||||||
|
request.setListener(new CryptoNetInfoRequestListener() {
|
||||||
|
@Override
|
||||||
|
public void onCarryOut() {
|
||||||
|
if (request.getStatus() == CreateBitcoinAccountRequest.StatusCode.SUCCEEDED){
|
||||||
|
Toast.makeText(getContext(),"The account was successfully created",Toast.LENGTH_LONG);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getContext(),"There was an error enabling the account",Toast.LENGTH_LONG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CryptoNetInfoRequests.getInstance().addRequest(request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by xd on 12/28/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GeneralAccountSeedFragment extends Fragment {
|
||||||
|
|
||||||
|
@BindView(R.id.tvMnemonic)
|
||||||
|
TextView tvMnemonic;
|
||||||
|
|
||||||
|
@BindView(R.id.btnCopy)
|
||||||
|
Button btnCopy;
|
||||||
|
|
||||||
|
AccountSeed accountSeed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public GeneralAccountSeedFragment() {
|
||||||
|
|
||||||
|
if (getArguments() != null) {
|
||||||
|
long accountSeedId = getArguments().getLong("SEED_ID", -1);
|
||||||
|
|
||||||
|
if (accountSeedId > -1) {
|
||||||
|
this.accountSeed = CrystalDatabase.getAppDatabase(getContext()).accountSeedDao().findById(accountSeedId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GeneralAccountSeedFragment newInstance(long accountSeedId) {
|
||||||
|
GeneralAccountSeedFragment fragment = new GeneralAccountSeedFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong("SEED_ID", accountSeedId);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
|
||||||
|
|
||||||
|
if (accountSeedId > -1){
|
||||||
|
fragment.accountSeed = CrystalDatabase.getAppDatabase(fragment.getContext()).accountSeedDao().findById(accountSeedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false);
|
||||||
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCopy)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
btnCopyClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
initAlreadyLtm();
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initAlreadyLtm(){
|
||||||
|
tvMnemonic.setText(this.accountSeed.getMasterSeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clic on button copy to clipboard
|
||||||
|
* */
|
||||||
|
@OnClick(R.id.btnCopy)
|
||||||
|
public void btnCopyClick(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save to clipboard the brainkey chain
|
||||||
|
* */
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText(tvMnemonic.getText(), tvMnemonic.getText().toString());
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Success message
|
||||||
|
* */
|
||||||
|
Toast.makeText(activity,getResources().getString(R.string.window_seed_toast_clipboard), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
package cy.agorise.crystalwallet.fragments;
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -8,11 +12,15 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
import cy.agorise.crystalwallet.models.AccountSeed;
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
@ -30,9 +38,15 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
|
||||||
@BindView(R.id.tvMnemonic)
|
@BindView(R.id.tvMnemonic)
|
||||||
TextView tvMnemonic;
|
TextView tvMnemonic;
|
||||||
|
|
||||||
|
@BindView(R.id.btnCopy)
|
||||||
|
Button btnCopy;
|
||||||
|
|
||||||
CryptoNetAccount cryptoNetAccount;
|
CryptoNetAccount cryptoNetAccount;
|
||||||
AccountSeed accountSeed;
|
AccountSeed accountSeed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public GeneralCryptoNetAccountSettingsFragment() {
|
public GeneralCryptoNetAccountSettingsFragment() {
|
||||||
|
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
|
@ -73,6 +87,18 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
|
||||||
View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false);
|
View v = inflater.inflate(R.layout.fragment_general_crypto_net_account_settings, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnCopy)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
btnCopyClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
initAlreadyLtm();
|
initAlreadyLtm();
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -83,4 +109,24 @@ public class GeneralCryptoNetAccountSettingsFragment extends Fragment {
|
||||||
tvMnemonic.setText(this.accountSeed.getMasterSeed());
|
tvMnemonic.setText(this.accountSeed.getMasterSeed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clic on button copy to clipboard
|
||||||
|
* */
|
||||||
|
@OnClick(R.id.btnCopy)
|
||||||
|
public void btnCopyClick(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save to clipboard the brainkey chain
|
||||||
|
* */
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText(tvMnemonic.getText(), tvMnemonic.getText().toString());
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Success message
|
||||||
|
* */
|
||||||
|
Toast.makeText(activity,getResources().getString(R.string.window_seed_toast_clipboard), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,12 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
import com.vincent.filepicker.Constant;
|
import com.vincent.filepicker.Constant;
|
||||||
import com.vincent.filepicker.activity.AudioPickActivity;
|
import com.vincent.filepicker.activity.AudioPickActivity;
|
||||||
import com.vincent.filepicker.filter.entity.AudioFile;
|
import com.vincent.filepicker.filter.entity.AudioFile;
|
||||||
|
@ -71,6 +73,8 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
Spinner spDisplayDateTime;
|
Spinner spDisplayDateTime;
|
||||||
@BindView (R.id.tvReceiveFundsSoundValue)
|
@BindView (R.id.tvReceiveFundsSoundValue)
|
||||||
TextView tvReceiveFundsSound;
|
TextView tvReceiveFundsSound;
|
||||||
|
@BindView (R.id.btnContact)
|
||||||
|
Button btnContact;
|
||||||
|
|
||||||
public GeneralSettingsFragment() {
|
public GeneralSettingsFragment() {
|
||||||
this.spPreferredLanguageInitialized = false;
|
this.spPreferredLanguageInitialized = false;
|
||||||
|
@ -99,6 +103,17 @@ public class GeneralSettingsFragment extends Fragment {
|
||||||
View v = inflater.inflate(R.layout.fragment_general_settings, container, false);
|
View v = inflater.inflate(R.layout.fragment_general_settings, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnContact)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
||||||
generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList();
|
generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList();
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,20 @@ import android.app.Dialog;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
@ -19,11 +26,15 @@ import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.thekhaeng.pushdownanim.PushDownAnim;
|
||||||
|
import com.vincent.filepicker.ToastUtil;
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
import butterknife.OnTouch;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.activities.BoardActivity;
|
import cy.agorise.crystalwallet.activities.BoardActivity;
|
||||||
import cy.agorise.crystalwallet.activities.ImportSeedActivity;
|
import cy.agorise.crystalwallet.activities.ImportSeedActivity;
|
||||||
|
@ -49,7 +60,10 @@ public class ImportAccountOptionsFragment extends DialogFragment {
|
||||||
Button btnClose;
|
Button btnClose;
|
||||||
@BindView(R.id.btnImportBackup)
|
@BindView(R.id.btnImportBackup)
|
||||||
Button btnImportBackup;
|
Button btnImportBackup;
|
||||||
|
@BindView(R.id.btnImportSeed)
|
||||||
|
Button btnImportSeed;
|
||||||
|
|
||||||
|
private static final int PERMISSION_REQUEST_CODE = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Dialog for loading
|
Dialog for loading
|
||||||
|
@ -90,6 +104,34 @@ public class ImportAccountOptionsFragment extends DialogFragment {
|
||||||
View view = inflater.inflate(R.layout.fragment_import_account_options, null);
|
View view = inflater.inflate(R.layout.fragment_import_account_options, null);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Integration of library with button efects
|
||||||
|
* */
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnClose)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnImportBackup)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
importBackup();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
PushDownAnim.setPushDownAnimTo(btnImportSeed)
|
||||||
|
.setOnClickListener( new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick( View view ){
|
||||||
|
importSeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
return builder.setView(view).create();
|
return builder.setView(view).create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,18 +152,88 @@ public class ImportAccountOptionsFragment extends DialogFragment {
|
||||||
|
|
||||||
@OnClick (R.id.btnImportBackup)
|
@OnClick (R.id.btnImportBackup)
|
||||||
public void importBackup(){
|
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)
|
@OnClick (R.id.btnImportSeed)
|
||||||
public void importSeed(){
|
public void importSeed(){
|
||||||
Intent intent = new Intent(this.getActivity(), ImportSeedActivity.class);
|
|
||||||
startActivity(intent);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,18 +3,30 @@ package cy.agorise.crystalwallet.fragments;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.activities.BoardActivity;
|
||||||
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
|
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
|
||||||
|
@ -25,6 +37,12 @@ import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
|
||||||
|
|
||||||
public class NoneSecurityFragment extends Fragment {
|
public class NoneSecurityFragment extends Fragment {
|
||||||
|
|
||||||
|
@BindView(R.id.btnOK)
|
||||||
|
Button btnOK;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public NoneSecurityFragment() {
|
public NoneSecurityFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
@ -43,14 +61,41 @@ public class NoneSecurityFragment extends Fragment {
|
||||||
View v = inflater.inflate(R.layout.fragment_none_security, container, false);
|
View v = inflater.inflate(R.layout.fragment_none_security, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
||||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||||
super.setUserVisibleHint(isVisibleToUser);
|
super.setUserVisibleHint(isVisibleToUser);
|
||||||
if (isVisibleToUser) {
|
if (isVisibleToUser) {
|
||||||
CrystalSecurityMonitor.getInstance(null).clearSecurity();
|
CrystalSecurityMonitor.getInstance(null).clearSecurity();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package cy.agorise.crystalwallet.fragments;
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.Observer;
|
import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -18,13 +21,19 @@ import com.andrognito.patternlockview.PatternLockView;
|
||||||
import com.andrognito.patternlockview.listener.PatternLockViewListener;
|
import com.andrognito.patternlockview.listener.PatternLockViewListener;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.CrystalDialog;
|
||||||
|
import cy.agorise.crystalwallet.interfaces.OnResponse;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
|
import cy.agorise.crystalwallet.util.ChildViewPager;
|
||||||
import cy.agorise.crystalwallet.util.PasswordManager;
|
import cy.agorise.crystalwallet.util.PasswordManager;
|
||||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
|
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
|
||||||
|
@ -42,9 +51,17 @@ public class PatternSecurityFragment extends Fragment {
|
||||||
@BindView(R.id.tvPatternText)
|
@BindView(R.id.tvPatternText)
|
||||||
TextView tvPatternText;
|
TextView tvPatternText;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contains the ChildViewPager to block the viewpager when the user is using the pattern control
|
||||||
|
* */
|
||||||
|
private ChildViewPager childViewPager;
|
||||||
|
|
||||||
private PatternLockViewListener actualPatternListener;
|
private PatternLockViewListener actualPatternListener;
|
||||||
private String patternEntered;
|
private String patternEntered;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public PatternSecurityFragment() {
|
public PatternSecurityFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
@ -77,6 +94,11 @@ public class PatternSecurityFragment extends Fragment {
|
||||||
return patternString;
|
return patternString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setChildViewPager(ChildViewPager childViewPager) {
|
||||||
|
this.childViewPager = childViewPager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void removePatternListener(){
|
public void removePatternListener(){
|
||||||
if (actualPatternListener != null){
|
if (actualPatternListener != null){
|
||||||
patternLockView.removePatternLockListener(actualPatternListener);
|
patternLockView.removePatternLockListener(actualPatternListener);
|
||||||
|
@ -87,12 +109,12 @@ public class PatternSecurityFragment extends Fragment {
|
||||||
public void showNewPatternUI(){
|
public void showNewPatternUI(){
|
||||||
removePatternListener();
|
removePatternListener();
|
||||||
patternLockView.clearPattern();
|
patternLockView.clearPattern();
|
||||||
tvPatternText.setText("Enter new pattern");
|
tvPatternText.setTextColor(Color.WHITE);
|
||||||
|
tvPatternText.setText(getActivity().getResources().getString(R.string.Enter_new_pattern));
|
||||||
|
|
||||||
actualPatternListener = new PatternLockViewListener() {
|
actualPatternListener = new PatternLockViewListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onStarted() {
|
public void onStarted() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,7 +140,7 @@ public class PatternSecurityFragment extends Fragment {
|
||||||
removePatternListener();
|
removePatternListener();
|
||||||
patternLockView.clearPattern();
|
patternLockView.clearPattern();
|
||||||
patternLockView.requestFocus();
|
patternLockView.requestFocus();
|
||||||
tvPatternText.setText("Confirm new pattern");
|
tvPatternText.setText(getActivity().getResources().getString(R.string.Confirm_new_pattern));
|
||||||
|
|
||||||
actualPatternListener = new PatternLockViewListener() {
|
actualPatternListener = new PatternLockViewListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -135,7 +157,9 @@ public class PatternSecurityFragment extends Fragment {
|
||||||
public void onComplete(List<PatternLockView.Dot> pattern) {
|
public void onComplete(List<PatternLockView.Dot> pattern) {
|
||||||
if (patternEntered.equals(patternToString(pattern))){
|
if (patternEntered.equals(patternToString(pattern))){
|
||||||
savePattern(patternEntered);
|
savePattern(patternEntered);
|
||||||
showNewPatternUI();
|
}
|
||||||
|
else{
|
||||||
|
resetPattern();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,9 +171,79 @@ public class PatternSecurityFragment extends Fragment {
|
||||||
patternLockView.addPatternLockListener(actualPatternListener);
|
patternLockView.addPatternLockListener(actualPatternListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetPattern(){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show error
|
||||||
|
* */
|
||||||
|
tvPatternText.setText(getActivity().getResources().getString(R.string.Incorrect_pattern));
|
||||||
|
tvPatternText.setTextColor(Color.RED);
|
||||||
|
final Timer t = new Timer();
|
||||||
|
t.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
t.cancel();
|
||||||
|
showNewPatternUI();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
//Set how long before to start calling the TimerTask (in milliseconds)
|
||||||
|
1000,
|
||||||
|
//Set the amount of time between each execution (in milliseconds)
|
||||||
|
1000);
|
||||||
|
}
|
||||||
|
|
||||||
public void savePattern(String pattern){
|
public void savePattern(String pattern){
|
||||||
String patternEncripted = PasswordManager.encriptPassword(pattern);
|
String patternEncripted = PasswordManager.encriptPassword(pattern);
|
||||||
CrystalSecurityMonitor.getInstance(null).setPatternEncrypted(patternEncripted);
|
CrystalSecurityMonitor.getInstance(null).setPatternEncrypted(patternEncripted);
|
||||||
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
|
/*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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,35 @@
|
||||||
package cy.agorise.crystalwallet.fragments;
|
package cy.agorise.crystalwallet.fragments;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import butterknife.OnFocusChange;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
|
||||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||||
import cy.agorise.crystalwallet.util.PasswordManager;
|
import cy.agorise.crystalwallet.util.PasswordManager;
|
||||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||||
|
@ -42,6 +53,19 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
|
||||||
@BindView(R.id.tvConfirmPinError)
|
@BindView(R.id.tvConfirmPinError)
|
||||||
TextView tvConfirmPinError;
|
TextView tvConfirmPinError;
|
||||||
|
|
||||||
|
@BindView(R.id.btnOK)
|
||||||
|
Button btnOK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates the new typing for the patterns
|
||||||
|
* */
|
||||||
|
private boolean first = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag to check if validation of fields is correct
|
||||||
|
* */
|
||||||
|
private boolean valid = false;
|
||||||
|
|
||||||
GeneralSettingListViewModel generalSettingListViewModel;
|
GeneralSettingListViewModel generalSettingListViewModel;
|
||||||
GeneralSetting passwordGeneralSetting;
|
GeneralSetting passwordGeneralSetting;
|
||||||
PinSecurityValidator pinSecurityValidator;
|
PinSecurityValidator pinSecurityValidator;
|
||||||
|
@ -64,15 +88,117 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
|
||||||
View v = inflater.inflate(R.layout.fragment_pin_security, container, false);
|
View v = inflater.inflate(R.layout.fragment_pin_security, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initially not enabled til it passes validations
|
||||||
|
* */
|
||||||
|
btnOK.setEnabled(false);
|
||||||
|
|
||||||
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
||||||
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
||||||
|
|
||||||
pinSecurityValidator = new PinSecurityValidator(this.getContext(), etNewPin, etConfirmPin);
|
pinSecurityValidator = new PinSecurityValidator(this.getContext(), etNewPin, etConfirmPin);
|
||||||
pinSecurityValidator.setListener(this);
|
pinSecurityValidator.setListener(this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If PIN is configured set some text
|
||||||
|
* */
|
||||||
|
final CrystalSecurityMonitor crystalSecurityMonitor = CrystalSecurityMonitor.getInstance(getActivity());
|
||||||
|
switch(CrystalSecurityMonitor.getInstance(getActivity()).actualSecurity()) {
|
||||||
|
case GeneralSetting.SETTING_PASSWORD:
|
||||||
|
|
||||||
|
if(etNewPin!=null && etConfirmPin!=null){
|
||||||
|
etNewPin.setText("123456");
|
||||||
|
etConfirmPin.setText("123456");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GeneralSetting.SETTING_PATTERN:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
if(etNewPin!=null && etConfirmPin!=null) {
|
||||||
|
etNewPin.setText("");
|
||||||
|
etConfirmPin.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Focus in no where
|
||||||
|
* */
|
||||||
|
tvNewPinError.requestFocus();
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||||
|
super.setUserVisibleHint(isVisibleToUser);
|
||||||
|
|
||||||
|
first = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If PIN is configured set some text
|
||||||
|
* */
|
||||||
|
final CrystalSecurityMonitor crystalSecurityMonitor = CrystalSecurityMonitor.getInstance(getActivity());
|
||||||
|
switch(CrystalSecurityMonitor.getInstance(getActivity()).actualSecurity()) {
|
||||||
|
case GeneralSetting.SETTING_PASSWORD:
|
||||||
|
|
||||||
|
if(etNewPin!=null && etConfirmPin!=null){
|
||||||
|
etNewPin.setText("123456");
|
||||||
|
etConfirmPin.setText("123456");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GeneralSetting.SETTING_PATTERN:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
if(etNewPin!=null && etConfirmPin!=null) {
|
||||||
|
etNewPin.setText("");
|
||||||
|
etConfirmPin.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Focus in no where
|
||||||
|
* */
|
||||||
|
if(getActivity()!=null){
|
||||||
|
tvNewPinError.requestFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.btnOK)
|
||||||
|
void okClic(final View view) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only can continue if the fields are correctly validated
|
||||||
|
* */
|
||||||
|
if(valid){
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Question if continue or not
|
||||||
|
* */
|
||||||
|
final QuestionDialog questionDialog = new QuestionDialog(getActivity());
|
||||||
|
questionDialog.setText(getActivity().getString(R.string.question_continue));
|
||||||
|
questionDialog.setOnNegative(new NegativeResponse() {
|
||||||
|
@Override
|
||||||
|
public void onNegative(@NotNull DialogMaterial dialogMaterial) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
questionDialog.setOnPositive(new PositiveResponse() {
|
||||||
|
@Override
|
||||||
|
public void onPositive() {
|
||||||
|
savePassword();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
questionDialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etNewPin,
|
@OnTextChanged(value = R.id.etNewPin,
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||||
void afterNewPinChanged(Editable editable) {
|
void afterNewPinChanged(Editable editable) {
|
||||||
|
@ -94,6 +220,16 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnFocusChange({R.id.etNewPin,R.id.etConfirmPin})
|
||||||
|
public void focusChangePIN(View view, boolean hasFocus){
|
||||||
|
if(hasFocus){
|
||||||
|
if(first){
|
||||||
|
first = false;
|
||||||
|
clearFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValidationSucceeded(final ValidationField field) {
|
public void onValidationSucceeded(final ValidationField field) {
|
||||||
final PinSecurityFragment fragment = this;
|
final PinSecurityFragment fragment = this;
|
||||||
|
@ -108,29 +244,64 @@ public class PinSecurityFragment extends Fragment implements UIValidatorListener
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pinSecurityValidator.isValid()){
|
if (pinSecurityValidator.isValid()){
|
||||||
CharSequence text = "Your password has been sucessfully changed!";
|
//savePassword();
|
||||||
int duration = Toast.LENGTH_SHORT;
|
|
||||||
|
|
||||||
Toast toast = Toast.makeText(getContext(), text, duration);
|
if(!first){
|
||||||
toast.show();
|
|
||||||
|
|
||||||
savePassword(etNewPin.getText().toString());
|
//Now is valid
|
||||||
|
valid = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable ok button to continue
|
||||||
|
* */
|
||||||
|
btnOK.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
clearFields();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void savePassword(){
|
||||||
|
|
||||||
|
savePassword(etNewPin.getText().toString());
|
||||||
|
|
||||||
|
CharSequence text = "Your password has been sucessfully changed!";
|
||||||
|
int duration = Toast.LENGTH_SHORT;
|
||||||
|
Toast toast = Toast.makeText(getContext(), text, duration);
|
||||||
|
toast.show();
|
||||||
|
|
||||||
|
etNewPin.setText("123456");
|
||||||
|
etConfirmPin.setText("123456");
|
||||||
|
|
||||||
|
first = true;
|
||||||
|
|
||||||
|
btnOK.setEnabled(false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Focus in no where
|
||||||
|
* */
|
||||||
|
tvNewPinError.requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
public void savePassword(String password) {
|
public void savePassword(String password) {
|
||||||
String passwordEncripted = PasswordManager.encriptPassword(password);
|
String passwordEncripted = PasswordManager.encriptPassword(password);
|
||||||
CrystalSecurityMonitor.getInstance(null).setPasswordSecurity(passwordEncripted);
|
CrystalSecurityMonitor.getInstance(getActivity()).setPasswordSecurity(passwordEncripted);
|
||||||
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
|
|
||||||
|
//CrystalSecurityMonitor.getInstance(getActivity()).callPasswordRequest(this.getActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValidationFailed(final ValidationField field) {
|
public void onValidationFailed(final ValidationField field) {
|
||||||
|
|
||||||
|
//Still false
|
||||||
|
valid = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable til it passes validations
|
||||||
|
* */
|
||||||
|
btnOK.setEnabled(false);
|
||||||
|
|
||||||
this.getActivity().runOnUiThread(new Runnable() {
|
this.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.content.ContextWrapper;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
@ -22,18 +23,28 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.MultiFormatWriter;
|
import com.google.zxing.MultiFormatWriter;
|
||||||
import com.google.zxing.WriterException;
|
import com.google.zxing.WriterException;
|
||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
import com.journeyapps.barcodescanner.BarcodeEncoder;
|
||||||
|
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CalculateBitcoinUriRequest;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.NextBitcoinAccountAddressRequest;
|
||||||
import cy.agorise.crystalwallet.util.CircularImageView;
|
import cy.agorise.crystalwallet.util.CircularImageView;
|
||||||
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountListViewModel;
|
||||||
import cy.agorise.crystalwallet.views.CryptoNetAccountAdapter;
|
import cy.agorise.crystalwallet.views.CryptoNetAccountAdapter;
|
||||||
|
@ -75,6 +86,8 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
|
||||||
TextView tvAssetError;
|
TextView tvAssetError;
|
||||||
@BindView(R.id.ivQrCode)
|
@BindView(R.id.ivQrCode)
|
||||||
ImageView ivQrCode;
|
ImageView ivQrCode;
|
||||||
|
@BindView(R.id.pbQrCode)
|
||||||
|
ProgressBar pbQrCode;
|
||||||
@BindView(R.id.tvCancel)
|
@BindView(R.id.tvCancel)
|
||||||
TextView tvCancel;
|
TextView tvCancel;
|
||||||
|
|
||||||
|
@ -95,6 +108,10 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
|
||||||
|
|
||||||
private FloatingActionButton fabReceive;
|
private FloatingActionButton fabReceive;
|
||||||
|
|
||||||
|
private AsyncTask qrCodeTask;
|
||||||
|
|
||||||
|
private Double lastAmount = -1.0;
|
||||||
|
|
||||||
public static ReceiveTransactionFragment newInstance(long cryptoNetAccountId) {
|
public static ReceiveTransactionFragment newInstance(long cryptoNetAccountId) {
|
||||||
ReceiveTransactionFragment f = new ReceiveTransactionFragment();
|
ReceiveTransactionFragment f = new ReceiveTransactionFragment();
|
||||||
|
|
||||||
|
@ -132,36 +149,13 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
|
||||||
db = CrystalDatabase.getAppDatabase(this.getContext());
|
db = CrystalDatabase.getAppDatabase(this.getContext());
|
||||||
this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId);
|
this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId);
|
||||||
|
|
||||||
/*
|
|
||||||
* this is only for graphene accounts.
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
|
|
||||||
this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
|
|
||||||
|
|
||||||
final LiveData<List<CryptoCoinBalance>> balancesList = db.cryptoCoinBalanceDao().getBalancesFromAccount(cryptoNetAccountId);
|
|
||||||
balancesList.observe(this, new Observer<List<CryptoCoinBalance>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(@Nullable List<CryptoCoinBalance> cryptoCoinBalances) {
|
|
||||||
ArrayList<Long> assetIds = new ArrayList<Long>();
|
|
||||||
for (CryptoCoinBalance nextBalance : balancesList.getValue()) {
|
|
||||||
assetIds.add(nextBalance.getCryptoCurrencyId());
|
|
||||||
}
|
|
||||||
List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds);
|
|
||||||
|
|
||||||
CryptoCurrencyAdapter assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
|
|
||||||
spAsset.setAdapter(assetAdapter);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
receiveTransactionValidator = new ReceiveTransactionValidator(this.getContext(), this.cryptoNetAccount, spAsset, etAmount);
|
|
||||||
receiveTransactionValidator.setListener(this);
|
|
||||||
|
|
||||||
CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
|
CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
|
||||||
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
|
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
|
||||||
CryptoNetAccountAdapter toSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
|
CryptoNetAccountAdapter toSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
|
||||||
spTo.setAdapter(toSpinnerAdapter);
|
spTo.setAdapter(toSpinnerAdapter);
|
||||||
spTo.setSelection(0);
|
spTo.setSelection(0);
|
||||||
|
|
||||||
|
setAccountUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setView(view);
|
builder.setView(view);
|
||||||
|
@ -234,8 +228,59 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAccountUI(){
|
||||||
|
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
|
||||||
|
/*
|
||||||
|
* this is only for graphene accounts.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
|
||||||
|
this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
|
||||||
|
|
||||||
|
final LiveData<List<CryptoCoinBalance>> balancesList = db.cryptoCoinBalanceDao().getBalancesFromAccount(cryptoNetAccountId);
|
||||||
|
balancesList.observe(this, new Observer<List<CryptoCoinBalance>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable List<CryptoCoinBalance> cryptoCoinBalances) {
|
||||||
|
ArrayList<Long> assetIds = new ArrayList<Long>();
|
||||||
|
for (CryptoCoinBalance nextBalance : balancesList.getValue()) {
|
||||||
|
assetIds.add(nextBalance.getCryptoCurrencyId());
|
||||||
|
}
|
||||||
|
List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test
|
||||||
|
* */
|
||||||
|
//CryptoCurrency crypto1 = new CryptoCurrency();
|
||||||
|
//crypto1.setId(1);
|
||||||
|
//crypto1.setName("BITCOIN");
|
||||||
|
//crypto1.setPrecision(1);
|
||||||
|
//cryptoCurrencyList.add(crypto1);
|
||||||
|
|
||||||
|
|
||||||
|
CryptoCurrencyAdapter assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
|
||||||
|
spAsset.setAdapter(assetAdapter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
receiveTransactionValidator = new ReceiveTransactionValidator(this.getContext(), this.cryptoNetAccount, spAsset, etAmount);
|
||||||
|
receiveTransactionValidator.setListener(this);
|
||||||
|
} else {
|
||||||
|
CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
|
||||||
|
|
||||||
|
List<String> currencyList = new ArrayList<>();
|
||||||
|
currencyList.add(cryptoCoin.getLabel());
|
||||||
|
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this.getContext(),android.R.layout.simple_list_item_1,currencyList);
|
||||||
|
spAsset.setAdapter(arrayAdapter);
|
||||||
|
|
||||||
|
receiveTransactionValidator = new ReceiveTransactionValidator(this.getContext(), this.cryptoNetAccount, spAsset, etAmount);
|
||||||
|
receiveTransactionValidator.setListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OnItemSelected(R.id.spTo)
|
@OnItemSelected(R.id.spTo)
|
||||||
public void afterToSelected(Spinner spinner, int position) {
|
public void afterToSelected(Spinner spinner, int position) {
|
||||||
|
this.cryptoNetAccount = (CryptoNetAccount)spinner.getSelectedItem();
|
||||||
|
setAccountUI();
|
||||||
this.receiveTransactionValidator.validate();
|
this.receiveTransactionValidator.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +292,10 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
|
||||||
|
|
||||||
@OnItemSelected(R.id.spAsset)
|
@OnItemSelected(R.id.spAsset)
|
||||||
public void afterAssetSelected(Spinner spinner, int position) {
|
public void afterAssetSelected(Spinner spinner, int position) {
|
||||||
this.cryptoCurrency = (CryptoCurrency)spinner.getSelectedItem();
|
if (spinner.getSelectedItem() instanceof CryptoCurrency) {
|
||||||
|
this.cryptoCurrency = (CryptoCurrency) spinner.getSelectedItem();
|
||||||
|
}
|
||||||
|
|
||||||
this.receiveTransactionValidator.validate();
|
this.receiveTransactionValidator.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,71 +343,147 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createQrCode(){
|
public void createQrCode(){
|
||||||
Double amount = 0.0;
|
final Double amount;
|
||||||
try{
|
try{
|
||||||
amount = Double.valueOf(this.etAmount.getText().toString());
|
amount = Double.valueOf(this.etAmount.getText().toString());
|
||||||
|
|
||||||
} catch(NumberFormatException e){
|
} catch(NumberFormatException e){
|
||||||
|
lastAmount = -1.0;
|
||||||
Log.e("ReceiveFragment","Amount casting error.");
|
Log.e("ReceiveFragment","Amount casting error.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptoNetAccount toAccountSelected = (CryptoNetAccount) spTo.getSelectedItem();
|
if (!amount.equals(lastAmount)) {
|
||||||
|
pbQrCode.setVisibility(View.VISIBLE);
|
||||||
|
lastAmount = amount;
|
||||||
|
CryptoNetAccount toAccountSelected = (CryptoNetAccount) spTo.getSelectedItem();
|
||||||
|
|
||||||
/*
|
if (this.qrCodeTask != null) {
|
||||||
* this is only for graphene accounts.
|
this.qrCodeTask.cancel(true);
|
||||||
*
|
}
|
||||||
**/
|
|
||||||
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(toAccountSelected);
|
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
|
||||||
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.clear();
|
||||||
this.invoiceItems.add(
|
this.invoiceItems.add(
|
||||||
new LineItem("transfer", 1, amount)
|
new LineItem("transfer", 1, amount)
|
||||||
);
|
);
|
||||||
|
|
||||||
LineItem items[] = new LineItem[this.invoiceItems.size()];
|
LineItem items[] = new LineItem[this.invoiceItems.size()];
|
||||||
items = this.invoiceItems.toArray(items);
|
items = this.invoiceItems.toArray(items);
|
||||||
this.invoice.setLineItems(items);
|
this.invoice.setLineItems(items);
|
||||||
this.invoice.setTo(grapheneAccountSelected.getName());
|
this.invoice.setTo(grapheneAccountSelected.getName());
|
||||||
this.invoice.setCurrency(this.cryptoCurrency.getName());
|
this.invoice.setCurrency(this.cryptoCurrency.getName());
|
||||||
|
|
||||||
try {
|
//if (this.qrCodeTask != null) {
|
||||||
Bitmap bitmap = textToImageEncode(Invoice.toQrCode(invoice));
|
// this.qrCodeTask.cancel(true);
|
||||||
ivQrCode.setImageBitmap(bitmap);
|
//}
|
||||||
} catch (WriterException e) {
|
|
||||||
Log.e("ReceiveFragment", "Error creating QrCode");
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap textToImageEncode(String Value) throws WriterException {
|
Bitmap textToImageEncode(String Value) throws WriterException {
|
||||||
//TODO: do this in another thread
|
Bitmap bitmap = null;
|
||||||
|
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
|
||||||
BitMatrix bitMatrix;
|
|
||||||
try {
|
try {
|
||||||
bitMatrix = new MultiFormatWriter().encode(
|
BitMatrix bitMatrix = multiFormatWriter.encode(Value, BarcodeFormat.QR_CODE, ivQrCode.getWidth(), ivQrCode.getHeight());
|
||||||
Value,
|
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
|
||||||
BarcodeFormat.DATA_MATRIX.QR_CODE,
|
bitmap = barcodeEncoder.createBitmap(bitMatrix);
|
||||||
ivQrCode.getWidth(), ivQrCode.getHeight(), null
|
} catch (WriterException e) {
|
||||||
);
|
e.printStackTrace();
|
||||||
|
|
||||||
} catch (IllegalArgumentException Illegalargumentexception) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int bitMatrixWidth = bitMatrix.getWidth();
|
|
||||||
int bitMatrixHeight = bitMatrix.getHeight();
|
|
||||||
int[] pixels = new int[bitMatrixWidth * bitMatrixHeight];
|
|
||||||
|
|
||||||
for (int y = 0; y < bitMatrixHeight; y++) {
|
|
||||||
int offset = y * bitMatrixWidth;
|
|
||||||
|
|
||||||
for (int x = 0; x < bitMatrixWidth; x++) {
|
|
||||||
pixels[offset + x] = bitMatrix.get(x, y) ?
|
|
||||||
getResources().getColor(R.color.QRCodeBlackColor):getResources().getColor(R.color.QRCodeWhiteColor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap bitmap = Bitmap.createBitmap(bitMatrixWidth, bitMatrixHeight, Bitmap.Config.ARGB_4444);
|
|
||||||
bitmap.setPixels(pixels, 0, ivQrCode.getWidth(), 0, 0, bitMatrixWidth, bitMatrixHeight);
|
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,10 +83,15 @@ public class SecuritySettingsFragment extends Fragment {
|
||||||
View v = inflater.inflate(R.layout.fragment_security_settings, container, false);
|
View v = inflater.inflate(R.layout.fragment_security_settings, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now this will not be implemented
|
||||||
|
* */
|
||||||
|
sPocketSecurity.setEnabled(false);
|
||||||
|
|
||||||
securityPagerAdapter = new SecurityPagerAdapter(getChildFragmentManager());
|
securityPagerAdapter = new SecurityPagerAdapter(getChildFragmentManager());
|
||||||
mPager.setAdapter(securityPagerAdapter);
|
mPager.setAdapter(securityPagerAdapter);
|
||||||
|
|
||||||
switch(CrystalSecurityMonitor.getInstance(null).actualSecurity()) {
|
switch(CrystalSecurityMonitor.getInstance(getActivity()).actualSecurity()) {
|
||||||
case GeneralSetting.SETTING_PASSWORD:
|
case GeneralSetting.SETTING_PASSWORD:
|
||||||
mPager.setCurrentItem(1);
|
mPager.setCurrentItem(1);
|
||||||
break;
|
break;
|
||||||
|
@ -96,7 +101,6 @@ public class SecuritySettingsFragment extends Fragment {
|
||||||
default:
|
default:
|
||||||
mPager.setCurrentItem(0);
|
mPager.setCurrentItem(0);
|
||||||
}
|
}
|
||||||
mPager.setSwipeLocked(true);
|
|
||||||
|
|
||||||
TabLayout tabLayout = v.findViewById(R.id.tabs);
|
TabLayout tabLayout = v.findViewById(R.id.tabs);
|
||||||
|
|
||||||
|
@ -117,7 +121,7 @@ public class SecuritySettingsFragment extends Fragment {
|
||||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||||
super.setUserVisibleHint(isVisibleToUser);
|
super.setUserVisibleHint(isVisibleToUser);
|
||||||
if (isVisibleToUser) {
|
if (isVisibleToUser) {
|
||||||
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
|
//CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +138,9 @@ public class SecuritySettingsFragment extends Fragment {
|
||||||
case 1:
|
case 1:
|
||||||
return new PinSecurityFragment();
|
return new PinSecurityFragment();
|
||||||
case 2:
|
case 2:
|
||||||
return new PatternSecurityFragment();
|
final PatternSecurityFragment patternSecurityFragment = new PatternSecurityFragment();
|
||||||
|
patternSecurityFragment.setChildViewPager(mPager);
|
||||||
|
return patternSecurityFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; //new OnConstructionFragment();
|
return null; //new OnConstructionFragment();
|
||||||
|
|
|
@ -8,11 +8,11 @@ import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ContextWrapper;
|
import android.content.ContextWrapper;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
@ -22,25 +22,21 @@ import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.widget.ArrayAdapter;
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ScrollView;
|
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
import com.jaredrummler.materialspinner.MaterialSpinner;
|
|
||||||
import com.vincent.filepicker.ToastUtil;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
@ -56,6 +52,14 @@ import butterknife.OnClick;
|
||||||
import butterknife.OnItemSelected;
|
import butterknife.OnItemSelected;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
|
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
||||||
|
import cy.agorise.crystalwallet.dialogs.material.CrystalDialog;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
import cy.agorise.crystalwallet.interfaces.OnResponse;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.BitcoinSendRequest;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.BitcoinUriParseRequest;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
|
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
|
||||||
|
@ -81,10 +85,12 @@ import static butterknife.internal.Utils.listOf;
|
||||||
|
|
||||||
public class SendTransactionFragment extends DialogFragment implements UIValidatorListener, ZXingScannerView.ResultHandler {
|
public class SendTransactionFragment extends DialogFragment implements UIValidatorListener, ZXingScannerView.ResultHandler {
|
||||||
|
|
||||||
|
private final String TAG = getClass().getName();
|
||||||
|
|
||||||
SendTransactionValidator sendTransactionValidator;
|
SendTransactionValidator sendTransactionValidator;
|
||||||
|
|
||||||
@BindView(R.id.spFrom)
|
@BindView(R.id.spFrom)
|
||||||
MaterialSpinner spFrom;
|
Spinner spFrom;
|
||||||
@BindView(R.id.tvFromError)
|
@BindView(R.id.tvFromError)
|
||||||
TextView tvFromError;
|
TextView tvFromError;
|
||||||
@BindView(R.id.etTo)
|
@BindView(R.id.etTo)
|
||||||
|
@ -93,12 +99,14 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
View viewSend;
|
View viewSend;
|
||||||
@BindView(R.id.tvToError)
|
@BindView(R.id.tvToError)
|
||||||
TextView tvToError;
|
TextView tvToError;
|
||||||
|
@BindView(R.id.fabCloseCamera)
|
||||||
|
FloatingActionButton btnCloseCamera;
|
||||||
@BindView(R.id.spAsset)
|
@BindView(R.id.spAsset)
|
||||||
Spinner spAsset;
|
Spinner spAsset;
|
||||||
@BindView(R.id.tvAssetError)
|
@BindView(R.id.tvAssetError)
|
||||||
TextView tvAssetError;
|
TextView tvAssetError;
|
||||||
@BindView(R.id.scrollMain)
|
//@BindView(R.id.scrollMain)
|
||||||
ScrollView scrollMain;
|
//ScrollView scrollMain;
|
||||||
@BindView(R.id.etAmount)
|
@BindView(R.id.etAmount)
|
||||||
EditText etAmount;
|
EditText etAmount;
|
||||||
@BindView(R.id.tvAmountError)
|
@BindView(R.id.tvAmountError)
|
||||||
|
@ -109,11 +117,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
TextView tvMemoError;
|
TextView tvMemoError;
|
||||||
@BindView(R.id.btnSend)
|
@BindView(R.id.btnSend)
|
||||||
FloatingActionButton btnSend;
|
FloatingActionButton btnSend;
|
||||||
@BindView(R.id.btnCancel)
|
|
||||||
TextView btnCancel;
|
|
||||||
@BindView(R.id.ivPeople)
|
@BindView(R.id.ivPeople)
|
||||||
ImageView ivPeople;
|
ImageView ivPeople;
|
||||||
|
|
||||||
@BindView(R.id.ivCamera)
|
@BindView(R.id.ivCamera)
|
||||||
ZXingScannerView mScannerView;
|
ZXingScannerView mScannerView;
|
||||||
|
|
||||||
|
@ -122,7 +127,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
@BindView(R.id.gravatar)
|
@BindView(R.id.gravatar)
|
||||||
CircularImageView userImg;
|
CircularImageView userImg;
|
||||||
|
|
||||||
Button btnScanQrCode;
|
/* Flag to control when the camera is visible and when is hidden */
|
||||||
|
private boolean cameraVisible = false;
|
||||||
|
|
||||||
private long cryptoNetAccountId;
|
private long cryptoNetAccountId;
|
||||||
private CryptoNetAccount cryptoNetAccount;
|
private CryptoNetAccount cryptoNetAccount;
|
||||||
|
@ -131,7 +137,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
private FloatingActionButton fabSend;
|
private FloatingActionButton fabSend;
|
||||||
private AlertDialog.Builder builder;
|
private AlertDialog.Builder builder;
|
||||||
|
|
||||||
|
/* Dialog for loading */
|
||||||
|
private CrystalDialog crystalDialog;
|
||||||
|
|
||||||
public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
|
public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
|
||||||
SendTransactionFragment f = new SendTransactionFragment();
|
SendTransactionFragment f = new SendTransactionFragment();
|
||||||
|
@ -157,72 +164,45 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
|
|
||||||
//AlertDialog.Builder
|
//AlertDialog.Builder
|
||||||
builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full);
|
builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full);
|
||||||
//builder.setTitle("Send");
|
|
||||||
|
|
||||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||||
View view = inflater.inflate(R.layout.send_transaction, null);
|
View view = inflater.inflate(R.layout.send_transaction, null);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Detet scroll changes
|
|
||||||
* */
|
|
||||||
scrollMain.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
|
|
||||||
@Override
|
|
||||||
public void onScrollChanged() {
|
|
||||||
|
|
||||||
View view = scrollMain.getChildAt(scrollMain.getChildCount() - 1);
|
|
||||||
|
|
||||||
int diff = (view.getBottom() - (scrollMain.getHeight() + scrollMain.getScrollY()));
|
|
||||||
|
|
||||||
float traslationY = btnSend.getTranslationY();
|
|
||||||
|
|
||||||
if(diff<=266 && diff>128){
|
|
||||||
//btnSend.setTranslationY(0);
|
|
||||||
//viewSend.setTranslationY(0);
|
|
||||||
|
|
||||||
btnSend.animate().y(880);
|
|
||||||
viewSend.animate().y(800);
|
|
||||||
}
|
|
||||||
else if(diff<=128 && diff>10){
|
|
||||||
//btnSend.setTranslationY(-130);
|
|
||||||
//viewSend.setTranslationY(-130);
|
|
||||||
|
|
||||||
btnSend.animate().y(880);
|
|
||||||
viewSend.animate().y(800);
|
|
||||||
}
|
|
||||||
else if(diff<=10 && diff>0){
|
|
||||||
//btnSend.setTranslationY(-170);
|
|
||||||
//viewSend.setTranslationY(-170);
|
|
||||||
|
|
||||||
btnSend.animate().y(680);
|
|
||||||
viewSend.animate().y(600);
|
|
||||||
}
|
|
||||||
else if(diff==0){
|
|
||||||
//btnSend.setTranslationY(-190);
|
|
||||||
//viewSend.setTranslationY(-190);
|
|
||||||
|
|
||||||
btnSend.animate().y(680);
|
|
||||||
viewSend.animate().y(600);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1);
|
this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1);
|
||||||
|
|
||||||
/*
|
/* Add style to the spinner android */
|
||||||
* Add style to the spinner android
|
|
||||||
* */
|
|
||||||
spFrom.setBackground(getContext().getDrawable(R.drawable.square_color));
|
spFrom.setBackground(getContext().getDrawable(R.drawable.square_color));
|
||||||
|
|
||||||
if (this.cryptoNetAccountId != -1) {
|
if (this.cryptoNetAccountId != -1) {
|
||||||
db = CrystalDatabase.getAppDatabase(this.getContext());
|
db = CrystalDatabase.getAppDatabase(this.getContext());
|
||||||
this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId);
|
this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId);
|
||||||
|
|
||||||
|
CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
|
||||||
|
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
|
||||||
|
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
|
||||||
|
|
||||||
|
spFrom.setAdapter(fromSpinnerAdapter);
|
||||||
|
spFrom.setSelection(0);
|
||||||
|
|
||||||
|
setAccountUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadUserImage();
|
||||||
|
|
||||||
|
/* Check for CAMERA permission */
|
||||||
|
if (Build.VERSION.SDK_INT >= 23 && !checkCameraPermission())
|
||||||
|
requestCameraPermission();
|
||||||
|
|
||||||
|
return builder.setView(view).create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountUI(){
|
||||||
|
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
|
||||||
/*
|
/*
|
||||||
* this is only for graphene accounts.
|
* this is only for graphene accounts.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
|
this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
|
||||||
this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
|
this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
|
||||||
|
|
||||||
|
@ -236,70 +216,102 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
}
|
}
|
||||||
List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds);
|
List<CryptoCurrency> cryptoCurrencyList = db.cryptoCurrencyDao().getByIds(assetIds);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test
|
||||||
|
* */
|
||||||
|
//CryptoCurrency crypto1 = new CryptoCurrency();
|
||||||
|
//crypto1.setId(1);
|
||||||
|
//crypto1.setName("BITCOIN");
|
||||||
|
//crypto1.setPrecision(1);
|
||||||
|
//cryptoCurrencyList.add(crypto1);
|
||||||
|
|
||||||
|
|
||||||
assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
|
assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
|
||||||
spAsset.setAdapter(assetAdapter);
|
spAsset.setAdapter(assetAdapter);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO SendTransactionValidator to accept spFrom
|
// TODO SendTransactionValidator to accept spFrom
|
||||||
sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
|
sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
|
||||||
sendTransactionValidator.setListener(this);
|
sendTransactionValidator.setListener(this);
|
||||||
|
|
||||||
CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
|
} else {
|
||||||
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
|
CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
|
||||||
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
|
|
||||||
|
|
||||||
spFrom.setAdapter(fromSpinnerAdapter);
|
List<String> currencyList = new ArrayList<>();
|
||||||
//spFrom.setSelection(0);
|
currencyList.add(cryptoCoin.getLabel());
|
||||||
|
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this.getContext(),android.R.layout.simple_list_item_1,currencyList);
|
||||||
|
spAsset.setAdapter(arrayAdapter);
|
||||||
|
|
||||||
/*
|
// TODO SendTransactionValidator to accept spFrom
|
||||||
* Custom material spinner implementation
|
sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
|
||||||
* */
|
sendTransactionValidator.setListener(this);
|
||||||
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();
|
private boolean checkCameraPermission() {
|
||||||
try {
|
int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA);
|
||||||
verifyCameraPermissions(getActivity());
|
return result == PackageManager.PERMISSION_GRANTED;
|
||||||
beginScanQrCode();
|
}
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return builder.setView(view).create();
|
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
/*builder.setNeutralButton("Scan QR Code", new DialogInterface.OnClickListener() {
|
mScannerView.setResultHandler(this);
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
beginScanQrCode();
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
// Force dialog fragment to use the full width of the screen
|
|
||||||
Window dialogWindow = getDialog().getWindow();
|
|
||||||
assert dialogWindow != null;
|
|
||||||
dialogWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
loadUserImage();
|
loadUserImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mScannerView.stopCamera();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
@ -328,10 +340,12 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@OnItemSelected(R.id.spFrom)
|
@OnItemSelected(R.id.spFrom)
|
||||||
public void afterFromSelected(Spinner spinner, int position) {
|
public void afterFromSelected(Spinner spinner, int position) {
|
||||||
|
this.cryptoNetAccount = (CryptoNetAccount)spinner.getSelectedItem();
|
||||||
|
setAccountUI();
|
||||||
this.sendTransactionValidator.validate();
|
this.sendTransactionValidator.validate();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etTo,
|
@OnTextChanged(value = R.id.etTo,
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||||
|
@ -351,6 +365,46 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OnClick(R.id.fabCloseCamera)
|
||||||
|
public void onClickCloseCamera(){
|
||||||
|
if(cameraVisible)
|
||||||
|
hideCamera();
|
||||||
|
else
|
||||||
|
showCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the camera and hide the black background
|
||||||
|
* */
|
||||||
|
private void showCamera(){
|
||||||
|
/* Change visibilities of views */
|
||||||
|
mScannerView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
/* Change icon */
|
||||||
|
btnCloseCamera.setImageDrawable(getResources().getDrawable(R.drawable.ic_close));
|
||||||
|
|
||||||
|
/* Reset variable */
|
||||||
|
cameraVisible = true;
|
||||||
|
|
||||||
|
/* Star the camera again */
|
||||||
|
beginScanQrCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the camera and show the black background
|
||||||
|
* */
|
||||||
|
private void hideCamera(){
|
||||||
|
/* Change visibilities of views */
|
||||||
|
mScannerView.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
/* Change icon */
|
||||||
|
btnCloseCamera.setImageDrawable(getResources().getDrawable(R.drawable.ok));
|
||||||
|
|
||||||
|
/* Reset variable */
|
||||||
|
cameraVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
@OnTextChanged(value = R.id.etMemo,
|
@OnTextChanged(value = R.id.etMemo,
|
||||||
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
|
||||||
void afterMemoChanged(Editable editable) {
|
void afterMemoChanged(Editable editable) {
|
||||||
|
@ -408,51 +462,113 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
|
|
||||||
@OnClick(R.id.btnSend)
|
@OnClick(R.id.btnSend)
|
||||||
public void sendTransaction(){
|
public void sendTransaction(){
|
||||||
|
final SendTransactionFragment thisFragment = this;
|
||||||
|
final CryptoNetInfoRequest sendRequest;
|
||||||
|
|
||||||
if (this.sendTransactionValidator.isValid()) {
|
if (this.sendTransactionValidator.isValid()) {
|
||||||
CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex());
|
//CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getItems().get(spFrom.getSelectedIndex());
|
||||||
|
CryptoNetAccount fromAccountSelected = (CryptoNetAccount) spFrom.getSelectedItem();
|
||||||
|
|
||||||
|
|
||||||
/*
|
if (fromAccountSelected.getCryptoNet() == CryptoNet.BITSHARES) {
|
||||||
* this is only for graphene accounts.
|
/* This is only for graphene accounts. */
|
||||||
*
|
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected);
|
||||||
**/
|
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId()));
|
||||||
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())));
|
||||||
|
|
||||||
//TODO convert the amount to long type using the precision of the currency
|
/*final ValidateBitsharesSendRequest*/
|
||||||
Double amountFromEditText = Double.parseDouble(this.etAmount.getText().toString());
|
sendRequest = new ValidateBitsharesSendRequest(
|
||||||
Long amount = (long)Math.floor(amountFromEditText*Math.round(Math.pow(10,((CryptoCurrency)spAsset.getSelectedItem()).getPrecision())));
|
this.getContext(),
|
||||||
|
grapheneAccountSelected,
|
||||||
|
this.etTo.getText().toString(),
|
||||||
|
amount,
|
||||||
|
((CryptoCurrency) spAsset.getSelectedItem()).getName(),
|
||||||
|
etMemo.getText().toString()
|
||||||
|
);
|
||||||
|
|
||||||
final ValidateBitsharesSendRequest sendRequest = new ValidateBitsharesSendRequest(
|
sendRequest.setListener(new CryptoNetInfoRequestListener() {
|
||||||
this.getContext(),
|
@Override
|
||||||
grapheneAccountSelected,
|
public void onCarryOut() {
|
||||||
this.etTo.getText().toString(),
|
if (((ValidateBitsharesSendRequest)sendRequest).getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)) {
|
||||||
amount,
|
try {
|
||||||
((CryptoCurrency)spAsset.getSelectedItem()).getName(),
|
crystalDialog.dismiss();
|
||||||
etMemo.getText().toString()
|
thisFragment.dismiss();
|
||||||
);
|
//thisFragment.finalize();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
sendRequest.setListener(new CryptoNetInfoRequestListener() {
|
throwable.printStackTrace();
|
||||||
@Override
|
}
|
||||||
public void onCarryOut() {
|
} else {
|
||||||
if (sendRequest.getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)){
|
crystalDialog.dismiss();
|
||||||
try {
|
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
|
||||||
this.finalize();
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
|
||||||
|
|
||||||
|
//TODO convert the amount to long type using the precision of the currency
|
||||||
|
Double amountFromEditText = Double.parseDouble(this.etAmount.getText().toString());
|
||||||
|
Long amount = (long) Math.floor(amountFromEditText * (Math.pow(10, cryptoCoin.getPrecision())));
|
||||||
|
|
||||||
|
sendRequest = new BitcoinSendRequest(
|
||||||
|
this.getContext(),
|
||||||
|
this.cryptoNetAccount,
|
||||||
|
this.etTo.getText().toString(),
|
||||||
|
amount,
|
||||||
|
cryptoCoin,
|
||||||
|
etMemo.getText().toString()
|
||||||
|
);
|
||||||
|
|
||||||
|
sendRequest.setListener(new CryptoNetInfoRequestListener() {
|
||||||
|
@Override
|
||||||
|
public void onCarryOut() {
|
||||||
|
if (((BitcoinSendRequest)sendRequest).getStatus().equals(ValidateBitsharesSendRequest.StatusCode.SUCCEEDED)) {
|
||||||
|
try {
|
||||||
|
crystalDialog.dismiss();
|
||||||
|
thisFragment.dismiss();
|
||||||
|
//thisFragment.finalize();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
throwable.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
crystalDialog.dismiss();
|
||||||
|
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If exists mode security show it and validate events in case of success or fail */
|
||||||
|
CrystalSecurityMonitor.getInstance(this.getActivity()).callPasswordRequest(this.getActivity(), new OnResponse() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
|
||||||
|
/* Show loading dialog */
|
||||||
|
crystalDialog = new CrystalDialog((Activity) getContext());
|
||||||
|
crystalDialog.setText("Sending");
|
||||||
|
crystalDialog.progress();
|
||||||
|
crystalDialog.show();
|
||||||
|
|
||||||
|
CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailed() {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
|
//CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginScanQrCode(){
|
public void beginScanQrCode(){
|
||||||
//mScannerView = new ZXingScannerView(getContext());
|
//mScannerView = new ZXingScannerView(getContext());
|
||||||
mScannerView.setFormats(listOf(BarcodeFormat.QR_CODE));
|
mScannerView.setFormats(listOf(BarcodeFormat.QR_CODE));
|
||||||
|
mScannerView.setAspectTolerance(0.5f);
|
||||||
mScannerView.setAutoFocus(true);
|
mScannerView.setAutoFocus(true);
|
||||||
mScannerView.setLaserColor(R.color.colorAccent);
|
mScannerView.setLaserColor(R.color.colorAccent);
|
||||||
mScannerView.setMaskColor(R.color.colorAccent);
|
mScannerView.setMaskColor(R.color.colorAccent);
|
||||||
|
@ -462,24 +578,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
|
|
||||||
// Camera Permissions
|
// Camera Permissions
|
||||||
private static final int REQUEST_CAMERA_PERMISSION = 1;
|
private static final int REQUEST_CAMERA_PERMISSION = 1;
|
||||||
private static String[] PERMISSIONS_CAMERA = {
|
|
||||||
Manifest.permission.CAMERA
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
public static void verifyCameraPermissions(Activity activity) {
|
|
||||||
// Check if we have write permission
|
|
||||||
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
|
|
||||||
|
|
||||||
if (permission != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
// We don't have permission so prompt the user
|
|
||||||
ActivityCompat.requestPermissions(
|
|
||||||
activity,
|
|
||||||
PERMISSIONS_CAMERA,
|
|
||||||
REQUEST_CAMERA_PERMISSION
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValidationSucceeded(final ValidationField field) {
|
public void onValidationSucceeded(final ValidationField field) {
|
||||||
|
@ -534,13 +632,14 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
@Override
|
@Override
|
||||||
public void handleResult(Result result) {
|
public void handleResult(Result result) {
|
||||||
try {
|
try {
|
||||||
System.out.println("CAMERA result " + result.getText() );
|
|
||||||
Invoice invoice = Invoice.fromQrCode(result.getText());
|
Invoice invoice = Invoice.fromQrCode(result.getText());
|
||||||
|
|
||||||
|
Log.d(TAG, "QR Code read: " + invoice.toJsonString());
|
||||||
|
|
||||||
etTo.setText(invoice.getTo());
|
etTo.setText(invoice.getTo());
|
||||||
|
|
||||||
for (int i = 0; i < assetAdapter.getCount(); i++) {
|
for (int i = 0; i < assetAdapter.getCount(); i++) {
|
||||||
if (assetAdapter.getItem(i).getName().equals(invoice.getCurrency())) {
|
if (assetAdapter.getItem(i).getName().equals(invoice.getCurrency().toUpperCase())) {
|
||||||
spAsset.setSelection(i);
|
spAsset.setSelection(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -557,8 +656,34 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
|
||||||
df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ENGLISH));
|
df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ENGLISH));
|
||||||
etAmount.setText(df.format(amount));
|
etAmount.setText(df.format(amount));
|
||||||
Log.i("SendFragment", result.getText());
|
Log.i("SendFragment", result.getText());
|
||||||
|
return;
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Is not a bitshares QR
|
||||||
|
//CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
|
||||||
|
final BitcoinUriParseRequest bitcoinUriParseRequest = new BitcoinUriParseRequest(result.getText(), CryptoCoin.BITCOIN);
|
||||||
|
|
||||||
|
bitcoinUriParseRequest.setListener(new CryptoNetInfoRequestListener() {
|
||||||
|
@Override
|
||||||
|
public void onCarryOut() {
|
||||||
|
if (bitcoinUriParseRequest.getAddress() != null) {
|
||||||
|
if (!bitcoinUriParseRequest.getAddress().equals("")) {
|
||||||
|
etTo.setText(bitcoinUriParseRequest.getAddress());
|
||||||
|
}
|
||||||
|
if (bitcoinUriParseRequest.getAmount() > 0) {
|
||||||
|
etAmount.setText(bitcoinUriParseRequest.getAmount().toString());
|
||||||
|
}
|
||||||
|
if (!bitcoinUriParseRequest.getMemo().equals("")) {
|
||||||
|
etMemo.setText(bitcoinUriParseRequest.getMemo());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getContext(), "Not a valid QR info", Toast.LENGTH_LONG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CryptoNetInfoRequests.getInstance().addRequest(bitcoinUriParseRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,18 +5,20 @@ import android.arch.lifecycle.Observer;
|
||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.arch.paging.PagedList;
|
import android.arch.paging.PagedList;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -25,27 +27,30 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnTextChanged;
|
import butterknife.OnTextChanged;
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended;
|
import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended;
|
||||||
import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel;
|
import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel;
|
||||||
import cy.agorise.crystalwallet.views.TransactionListView;
|
import cy.agorise.crystalwallet.views.TransactionListAdapter;
|
||||||
import cy.agorise.crystalwallet.views.TransactionOrderSpinnerAdapter;
|
import cy.agorise.crystalwallet.views.TransactionOrderSpinnerAdapter;
|
||||||
|
|
||||||
public class TransactionsFragment extends Fragment {
|
public class TransactionsFragment extends Fragment {
|
||||||
|
|
||||||
@BindView(R.id.vTransactionListView)
|
|
||||||
TransactionListView transactionListView;
|
|
||||||
|
|
||||||
@BindView(R.id.spTransactionsOrder)
|
@BindView(R.id.spTransactionsOrder)
|
||||||
Spinner spTransactionsOrder;
|
Spinner spTransactionsOrder;
|
||||||
|
|
||||||
@BindView(R.id.etTransactionSearch)
|
@BindView(R.id.etTransactionSearch)
|
||||||
EditText etTransactionSearch;
|
EditText etTransactionSearch;
|
||||||
|
|
||||||
RecyclerView balanceRecyclerView;
|
@BindView(R.id.tvNoTransactions)
|
||||||
|
TextView tvNoTransactions;
|
||||||
|
|
||||||
|
@BindView(R.id.rvTransactions)
|
||||||
|
RecyclerView rvTransactions;
|
||||||
|
|
||||||
FloatingActionButton fabSend;
|
FloatingActionButton fabSend;
|
||||||
FloatingActionButton fabReceive;
|
FloatingActionButton fabReceive;
|
||||||
|
|
||||||
|
|
||||||
|
TransactionListAdapter transactionListAdapter;
|
||||||
TransactionListViewModel transactionListViewModel;
|
TransactionListViewModel transactionListViewModel;
|
||||||
LiveData<PagedList<CryptoCoinTransactionExtended>> transactionsLiveData;
|
LiveData<PagedList<CryptoCoinTransactionExtended>> transactionsLiveData;
|
||||||
|
|
||||||
|
@ -66,20 +71,22 @@ public class TransactionsFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
View view = inflater.inflate(R.layout.fragment_transactions, container, false);
|
View view = inflater.inflate(R.layout.fragment_transactions, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
// Gets the Balance RecyclerView
|
rvTransactions.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
balanceRecyclerView = view.findViewById(R.id.transactionListView);
|
transactionListAdapter = new TransactionListAdapter(this);
|
||||||
|
rvTransactions.setAdapter(transactionListAdapter);
|
||||||
|
|
||||||
fabSend = getActivity().findViewById(R.id.fabSend);
|
fabSend = getActivity().findViewById(R.id.fabSend);
|
||||||
fabReceive = getActivity().findViewById(R.id.fabReceive);
|
fabReceive = getActivity().findViewById(R.id.fabReceive);
|
||||||
|
|
||||||
// TODO move this listener to the activity, to make this fragment reusable
|
// TODO move this listener to the activity, to make this fragment reusable
|
||||||
// Adds listener to the RecyclerView to show and hide buttons at the bottom of the screen
|
// Adds listener to the RecyclerView to show and hide buttons at the bottom of the screen
|
||||||
balanceRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
rvTransactions.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(RecyclerView recyclerView, int dx,int dy){
|
public void onScrolled(RecyclerView recyclerView, int dx,int dy){
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
super.onScrolled(recyclerView, dx, dy);
|
||||||
|
@ -119,12 +126,17 @@ public class TransactionsFragment extends Fragment {
|
||||||
transactionListViewModel.initTransactionList(orderSelected.getField(),etTransactionSearch.getText().toString());
|
transactionListViewModel.initTransactionList(orderSelected.getField(),etTransactionSearch.getText().toString());
|
||||||
transactionsLiveData = transactionListViewModel.getTransactionList();
|
transactionsLiveData = transactionListViewModel.getTransactionList();
|
||||||
|
|
||||||
final Fragment fragment = this;
|
|
||||||
transactionsLiveData.observe(this, new Observer<PagedList<CryptoCoinTransactionExtended>>() {
|
transactionsLiveData.observe(this, new Observer<PagedList<CryptoCoinTransactionExtended>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(@Nullable PagedList<CryptoCoinTransactionExtended> cryptoCoinTransactions) {
|
public void onChanged(@Nullable PagedList<CryptoCoinTransactionExtended> transactions) {
|
||||||
Log.i("Transactions","Transactions have change! Count:"+cryptoCoinTransactions.size());
|
transactionListAdapter.submitList(transactions);
|
||||||
transactionListView.setData(cryptoCoinTransactions, fragment);
|
|
||||||
|
if(transactions != null && transactions.size() > 0){
|
||||||
|
tvNoTransactions.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
tvNoTransactions.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -136,7 +148,7 @@ public class TransactionsFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initTransactionsOrderSpinner(){
|
public void initTransactionsOrderSpinner(){
|
||||||
List<TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem> spinnerValues = new ArrayList<TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem>();
|
List<TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem> spinnerValues = new ArrayList<>();
|
||||||
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("date","Date",0,false));
|
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("date","Date",0,false));
|
||||||
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("amount","Amount",0,false));
|
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("amount","Amount",0,false));
|
||||||
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("is_input","In/Out",0,false));
|
spinnerValues.add(new TransactionOrderSpinnerAdapter.TransactionOrderSpinnerItem("is_input","In/Out",0,false));
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package cy.agorise.crystalwallet.interfaces;
|
||||||
|
|
||||||
|
public interface OnResponse {
|
||||||
|
void onSuccess();
|
||||||
|
void onFailed();
|
||||||
|
}
|
|
@ -2,11 +2,13 @@ package cy.agorise.crystalwallet.manager;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.common.primitives.UnsignedLong;
|
import com.google.common.primitives.UnsignedLong;
|
||||||
|
|
||||||
import org.bitcoinj.core.ECKey;
|
import org.bitcoinj.core.ECKey;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -20,12 +22,14 @@ import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
|
||||||
import cy.agorise.crystalwallet.apigenerator.grapheneoperation.AccountUpgradeOperationBuilder;
|
import cy.agorise.crystalwallet.apigenerator.grapheneoperation.AccountUpgradeOperationBuilder;
|
||||||
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
|
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
|
||||||
import cy.agorise.crystalwallet.dao.AccountSeedDao;
|
import cy.agorise.crystalwallet.dao.AccountSeedDao;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
||||||
import cy.agorise.crystalwallet.models.seed.BIP39;
|
import cy.agorise.crystalwallet.models.seed.BIP39;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetEquivalentRequest;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetEquivalentRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.GetBitsharesAccountNameCacheRequest;
|
import cy.agorise.crystalwallet.requestmanagers.GetBitsharesAccountNameCacheRequest;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.ImportBitsharesAccountRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesLTMUpgradeRequest;
|
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesLTMUpgradeRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
|
import cy.agorise.crystalwallet.requestmanagers.ValidateBitsharesSendRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest;
|
import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest;
|
||||||
|
@ -55,6 +59,7 @@ import cy.agorise.graphenej.UserAccount;
|
||||||
import cy.agorise.graphenej.models.AccountProperties;
|
import cy.agorise.graphenej.models.AccountProperties;
|
||||||
import cy.agorise.graphenej.models.BlockHeader;
|
import cy.agorise.graphenej.models.BlockHeader;
|
||||||
import cy.agorise.graphenej.models.HistoricalTransfer;
|
import cy.agorise.graphenej.models.HistoricalTransfer;
|
||||||
|
import cy.agorise.graphenej.objects.Memo;
|
||||||
import cy.agorise.graphenej.operations.TransferOperationBuilder;
|
import cy.agorise.graphenej.operations.TransferOperationBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,8 +69,6 @@ import cy.agorise.graphenej.operations.TransferOperationBuilder;
|
||||||
*/
|
*/
|
||||||
public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
||||||
|
|
||||||
//private final static String BITSHARES_TESTNET_CHAIN_ID= "9cf6f255a208100d2bb275a3c52f4b1589b7ec9c9bfc2cb2a5fe6411295106d8";
|
|
||||||
|
|
||||||
private final static String SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
private final static String SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
||||||
private final static String DEFAULT_TIME_ZONE = "GMT";
|
private final static String DEFAULT_TIME_ZONE = "GMT";
|
||||||
|
|
||||||
|
@ -89,6 +92,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(fetch)[0];
|
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(fetch)[0];
|
||||||
fetch.setId(idAccount);
|
fetch.setId(idAccount);
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(fetch));
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(fetch));
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
|
||||||
|
if(seed.getName() == null || seed.getName().isEmpty()){
|
||||||
|
seed.setName(grapheneAccount.getName());
|
||||||
|
db.accountSeedDao().insertAccountSeed(seed);
|
||||||
|
}
|
||||||
subscribeBitsharesAccount(fetch.getId(),fetch.getAccountId(),context);
|
subscribeBitsharesAccount(fetch.getId(),fetch.getAccountId(),context);
|
||||||
request.success(fetch);
|
request.success(fetch);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +137,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
long[] idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
long[] idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
||||||
grapheneAccount.setId(idAccount[0]);
|
grapheneAccount.setId(idAccount[0]);
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
|
||||||
|
if(seed.getName() == null || seed.getName().isEmpty()){
|
||||||
|
seed.setName(grapheneAccount.getName());
|
||||||
|
db.accountSeedDao().insertAccountSeed(seed);
|
||||||
|
}
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +158,14 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
GrapheneAccount fetch = (GrapheneAccount) answer;
|
GrapheneAccount fetch = (GrapheneAccount) answer;
|
||||||
grapheneAccount.setName(fetch.getName());
|
grapheneAccount.setName(fetch.getName());
|
||||||
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
|
||||||
|
grapheneAccount.setId(idAccount);
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
|
||||||
|
if(seed.getName() == null || seed.getName().isEmpty()){
|
||||||
|
seed.setName(grapheneAccount.getName());
|
||||||
|
db.accountSeedDao().insertAccountSeed(seed);
|
||||||
|
}
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,8 +176,14 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
});
|
});
|
||||||
}else {
|
}else {
|
||||||
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
|
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
|
||||||
|
grapheneAccount.setId(idAccount);
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
|
||||||
|
if(seed.getName() == null || seed.getName().isEmpty()){
|
||||||
|
seed.setName(grapheneAccount.getName());
|
||||||
|
db.accountSeedDao().insertAccountSeed(seed);
|
||||||
|
}
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context);
|
subscribeBitsharesAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,6 +204,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
info.setAccountId(fetch.getAccountId());
|
info.setAccountId(fetch.getAccountId());
|
||||||
grapheneAccount.setAccountId(fetch.getAccountId());
|
grapheneAccount.setAccountId(fetch.getAccountId());
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
|
||||||
|
if(seed.getName() == null || seed.getName().isEmpty()){
|
||||||
|
seed.setName(grapheneAccount.getName());
|
||||||
|
db.accountSeedDao().insertAccountSeed(seed);
|
||||||
|
}
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +225,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
info.setName(fetch.getName());
|
info.setName(fetch.getName());
|
||||||
grapheneAccount.setName(fetch.getName());
|
grapheneAccount.setName(fetch.getName());
|
||||||
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
|
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
|
||||||
|
if(seed.getName() == null || seed.getName().isEmpty()){
|
||||||
|
seed.setName(grapheneAccount.getName());
|
||||||
|
db.accountSeedDao().insertAccountSeed(seed);
|
||||||
|
}
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +239,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
|
||||||
|
if(seed.getName() == null || seed.getName().isEmpty()){
|
||||||
|
seed.setName(grapheneAccount.getName());
|
||||||
|
db.accountSeedDao().insertAccountSeed(seed);
|
||||||
|
}
|
||||||
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +252,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
private void subscribeBitsharesAccount(long accountId, String accountBitsharesID, Context context){
|
private void subscribeBitsharesAccount(long accountId, String accountBitsharesID, Context context){
|
||||||
GrapheneApiGenerator.subscribeBitsharesAccount(accountId,accountBitsharesID,context);
|
GrapheneApiGenerator.subscribeBitsharesAccount(accountId,accountBitsharesID,context);
|
||||||
BitsharesAccountManager.refreshAccountTransactions(accountId,context);
|
BitsharesAccountManager.refreshAccountTransactions(accountId,context);
|
||||||
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesID,context);
|
GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesID,CryptoNet.BITSHARES,context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,27 +261,103 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onNewRequest(CryptoNetInfoRequest request) {
|
public void onNewRequest(CryptoNetInfoRequest request) {
|
||||||
if (request instanceof ValidateImportBitsharesAccountRequest){
|
if(request.getCoin().equals(CryptoCoin.BITSHARES)) {
|
||||||
this.validateImportAccount((ValidateImportBitsharesAccountRequest) request);
|
if (request instanceof ImportBitsharesAccountRequest) {
|
||||||
} else if (request instanceof ValidateExistBitsharesAccountRequest){
|
this.importAccount((ImportBitsharesAccountRequest) request);
|
||||||
this.validateExistAcccount((ValidateExistBitsharesAccountRequest) request);
|
} else if (request instanceof ValidateImportBitsharesAccountRequest) {
|
||||||
} else if (request instanceof ValidateBitsharesSendRequest){
|
this.validateImportAccount((ValidateImportBitsharesAccountRequest) request);
|
||||||
this.validateSendRequest((ValidateBitsharesSendRequest) request);
|
} else if (request instanceof ValidateExistBitsharesAccountRequest) {
|
||||||
}else if (request instanceof CryptoNetEquivalentRequest){
|
this.validateExistAcccount((ValidateExistBitsharesAccountRequest) request);
|
||||||
this.getEquivalentValue((CryptoNetEquivalentRequest) request);
|
} else if (request instanceof ValidateBitsharesSendRequest) {
|
||||||
}else if (request instanceof ValidateCreateBitsharesAccountRequest){
|
this.validateSendRequest((ValidateBitsharesSendRequest) request);
|
||||||
this.validateCreateAccount((ValidateCreateBitsharesAccountRequest) request);
|
} else if (request instanceof CryptoNetEquivalentRequest) {
|
||||||
}else if (request instanceof ValidateBitsharesLTMUpgradeRequest){
|
this.getEquivalentValue((CryptoNetEquivalentRequest) request);
|
||||||
this.validateLTMAccountUpgrade((ValidateBitsharesLTMUpgradeRequest) request);
|
} else if (request instanceof ValidateCreateBitsharesAccountRequest) {
|
||||||
}else if (request instanceof GetBitsharesAccountNameCacheRequest){
|
this.validateCreateAccount((ValidateCreateBitsharesAccountRequest) request);
|
||||||
this.getBitsharesAccountNameCacheRequest((GetBitsharesAccountNameCacheRequest) request);
|
} else if (request instanceof ValidateBitsharesLTMUpgradeRequest) {
|
||||||
}else{
|
this.validateLTMAccountUpgrade((ValidateBitsharesLTMUpgradeRequest) request);
|
||||||
|
} else if (request instanceof GetBitsharesAccountNameCacheRequest) {
|
||||||
|
this.getBitsharesAccountNameCacheRequest((GetBitsharesAccountNameCacheRequest) request);
|
||||||
|
} else {
|
||||||
|
|
||||||
//TODO not implemented
|
//TODO not implemented
|
||||||
System.out.println("Error request not implemented " + request.getClass().getName());
|
System.out.println("Error request not implemented " + request.getClass().getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void importAccount(final ImportBitsharesAccountRequest importRequest){
|
||||||
|
final CrystalDatabase db = CrystalDatabase.getAppDatabase(importRequest.getContext());
|
||||||
|
final AccountSeedDao accountSeedDao = db.accountSeedDao();
|
||||||
|
ApiRequest getAccountNamesBK = new ApiRequest(0, new ApiRequestListener() {
|
||||||
|
@Override
|
||||||
|
public void success(Object answer, int idPetition) {
|
||||||
|
if(answer != null && importRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.NOT_STARTED)) {
|
||||||
|
UserAccount userAccount = (UserAccount) answer;
|
||||||
|
importRequest.setSeedType(SeedType.BRAINKEY);
|
||||||
|
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
|
||||||
|
|
||||||
|
AccountSeed seed = new AccountSeed();
|
||||||
|
seed.setName(userAccount.getName());
|
||||||
|
seed.setType(importRequest.getSeedType());
|
||||||
|
seed.setMasterSeed(importRequest.getMnemonic());
|
||||||
|
long idSeed = accountSeedDao.insertAccountSeed(seed);
|
||||||
|
if (idSeed >= 0) {
|
||||||
|
GrapheneAccount account = new GrapheneAccount();
|
||||||
|
account.setCryptoNet(CryptoNet.BITSHARES);
|
||||||
|
account.setAccountIndex(0);
|
||||||
|
account.setSeedId(idSeed);
|
||||||
|
account.setAccountId(userAccount.getObjectId());
|
||||||
|
importAccountFromSeed(account, importRequest.getContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fail(int idPetition) {
|
||||||
|
BIP39 bip39 = new BIP39(-1, importRequest.getMnemonic());
|
||||||
|
ApiRequest getAccountNamesBP39 = new ApiRequest(0, new ApiRequestListener() {
|
||||||
|
@Override
|
||||||
|
public void success(Object answer, int idPetition) {
|
||||||
|
if(answer != null && importRequest.getStatus().equals(ImportBitsharesAccountRequest.StatusCode.NOT_STARTED)) {
|
||||||
|
UserAccount userAccount = (UserAccount) answer;
|
||||||
|
importRequest.setSeedType(SeedType.BIP39);
|
||||||
|
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
|
||||||
|
|
||||||
|
AccountSeed seed = new AccountSeed();
|
||||||
|
seed.setName(userAccount.getName());
|
||||||
|
seed.setType(importRequest.getSeedType());
|
||||||
|
seed.setMasterSeed(importRequest.getMnemonic());
|
||||||
|
long idSeed = accountSeedDao.insertAccountSeed(seed);
|
||||||
|
if (idSeed >= 0) {
|
||||||
|
GrapheneAccount account = new GrapheneAccount();
|
||||||
|
account.setCryptoNet(CryptoNet.BITSHARES);
|
||||||
|
account.setAccountIndex(0);
|
||||||
|
account.setSeedId(idSeed);
|
||||||
|
account.setAccountId(userAccount.getObjectId());
|
||||||
|
importAccountFromSeed(account, importRequest.getContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fail(int idPetition) {
|
||||||
|
importRequest.setStatus(ImportBitsharesAccountRequest.StatusCode.BAD_SEED);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
GrapheneApiGenerator.getAccountByOwnerOrActiveAddress(new Address(ECKey.fromPublicOnly(bip39.getBitsharesActiveKey(0).getPubKey())),CryptoNet.BITSHARES,getAccountNamesBP39);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BrainKey bk = new BrainKey(importRequest.getMnemonic(), 0);
|
||||||
|
|
||||||
|
GrapheneApiGenerator.getAccountByOwnerOrActiveAddress(bk.getPublicAddress("BTS"),CryptoNet.BITSHARES,getAccountNamesBK);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the import account request
|
* Process the import account request
|
||||||
*/
|
*/
|
||||||
|
@ -307,7 +423,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.NO_ACCOUNT_DATA);
|
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.NO_ACCOUNT_DATA);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
GrapheneApiGenerator.getAccountById((String)answer,getAccountInfo);
|
GrapheneApiGenerator.getAccountById((String)answer,CryptoNet.BITSHARES,getAccountInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -317,7 +433,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
GrapheneApiGenerator.getAccountIdByName(importRequest.getAccountName(),checkAccountName);
|
GrapheneApiGenerator.getAccountIdByName(importRequest.getAccountName(),CryptoNet.BITSHARES,checkAccountName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateCreateAccount(final ValidateCreateBitsharesAccountRequest createRequest){
|
private void validateCreateAccount(final ValidateCreateBitsharesAccountRequest createRequest){
|
||||||
|
@ -372,7 +488,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
validateRequest.setAccountExists(false);
|
validateRequest.setAccountExists(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
GrapheneApiGenerator.getAccountIdByName(validateRequest.getAccountName(),checkAccountName);
|
GrapheneApiGenerator.getAccountIdByName(validateRequest.getAccountName(),CryptoNet.BITSHARES,checkAccountName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -471,9 +587,16 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
.setTransferAmount(new AssetAmount(UnsignedLong.valueOf(sendRequest.getAmount()), new Asset(idAsset)))
|
.setTransferAmount(new AssetAmount(UnsignedLong.valueOf(sendRequest.getAmount()), new Asset(idAsset)))
|
||||||
.setFee(new AssetAmount(UnsignedLong.valueOf(0), feeAsset));
|
.setFee(new AssetAmount(UnsignedLong.valueOf(0), feeAsset));
|
||||||
if (sendRequest.getMemo() != null) {
|
if (sendRequest.getMemo() != null) {
|
||||||
//builder.setMemo(new Memo(fromUserAccount,toUserAccount,0,sendRequest.getMemo().getBytes()));
|
try {
|
||||||
//TODO memo
|
//TODO change authority for memo
|
||||||
System.out.println("transaction has 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ArrayList<BaseOperation> operationList = new ArrayList<>();
|
ArrayList<BaseOperation> operationList = new ArrayList<>();
|
||||||
operationList.add(builder.build());
|
operationList.add(builder.build());
|
||||||
|
@ -570,7 +693,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
|
AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
|
||||||
|
|
||||||
ApiRequest accountRequest = new ApiRequest(0, listener);
|
ApiRequest accountRequest = new ApiRequest(0, listener);
|
||||||
GrapheneApiGenerator.getAccountById(grapheneId,accountRequest);
|
GrapheneApiGenerator.getAccountById(grapheneId,CryptoNet.BITSHARES,accountRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -582,7 +705,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
|
AccountIdOrNameListener listener = new AccountIdOrNameListener(request);
|
||||||
|
|
||||||
ApiRequest accountRequest = new ApiRequest(0, listener);
|
ApiRequest accountRequest = new ApiRequest(0, listener);
|
||||||
GrapheneApiGenerator.getAccountByName(grapheneName,accountRequest);
|
GrapheneApiGenerator.getAccountByName(grapheneName,CryptoNet.BITSHARES,accountRequest);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,7 +716,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
ApiRequest assetRequest = new ApiRequest(0, nameListener);
|
ApiRequest assetRequest = new ApiRequest(0, nameListener);
|
||||||
ArrayList<String> assetNames = new ArrayList<>();
|
ArrayList<String> assetNames = new ArrayList<>();
|
||||||
assetNames.add(assetName);
|
assetNames.add(assetName);
|
||||||
GrapheneApiGenerator.getAssetByName(assetNames, assetRequest);
|
GrapheneApiGenerator.getAssetByName(assetNames, CryptoNet.BITSHARES,assetRequest);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +739,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
int stop = start + limit;
|
int stop = start + limit;
|
||||||
|
|
||||||
ApiRequest transactionRequest = new ApiRequest(0, new TransactionRequestListener(start, stop, limit, grapheneAccount, db));
|
ApiRequest transactionRequest = new ApiRequest(0, new TransactionRequestListener(start, stop, limit, grapheneAccount, db));
|
||||||
GrapheneApiGenerator.getAccountTransaction(grapheneAccount.getAccountId(), start, stop, limit, transactionRequest);
|
GrapheneApiGenerator.getAccountTransaction(grapheneAccount.getAccountId(), start, stop, limit, CryptoNet.BITSHARES,transactionRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,7 +829,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
});
|
});
|
||||||
ArrayList<String> assets = new ArrayList<>();
|
ArrayList<String> assets = new ArrayList<>();
|
||||||
assets.add(transfer.getOperation().getAssetAmount().getAsset().getObjectId());
|
assets.add(transfer.getOperation().getAssetAmount().getAsset().getObjectId());
|
||||||
GrapheneApiGenerator.getAssetById(assets,assetRequest);
|
GrapheneApiGenerator.getAssetById(assets,CryptoNet.BITSHARES,assetRequest);
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
saveTransaction(transaction,info,transfer);
|
saveTransaction(transaction,info,transfer);
|
||||||
|
@ -719,7 +842,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
int newStart= start + limit;
|
int newStart= start + limit;
|
||||||
int newStop= stop + limit;
|
int newStop= stop + limit;
|
||||||
ApiRequest transactionRequest = new ApiRequest(newStart/limit, new TransactionRequestListener(newStart,newStop,limit,account,db));
|
ApiRequest transactionRequest = new ApiRequest(newStart/limit, new TransactionRequestListener(newStart,newStop,limit,account,db));
|
||||||
GrapheneApiGenerator.getAccountTransaction(account.getAccountId(),newStart,newStop,limit,transactionRequest);
|
GrapheneApiGenerator.getAccountTransaction(account.getAccountId(),newStart,newStop,limit,CryptoNet.BITSHARES,transactionRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,7 +858,7 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
|
||||||
transaction.setInput(!transfer.getOperation().getFrom().getObjectId().equals(account.getAccountId()));
|
transaction.setInput(!transfer.getOperation().getFrom().getObjectId().equals(account.getAccountId()));
|
||||||
transaction.setTo(transfer.getOperation().getTo().getObjectId());
|
transaction.setTo(transfer.getOperation().getTo().getObjectId());
|
||||||
|
|
||||||
GrapheneApiGenerator.getBlockHeaderTime(transfer.getBlockNum(), new ApiRequest(0, new GetTransactionDate(transaction, db.transactionDao())));
|
GrapheneApiGenerator.getBlockHeaderTime(transfer.getBlockNum(),CryptoNet.BITSHARES, new ApiRequest(0, new GetTransactionDate(transaction, db.transactionDao())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,6 @@ public class FileBackupManager implements FileServiceRequestsListener {
|
||||||
public static byte[] decompress(byte[] inputBytes, int which) {
|
public static byte[] decompress(byte[] inputBytes, int which) {
|
||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
try {
|
try {
|
||||||
System.out.println("Bytes: "+Util.bytesToHex(inputBytes));
|
|
||||||
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
|
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048);
|
ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048);
|
||||||
if(which == Util.XZ) {
|
if(which == Util.XZ) {
|
||||||
|
|
|
@ -3,32 +3,74 @@ package cy.agorise.crystalwallet.manager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import org.bitcoinj.core.Address;
|
import org.bitcoinj.core.Address;
|
||||||
|
import org.bitcoinj.core.AddressFormatException;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.core.ECKey;
|
||||||
import org.bitcoinj.core.Sha256Hash;
|
import org.bitcoinj.core.Sha256Hash;
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
import org.bitcoinj.core.TransactionOutPoint;
|
import org.bitcoinj.core.TransactionOutPoint;
|
||||||
import org.bitcoinj.crypto.ChildNumber;
|
import org.bitcoinj.crypto.ChildNumber;
|
||||||
|
import org.bitcoinj.crypto.DeterministicKey;
|
||||||
import org.bitcoinj.crypto.HDKeyDerivation;
|
import org.bitcoinj.crypto.HDKeyDerivation;
|
||||||
import org.bitcoinj.script.Script;
|
import org.bitcoinj.script.Script;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.apigenerator.ApiRequest;
|
import cy.agorise.crystalwallet.apigenerator.ApiRequest;
|
||||||
import cy.agorise.crystalwallet.apigenerator.ApiRequestListener;
|
import cy.agorise.crystalwallet.apigenerator.ApiRequestListener;
|
||||||
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
|
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
|
||||||
import cy.agorise.crystalwallet.apigenerator.insightapi.BroadcastTransaction;
|
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.models.CryptoNetAccount;
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
import cy.agorise.crystalwallet.models.GTxIO;
|
import cy.agorise.crystalwallet.requestmanagers.BitcoinSendRequest;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
|
import cy.agorise.crystalwallet.requestmanagers.BitcoinUriParseRequest;
|
||||||
import cy.agorise.crystalwallet.models.GeneralTransaction;
|
import cy.agorise.crystalwallet.requestmanagers.CalculateBitcoinUriRequest;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.CreateBitcoinAccountRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.GeneralAccountSendRequest;
|
import cy.agorise.crystalwallet.requestmanagers.NextBitcoinAccountAddressRequest;
|
||||||
|
import cy.agorise.crystalwallet.requestmanagers.ValidateBitcoinAddressRequest;
|
||||||
import cy.agorise.graphenej.Util;
|
import cy.agorise.graphenej.Util;
|
||||||
|
|
||||||
public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
|
||||||
|
|
||||||
|
static HashMap<CryptoCoin, GeneralAccountManager> generalAccountManagers = new HashMap();
|
||||||
|
|
||||||
|
private static CryptoCoin[] SUPPORTED_COINS = new CryptoCoin[]{
|
||||||
|
CryptoCoin.BITCOIN,
|
||||||
|
CryptoCoin.BITCOIN_TEST,
|
||||||
|
CryptoCoin.DASH,
|
||||||
|
CryptoCoin.LITECOIN
|
||||||
|
} ;
|
||||||
|
|
||||||
|
final CryptoCoin cryptoCoin;
|
||||||
|
final Context context;
|
||||||
|
|
||||||
|
public static GeneralAccountManager getAccountManager(CryptoCoin coin){
|
||||||
|
return generalAccountManagers.get(coin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeneralAccountManager(CryptoCoin cryptoCoin, Context context) {
|
||||||
|
this.cryptoCoin = cryptoCoin;
|
||||||
|
this.context = context;
|
||||||
|
generalAccountManagers.put(cryptoCoin,this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createAccountFromSeed(CryptoNetAccount account, ManagerRequest request, Context context) {
|
public void createAccountFromSeed(CryptoNetAccount account, ManagerRequest request, Context context) {
|
||||||
|
|
||||||
|
@ -40,55 +82,347 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadAccountFromDB(CryptoNetAccount account, Context context) {
|
public void loadAccountFromDB(final CryptoNetAccount account, Context context) {
|
||||||
|
final CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
|
||||||
|
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(account.getSeedId());
|
||||||
|
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
|
||||||
|
new ChildNumber(44, true));
|
||||||
|
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
|
||||||
|
new ChildNumber(cryptoCoin.getCoinNumber(), true));
|
||||||
|
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
|
||||||
|
new ChildNumber(account.getAccountIndex(), true));
|
||||||
|
final DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
|
||||||
|
new ChildNumber(0, false));
|
||||||
|
final DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
|
||||||
|
new ChildNumber(1, false));
|
||||||
|
|
||||||
|
CryptoCoinBalance balance = new CryptoCoinBalance();
|
||||||
|
long amount = 0;
|
||||||
|
List<CryptoCoinTransaction> trransactions = db.transactionDao().getByIdAccount(account.getId());
|
||||||
|
for(CryptoCoinTransaction transaction : trransactions){
|
||||||
|
if(transaction.isConfirmed()){
|
||||||
|
if(transaction.getInput()){
|
||||||
|
amount += transaction.getAmount();
|
||||||
|
}else{
|
||||||
|
amount -= transaction.getAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
balance.setBalance(amount);
|
||||||
|
balance.setCryptoCurrencyId(db.cryptoCurrencyDao().getByName(cryptoCoin.getLabel(),cryptoCoin.name()).getId());
|
||||||
|
balance.setAccountId(account.getId());
|
||||||
|
db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance);
|
||||||
|
|
||||||
|
long indexExternal = db.bitcoinAddressDao().getLastExternalAddress(account.getId());
|
||||||
|
if(indexExternal > 0){
|
||||||
|
for(int i = 0; i < indexExternal;i++){
|
||||||
|
BitcoinAddress address = db.bitcoinAddressDao().getExternalByIndex(i);
|
||||||
|
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,address.getAddress(),true,null);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
ECKey externalAddrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) 0, true));
|
||||||
|
BitcoinAddress address = new BitcoinAddress();
|
||||||
|
address.setChange(false);
|
||||||
|
address.setAccountId(account.getId());
|
||||||
|
address.setIndex(0);
|
||||||
|
String addressString = externalAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
|
||||||
|
address.setAddress(addressString);
|
||||||
|
db.bitcoinAddressDao().insertBitcoinAddresses(address);
|
||||||
|
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
|
||||||
|
new CheckAddressForTransaction(db.bitcoinAddressDao(),account.getId(),externalKey,false,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
long indexChange = db.bitcoinAddressDao().getLastChangeAddress(account.getId());
|
||||||
|
if(indexChange > 0){
|
||||||
|
for(int i = 0; i < indexChange;i++){
|
||||||
|
BitcoinAddress address = db.bitcoinAddressDao().getChangeByIndex(i);
|
||||||
|
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,address.getAddress(),true,null);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
ECKey changeAddrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) 0, true));
|
||||||
|
BitcoinAddress address = new BitcoinAddress();
|
||||||
|
address.setChange(true);
|
||||||
|
address.setAccountId(account.getId());
|
||||||
|
address.setIndex(0);
|
||||||
|
String addressString =changeAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
|
||||||
|
address.setAddress(addressString);
|
||||||
|
db.bitcoinAddressDao().insertBitcoinAddresses(address);
|
||||||
|
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
|
||||||
|
new CheckAddressForTransaction(db.bitcoinAddressDao(),account.getId(),externalKey,true,0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNewRequest(CryptoNetInfoRequest request) {
|
public void onNewRequest(CryptoNetInfoRequest request) {
|
||||||
|
//if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
|
||||||
|
if(request.getCoin().equals(this.cryptoCoin)){
|
||||||
|
if(request instanceof BitcoinSendRequest) {
|
||||||
|
this.send((BitcoinSendRequest) request);
|
||||||
|
}else if(request instanceof CreateBitcoinAccountRequest){
|
||||||
|
this.createGeneralAccount((CreateBitcoinAccountRequest) request);
|
||||||
|
}else if(request instanceof NextBitcoinAccountAddressRequest){
|
||||||
|
this.getNextAddress((NextBitcoinAccountAddressRequest) request);
|
||||||
|
}else if(request instanceof ValidateBitcoinAddressRequest){
|
||||||
|
this.validateAddress((ValidateBitcoinAddressRequest) request);
|
||||||
|
}else if(request instanceof CalculateBitcoinUriRequest){
|
||||||
|
this.calculateUri((CalculateBitcoinUriRequest) request);
|
||||||
|
}else if(request instanceof BitcoinUriParseRequest){
|
||||||
|
this.parseUri((BitcoinUriParseRequest) request);
|
||||||
|
}else{
|
||||||
|
System.out.println("Invalid " +this.cryptoCoin.getLabel() + " request ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that process each transaction fetched by the insight api
|
||||||
|
* @param txi
|
||||||
|
*/
|
||||||
|
public void processTxi(Txi txi){
|
||||||
|
try {
|
||||||
|
System.out.println("GeneralAccountManager processingTxi " + txi.txid);
|
||||||
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
|
||||||
|
List<BitcoinTransaction> btTransactions = db.bitcoinTransactionDao().getTransactionsByTxid(txi.txid);
|
||||||
|
if (!btTransactions.isEmpty()) {
|
||||||
|
System.out.println("GeneralAccountManager Transaction not null " + txi.txid);
|
||||||
|
for (BitcoinTransaction btTransaction : btTransactions) {
|
||||||
|
btTransaction.setConfirmations(txi.confirmations);
|
||||||
|
CryptoCoinTransaction ccTransaction = db.transactionDao().getById(btTransaction.getCryptoCoinTransactionId());
|
||||||
|
if (!ccTransaction.isConfirmed() && btTransaction.getConfirmations() >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
|
||||||
|
ccTransaction.setConfirmed(true);
|
||||||
|
db.transactionDao().insertTransaction(ccTransaction);
|
||||||
|
updateBalance(ccTransaction, (ccTransaction.getInput() ? 1 : -1) * ccTransaction.getAmount(), db);
|
||||||
|
}
|
||||||
|
|
||||||
|
db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*List<CryptoCoinTransaction> ccTransactions = new ArrayList();
|
||||||
|
btTransactions = new ArrayList();*/ //TODO transactions involving multiples accounts
|
||||||
|
CryptoCoinTransaction ccTransaction = new CryptoCoinTransaction();
|
||||||
|
BitcoinTransaction btTransaction = new BitcoinTransaction();
|
||||||
|
btTransaction.setTxId(txi.txid);
|
||||||
|
btTransaction.setBlock(txi.blockheight);
|
||||||
|
btTransaction.setFee((long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision())));
|
||||||
|
btTransaction.setConfirmations(txi.confirmations);
|
||||||
|
ccTransaction.setDate(new Date(txi.time * 1000));
|
||||||
|
if (txi.txlock || txi.confirmations >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
|
||||||
|
ccTransaction.setConfirmed(true);
|
||||||
|
} else {
|
||||||
|
ccTransaction.setConfirmed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ccTransaction.setInput(false);
|
||||||
|
|
||||||
|
long amount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//transaction.setAccount(this.mAccount);
|
||||||
|
//transaction.setType(cryptoCoin);
|
||||||
|
List<BitcoinTransactionGTxIO> gtxios = new ArrayList();
|
||||||
|
for (Vin vin : txi.vin) {
|
||||||
|
BitcoinTransactionGTxIO input = new BitcoinTransactionGTxIO();
|
||||||
|
String addr = vin.addr;
|
||||||
|
input.setAddress(addr);
|
||||||
|
input.setIndex(vin.n);
|
||||||
|
input.setOutput(true);
|
||||||
|
input.setAmount((long) (vin.value * Math.pow(10, cryptoCoin.getPrecision())));
|
||||||
|
input.setOriginalTxId(vin.txid);
|
||||||
|
input.setScriptHex(vin.scriptSig.hex);
|
||||||
|
|
||||||
|
BitcoinAddress address = db.bitcoinAddressDao().getdadress(addr);
|
||||||
|
if (address != null) {
|
||||||
|
if (ccTransaction.getAccountId() < 0) {
|
||||||
|
ccTransaction.setAccountId(address.getAccountId());
|
||||||
|
ccTransaction.setFrom(addr);
|
||||||
|
ccTransaction.setInput(false);
|
||||||
|
amount -= (long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (ccTransaction.getAccountId() == address.getAccountId()) {
|
||||||
|
amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision()));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) {
|
||||||
|
ccTransaction.setFrom(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtxios.add(input);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Vout vout : txi.vout) {
|
||||||
|
if (vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
BitcoinTransactionGTxIO output = new BitcoinTransactionGTxIO();
|
||||||
|
String addr = vout.scriptPubKey.addresses[0];
|
||||||
|
output.setAddress(addr);
|
||||||
|
output.setIndex(vout.n);
|
||||||
|
output.setOutput(false);
|
||||||
|
output.setAmount((long) (vout.value * Math.pow(10, cryptoCoin.getPrecision())));
|
||||||
|
output.setScriptHex(vout.scriptPubKey.hex);
|
||||||
|
output.setOriginalTxId(txi.txid);
|
||||||
|
|
||||||
|
gtxios.add(output);
|
||||||
|
|
||||||
|
BitcoinAddress address = db.bitcoinAddressDao().getdadress(addr);
|
||||||
|
if (address != null) {
|
||||||
|
if (ccTransaction.getAccountId() < 0) {
|
||||||
|
ccTransaction.setAccountId(address.getAccountId());
|
||||||
|
ccTransaction.setInput(true);
|
||||||
|
ccTransaction.setTo(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (ccTransaction.getAccountId() == address.getAccountId()) {
|
||||||
|
amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision()));
|
||||||
|
//}
|
||||||
|
} else {
|
||||||
|
//TOOD multiple send address
|
||||||
|
if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) {
|
||||||
|
ccTransaction.setTo(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ccTransaction.setAmount(amount);
|
||||||
|
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.getLabel(), this.cryptoCoin.getCryptoNet().name());
|
||||||
|
if (currency == null) {
|
||||||
|
currency = new CryptoCurrency();
|
||||||
|
currency.setCryptoNet(this.cryptoCoin.getCryptoNet());
|
||||||
|
currency.setName(this.cryptoCoin.getLabel());
|
||||||
|
currency.setPrecision(this.cryptoCoin.getPrecision());
|
||||||
|
long idCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(currency)[0];
|
||||||
|
currency.setId(idCurrency);
|
||||||
|
}
|
||||||
|
|
||||||
|
ccTransaction.setIdCurrency((int) currency.getId());
|
||||||
|
|
||||||
|
long ccId = db.transactionDao().insertTransaction(ccTransaction)[0];
|
||||||
|
btTransaction.setCryptoCoinTransactionId(ccId);
|
||||||
|
long btId = db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction)[0];
|
||||||
|
for (BitcoinTransactionGTxIO gtxio : gtxios) {
|
||||||
|
gtxio.setBitcoinTransactionId(ccId);
|
||||||
|
db.bitcoinTransactionDao().insertBitcoinTransactionGTxIO(gtxio);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ccTransaction.isConfirmed()) {
|
||||||
|
updateBalance(ccTransaction, amount, db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGeneralAccount(CreateBitcoinAccountRequest request){
|
||||||
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
|
||||||
|
CryptoNetAccount account = new CryptoNetAccount();
|
||||||
|
account.setAccountIndex(0);
|
||||||
|
account.setCryptoNet(this.cryptoCoin.getCryptoNet());
|
||||||
|
account.setName(request.getAccountSeed().getName());
|
||||||
|
account.setSeedId(request.getAccountSeed().getId());
|
||||||
|
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(account)[0];
|
||||||
|
account.setId(idAccount);
|
||||||
|
|
||||||
|
loadAccountFromDB(account,request.getContext());
|
||||||
|
request.setStatus(CreateBitcoinAccountRequest.StatusCode.SUCCEEDED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(final GeneralAccountSendRequest request){
|
private void updateBalance(CryptoCoinTransaction ccTransaction, long amount, CrystalDatabase db){
|
||||||
|
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.getLabel(), this.cryptoCoin.getCryptoNet().name());
|
||||||
|
if (currency == null) {
|
||||||
|
currency = new CryptoCurrency();
|
||||||
|
currency.setCryptoNet(this.cryptoCoin.getCryptoNet());
|
||||||
|
currency.setName(this.cryptoCoin.getLabel());
|
||||||
|
currency.setPrecision(this.cryptoCoin.getPrecision());
|
||||||
|
long idCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(currency)[0];
|
||||||
|
currency.setId(idCurrency);
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoCoinBalance balance = db.cryptoCoinBalanceDao().getBalanceFromAccount(ccTransaction.getAccountId(), currency.getId());
|
||||||
|
if (balance == null) {
|
||||||
|
balance = new CryptoCoinBalance();
|
||||||
|
balance.setAccountId(ccTransaction.getAccountId());
|
||||||
|
balance.setCryptoCurrencyId(currency.getId());
|
||||||
|
long idBalance = db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance)[0];
|
||||||
|
balance.setId(idBalance);
|
||||||
|
}
|
||||||
|
balance.setBalance(balance.getBalance()+amount);
|
||||||
|
db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateAddress(ValidateBitcoinAddressRequest request){
|
||||||
|
try{
|
||||||
|
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), request.getAddress());
|
||||||
|
request.setAddressValid(true);
|
||||||
|
}catch(AddressFormatException ex){
|
||||||
|
request.setAddressValid(false);
|
||||||
|
}
|
||||||
|
request.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(final BitcoinSendRequest request){
|
||||||
//TODO check server connection
|
//TODO check server connection
|
||||||
//TODO validate to address
|
//TODO validate to address
|
||||||
|
|
||||||
InsightApiGenerator.getEstimateFee(request.getAccount().getCryptoNet(),new ApiRequest(1, new ApiRequestListener() {
|
System.out.println("GeneralAccount Manager Send request, asking fee");
|
||||||
|
InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() {
|
||||||
@Override
|
@Override
|
||||||
public void success(Object answer, int idPetition) {
|
public void success(Object answer, int idPetition) {
|
||||||
Transaction tx = new Transaction(request.getAccount().getNetworkParam());
|
System.out.println("GeneralAccount Manager Send request, fee " + answer.toString());
|
||||||
long currentAmount = 0;
|
try {
|
||||||
long fee = -1;
|
Transaction tx = new Transaction(cryptoCoin.getParameters());
|
||||||
long feeRate = (Long) answer;
|
long currentAmount = 0;
|
||||||
fee = 226 * feeRate;
|
long fee = -1;
|
||||||
|
long feeRate = (long) (((double) answer) * Math.pow(10, cryptoCoin.getPrecision()));
|
||||||
|
fee = 226 * feeRate;
|
||||||
|
|
||||||
List<GeneralCoinAddress> addresses = request.getAccount().getAddresses();
|
System.out.println("GeneralAccount Manager Send request getting utxos" );
|
||||||
List<GTxIO> utxos = new ArrayList();
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
|
||||||
for(GeneralCoinAddress address : addresses){
|
db.bitcoinTransactionDao();
|
||||||
List<GTxIO> addrUtxos = address.getUTXos();
|
|
||||||
for(GTxIO addrUtxo : addrUtxos){
|
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(), db);
|
||||||
utxos.add(addrUtxo);
|
System.out.println("GeneralAccount Manager Send request utxos found " + utxos.size() );
|
||||||
currentAmount += addrUtxo.getAmount();
|
for(BitcoinTransactionGTxIO utxo : utxos){
|
||||||
if(currentAmount >= request.getAmount()+ fee){
|
currentAmount += utxo.getAmount();
|
||||||
|
if(currentAmount >= request.getAmount() + fee) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(currentAmount >= request.getAmount() + fee){
|
|
||||||
break;
|
if (currentAmount < request.getAmount() + fee) {
|
||||||
|
System.out.println("GeneralAccount Manager Send request no balance" );
|
||||||
|
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId());
|
||||||
|
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
|
||||||
|
new ChildNumber(44, true));
|
||||||
|
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
|
||||||
|
new ChildNumber(cryptoCoin.getCoinNumber(), true));
|
||||||
|
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
|
||||||
|
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
|
||||||
|
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
|
||||||
|
new ChildNumber(0, false));
|
||||||
|
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
|
||||||
|
new ChildNumber(1, false));
|
||||||
|
|
||||||
if(currentAmount< request.getAmount() + fee){
|
//String to an address
|
||||||
request.setStatus(GeneralAccountSendRequest.StatusCode.NO_BALANCE);
|
Address toAddr = Address.fromBase58(cryptoCoin.getParameters(), request.getToAccount());
|
||||||
return;
|
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr);
|
||||||
}
|
|
||||||
|
|
||||||
//String to an address
|
/*if(request.getMemo()!= null && !request.getMemo().isEmpty()){
|
||||||
Address toAddr = Address.fromBase58(request.getAccount().getNetworkParam(), request.getToAccount());
|
|
||||||
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr);
|
|
||||||
|
|
||||||
if(request.getMemo()!= null && !request.getMemo().isEmpty()){
|
|
||||||
String memo = request.getMemo();
|
String memo = request.getMemo();
|
||||||
if(request.getMemo().length()>40){
|
if(request.getMemo().length()>40){
|
||||||
memo = memo.substring(0,40);
|
memo = memo.substring(0,40);
|
||||||
|
@ -99,47 +433,282 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
|
||||||
System.arraycopy(memo.getBytes(),0,scriptByte,2,memo.length());
|
System.arraycopy(memo.getBytes(),0,scriptByte,2,memo.length());
|
||||||
Script memoScript = new Script(scriptByte);
|
Script memoScript = new Script(scriptByte);
|
||||||
tx.addOutput(Coin.valueOf(0),memoScript);
|
tx.addOutput(Coin.valueOf(0),memoScript);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//Change address
|
//Change address
|
||||||
long remain = currentAmount - request.getAmount() - fee;
|
long remain = currentAmount - request.getAmount() - fee;
|
||||||
if( remain > 0 ) {
|
if (remain > 0) {
|
||||||
Address changeAddr = Address.fromBase58(request.getAccount().getNetworkParam(), request.getAccount().getNextChangeAddress());
|
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
|
||||||
tx.addOutput(Coin.valueOf(remain), changeAddr);
|
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());
|
||||||
|
|
||||||
for(GTxIO utxo: utxos) {
|
} else {
|
||||||
Sha256Hash txHash = Sha256Hash.wrap(utxo.getTransaction().getTxid());
|
if (btAddress == null) {
|
||||||
Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
|
index = 0;
|
||||||
TransactionOutPoint outPoint = new TransactionOutPoint(request.getAccount().getNetworkParam(), utxo.getIndex(), txHash);
|
} else {
|
||||||
if(utxo.getAddress().getKey().isPubKeyOnly()){
|
index++;
|
||||||
if(utxo.getAddress().isIsChange()){
|
}
|
||||||
utxo.getAddress().setKey(HDKeyDerivation.deriveChildKey(request.getAccount().getChangeKey(), new ChildNumber(utxo.getAddress().getIndex(), false)));
|
btAddress = new BitcoinAddress();
|
||||||
}else{
|
btAddress.setIndex(index);
|
||||||
utxo.getAddress().setKey(HDKeyDerivation.deriveChildKey(request.getAccount().getExternalKey(), new ChildNumber(utxo.getAddress().getIndex(), false)));
|
btAddress.setAccountId(request.getSourceAccount().getId());
|
||||||
|
btAddress.setChange(true);
|
||||||
|
btAddress.setAddress(HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)).toAddress(cryptoCoin.getParameters()).toString());
|
||||||
|
db.bitcoinAddressDao().insertBitcoinAddresses(btAddress);
|
||||||
|
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
|
||||||
|
}
|
||||||
|
tx.addOutput(Coin.valueOf(remain), changeAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BitcoinTransactionGTxIO utxo : utxos) {
|
||||||
|
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId());
|
||||||
|
Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
|
||||||
|
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash);
|
||||||
|
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress());
|
||||||
|
ECKey addrKey;
|
||||||
|
|
||||||
|
if (btAddress.isChange()) {
|
||||||
|
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
|
||||||
|
} else {
|
||||||
|
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
|
||||||
|
}
|
||||||
|
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
|
||||||
|
currentAmount -= utxo.getAmount();
|
||||||
|
if(currentAmount<= 0){
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tx.addSignedInput(outPoint, script, utxo.getAddress().getKey(), Transaction.SigHash.ALL, true);
|
|
||||||
|
System.out.println("GeneralAccount Manager Send request rawtx " +Util.bytesToHex(tx.bitcoinSerialize()) );
|
||||||
|
InsightApiGenerator.broadcastTransaction(cryptoCoin, Util.bytesToHex(tx.bitcoinSerialize()), new ApiRequest(1, new ApiRequestListener() {
|
||||||
|
@Override
|
||||||
|
public void success(Object answer, int idPetition) {
|
||||||
|
System.out.println("GeneralAccount MAnager succed send");
|
||||||
|
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fail(int idPetition) {
|
||||||
|
System.out.println("GeneralAccount MAnager succed fail");
|
||||||
|
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("GeneralAccount Manager Send request error ");
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
InsightApiGenerator.broadcastTransaction(request.getAccount().getCryptoNet(),Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
|
|
||||||
@Override
|
|
||||||
public void success(Object answer, int idPetition) {
|
|
||||||
request.setStatus(GeneralAccountSendRequest.StatusCode.SUCCEEDED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fail(int idPetition) {
|
|
||||||
request.setStatus(GeneralAccountSendRequest.StatusCode.PETITION_FAILED);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fail(int idPetition) {
|
public void fail(int idPetition) {
|
||||||
request.setStatus(GeneralAccountSendRequest.StatusCode.NO_FEE);
|
System.out.println("GeneralAccount Manager Send request fee fail" );
|
||||||
|
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
|
||||||
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void getNextAddress(NextBitcoinAccountAddressRequest request){
|
||||||
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
|
||||||
|
long index = db.bitcoinAddressDao().getLastExternalAddress(request.getAccount().getId());
|
||||||
|
BitcoinAddress address = db.bitcoinAddressDao().getExternalByIndex(index);
|
||||||
|
if(address != null && db.bitcoinTransactionDao().getGtxIOByAddress(address.getAddress()).size()<=0){
|
||||||
|
request.setAddress(address.getAddress());
|
||||||
|
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
|
||||||
|
}else {
|
||||||
|
index++;
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().getSeedId());
|
||||||
|
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
|
||||||
|
new ChildNumber(44, true));
|
||||||
|
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
|
||||||
|
new ChildNumber(cryptoCoin.getCoinNumber(), true));
|
||||||
|
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
|
||||||
|
new ChildNumber(request.getAccount().getAccountIndex(), true));
|
||||||
|
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
|
||||||
|
new ChildNumber(0, false));
|
||||||
|
ECKey addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) index, true));
|
||||||
|
address = new BitcoinAddress();
|
||||||
|
address.setChange(false);
|
||||||
|
address.setAccountId(request.getAccount().getId());
|
||||||
|
address.setIndex(index);
|
||||||
|
String addressString = addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
|
||||||
|
address.setAddress(addressString);
|
||||||
|
db.bitcoinAddressDao().insertBitcoinAddresses(address);
|
||||||
|
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin, addressString, true, null);
|
||||||
|
|
||||||
|
request.setAddress(addressString);
|
||||||
|
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateUri(CalculateBitcoinUriRequest request) {
|
||||||
|
StringBuilder uri = new StringBuilder(this.cryptoCoin.name().toLowerCase()+":");
|
||||||
|
|
||||||
|
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
|
||||||
|
long index = db.bitcoinAddressDao().getLastExternalAddress(request.getAccount().getId());
|
||||||
|
BitcoinAddress address = db.bitcoinAddressDao().getExternalByIndex(index);
|
||||||
|
if(address != null && db.bitcoinTransactionDao().getGtxIOByAddress(address.getAddress()).size()<=0){
|
||||||
|
uri.append(address.getAddress());
|
||||||
|
}else {
|
||||||
|
index++;
|
||||||
|
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().getSeedId());
|
||||||
|
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
|
||||||
|
new ChildNumber(44, true));
|
||||||
|
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
|
||||||
|
new ChildNumber(cryptoCoin.getCoinNumber(), true));
|
||||||
|
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
|
||||||
|
new ChildNumber(request.getAccount().getAccountIndex(), true));
|
||||||
|
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
|
||||||
|
new ChildNumber(0, false));
|
||||||
|
ECKey addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) index, true));
|
||||||
|
address = new BitcoinAddress();
|
||||||
|
address.setChange(false);
|
||||||
|
address.setAccountId(request.getAccount().getId());
|
||||||
|
address.setIndex(index);
|
||||||
|
String addressString = addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
|
||||||
|
address.setAddress(addressString);
|
||||||
|
db.bitcoinAddressDao().insertBitcoinAddresses(address);
|
||||||
|
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin, addressString, true, null);
|
||||||
|
|
||||||
|
uri.append(address.getAddress());
|
||||||
|
}
|
||||||
|
if(request.getAmount() > 0 ){
|
||||||
|
uri.append("?amount=");
|
||||||
|
uri.append(Double.toString(request.getAmount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("GeneralAccountMAnager uri calculated : " + uri.toString());
|
||||||
|
|
||||||
|
request.setUri(uri.toString());
|
||||||
|
//request.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseUri(BitcoinUriParseRequest request){
|
||||||
|
String uri = request.getUri();
|
||||||
|
if(uri.indexOf(":")>0){
|
||||||
|
String cryptoNet = uri.substring(0,uri.indexOf(":"));
|
||||||
|
if(cryptoNet.equalsIgnoreCase(this.cryptoCoin.name().toLowerCase())){
|
||||||
|
try{
|
||||||
|
int parameterIndex =uri.indexOf("?");
|
||||||
|
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), uri.substring(uri.indexOf(":")+1,parameterIndex>0?parameterIndex:uri.length()));
|
||||||
|
request.setAddress(address.toString());
|
||||||
|
request.setStatus(BitcoinUriParseRequest.StatusCode.VALID);
|
||||||
|
if(parameterIndex>0){
|
||||||
|
try {
|
||||||
|
String[] parameters = uri.substring(parameterIndex + 1).split("&");
|
||||||
|
for (String parameter : parameters) {
|
||||||
|
int idx = parameter.indexOf("=");
|
||||||
|
if (idx > 0 && parameter.substring(0, idx).equalsIgnoreCase("amount")) {
|
||||||
|
request.setAmount(Double.parseDouble(parameter.substring(idx + 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(Exception ignored){}
|
||||||
|
}
|
||||||
|
}catch(AddressFormatException ex){
|
||||||
|
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
int parameterIndex =uri.indexOf("?");
|
||||||
|
if(parameterIndex>0){
|
||||||
|
try{
|
||||||
|
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), uri.substring(uri.indexOf(":")+1,parameterIndex>0?parameterIndex:uri.length()));
|
||||||
|
request.setAddress(address.toString());
|
||||||
|
request.setStatus(BitcoinUriParseRequest.StatusCode.VALID);
|
||||||
|
try{
|
||||||
|
String[] parameters = uri.substring(parameterIndex+1).split("&");
|
||||||
|
for(String parameter : parameters){
|
||||||
|
int idx = parameter.indexOf("=");
|
||||||
|
if(idx > 0 && parameter.substring(0,idx).equalsIgnoreCase("amount")){
|
||||||
|
request.setAmount(Double.parseDouble(parameter.substring(idx+1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(Exception ignored){}
|
||||||
|
|
||||||
|
}catch(AddressFormatException ex){
|
||||||
|
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
Address address = Address.fromBase58(this.cryptoCoin.getParameters(), uri);
|
||||||
|
request.setAddress(address.toString());
|
||||||
|
request.setStatus(BitcoinUriParseRequest.StatusCode.VALID);
|
||||||
|
|
||||||
|
}catch(AddressFormatException ex){
|
||||||
|
request.setStatus(BitcoinUriParseRequest.StatusCode.NOT_VALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BitcoinTransactionGTxIO> getUtxos(long accountId, CrystalDatabase db){
|
||||||
|
List<BitcoinTransactionGTxIO> answer = new ArrayList<>();
|
||||||
|
List<BitcoinTransactionGTxIO> bTGTxI = new ArrayList<>();
|
||||||
|
List<BitcoinTransactionGTxIO> bTGTxO = new ArrayList<>();
|
||||||
|
List<CryptoCoinTransaction> ccTransactions = db.transactionDao().getByIdAccount(accountId);
|
||||||
|
for(CryptoCoinTransaction ccTransaction : ccTransactions) {
|
||||||
|
List<BitcoinTransactionGTxIO> gtxios = db.bitcoinTransactionDao().getGtxIOByTransaction(ccTransaction.getId());
|
||||||
|
for(BitcoinTransactionGTxIO gtxio : gtxios){
|
||||||
|
if(db.bitcoinAddressDao().addressExists(gtxio.getAddress())){
|
||||||
|
if(gtxio.isOutput()){
|
||||||
|
bTGTxO.add(gtxio);
|
||||||
|
}else{
|
||||||
|
bTGTxI.add(gtxio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(BitcoinTransactionGTxIO gtxi : bTGTxI){
|
||||||
|
boolean find = false;
|
||||||
|
for(BitcoinTransactionGTxIO gtxo : bTGTxO){
|
||||||
|
if(gtxo.getOriginalTxId().equals(gtxi.getOriginalTxId())){
|
||||||
|
find = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!find){
|
||||||
|
answer.add(gtxi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CheckAddressForTransaction implements InsightApiGenerator.HasTransactionListener{
|
||||||
|
BitcoinAddressDao bitcoinAddressDao;
|
||||||
|
long idAccount;
|
||||||
|
DeterministicKey addressKey;
|
||||||
|
boolean isChange;
|
||||||
|
int lastIndex;
|
||||||
|
|
||||||
|
public CheckAddressForTransaction(BitcoinAddressDao bitcoinAddressDao, long idAccount, DeterministicKey addressKey, boolean isChange, int lastIndex) {
|
||||||
|
this.bitcoinAddressDao = bitcoinAddressDao;
|
||||||
|
this.idAccount = idAccount;
|
||||||
|
this.addressKey = addressKey;
|
||||||
|
this.isChange = isChange;
|
||||||
|
this.lastIndex = lastIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hasTransaction(boolean value) {
|
||||||
|
if(value){
|
||||||
|
|
||||||
|
ECKey externalAddrKey = HDKeyDerivation.deriveChildKey(addressKey, new ChildNumber(lastIndex+1, true));
|
||||||
|
BitcoinAddress address = new BitcoinAddress();
|
||||||
|
address.setChange(isChange);
|
||||||
|
address.setAccountId(idAccount);
|
||||||
|
address.setIndex(lastIndex+1);
|
||||||
|
String addressString =externalAddrKey.toAddress(cryptoCoin.getParameters()).toString();
|
||||||
|
address.setAddress(addressString);
|
||||||
|
bitcoinAddressDao.insertBitcoinAddresses(address);
|
||||||
|
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
|
||||||
|
new CheckAddressForTransaction(bitcoinAddressDao,idAccount,addressKey,isChange,lastIndex+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,756 @@
|
||||||
|
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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,12 +9,14 @@ import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.util.DiffUtil;
|
import android.support.v7.util.DiffUtil;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Base58;
|
||||||
import org.bitcoinj.core.ECKey;
|
import org.bitcoinj.core.ECKey;
|
||||||
import org.bitcoinj.crypto.HDKeyDerivation;
|
import org.bitcoinj.crypto.HDKeyDerivation;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.enums.SeedType;
|
import cy.agorise.crystalwallet.enums.SeedType;
|
||||||
import cy.agorise.crystalwallet.models.seed.BIP39;
|
import cy.agorise.crystalwallet.models.seed.BIP39;
|
||||||
|
@ -115,8 +117,6 @@ public class AccountSeed {
|
||||||
BufferedReader reader = null;
|
BufferedReader reader = null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BRAINKEY:
|
case BRAINKEY:
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("brainkeydict.txt"), "UTF-8"));
|
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("brainkeydict.txt"), "UTF-8"));
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ public class AccountSeed {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case BIP39:
|
case BIP39:
|
||||||
try {
|
try {
|
||||||
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("bip39dict.txt"), "UTF-8"));
|
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("bip39dict.txt"), "UTF-8"));
|
||||||
|
@ -139,6 +140,7 @@ public class AccountSeed {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -149,6 +151,15 @@ public class AccountSeed {
|
||||||
return new BrainKey(this.mMasterSeed,0).getPrivateKey();
|
return new BrainKey(this.mMasterSeed,0).getPrivateKey();
|
||||||
case BIP39:
|
case BIP39:
|
||||||
return HDKeyDerivation.createMasterPrivateKey(new BIP39(mId, mMasterSeed).getSeed());
|
return HDKeyDerivation.createMasterPrivateKey(new BIP39(mId, mMasterSeed).getSeed());
|
||||||
|
case WIF:
|
||||||
|
byte[] decoded = Base58.decode(this.mMasterSeed);
|
||||||
|
byte[] privKey = Arrays.copyOfRange(decoded, 1, decoded.length - 4);
|
||||||
|
byte[] checksum = Arrays.copyOfRange(decoded, decoded.length - 4, decoded.length);
|
||||||
|
//TODO calculate chekcsum
|
||||||
|
while(privKey.length>32){
|
||||||
|
privKey = Arrays.copyOfRange(privKey,0,privKey.length-1);
|
||||||
|
}
|
||||||
|
return ECKey.fromPrivate(privKey);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo;
|
||||||
|
import android.arch.persistence.room.Entity;
|
||||||
|
import android.arch.persistence.room.ForeignKey;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Bitcoin derivated address
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/17/2018.
|
||||||
|
*/
|
||||||
|
@Entity(
|
||||||
|
tableName="bitcoin_address",
|
||||||
|
primaryKeys = {"account_id","address_index","is_change"},
|
||||||
|
foreignKeys = {
|
||||||
|
@ForeignKey(
|
||||||
|
entity = CryptoNetAccount.class,
|
||||||
|
parentColumns = "id",
|
||||||
|
childColumns = "account_id",
|
||||||
|
onDelete = ForeignKey.CASCADE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class BitcoinAddress {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the account associated
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="account_id")
|
||||||
|
protected long accountId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of this address
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="address_index")
|
||||||
|
@NonNull protected long index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not this address is a change one
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="is_change")
|
||||||
|
@NonNull protected boolean isChange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="address")
|
||||||
|
@NonNull protected String address;
|
||||||
|
|
||||||
|
public BitcoinAddress(long accountId, @NonNull long index, boolean isChange, String address) {
|
||||||
|
this.accountId = accountId;
|
||||||
|
this.index = index;
|
||||||
|
this.isChange = isChange;
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitcoinAddress() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountId(long accountId) {
|
||||||
|
this.accountId = accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public long getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(@NonNull long index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChange() {
|
||||||
|
return isChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChange(boolean change) {
|
||||||
|
isChange = change;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo;
|
||||||
|
import android.arch.persistence.room.Entity;
|
||||||
|
import android.arch.persistence.room.ForeignKey;
|
||||||
|
import android.arch.persistence.room.Ignore;
|
||||||
|
import android.arch.persistence.room.Index;
|
||||||
|
import android.arch.persistence.room.PrimaryKey;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.util.DiffUtil;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Bitcoin alike Transaction
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/2/2018.
|
||||||
|
*/
|
||||||
|
@Entity(
|
||||||
|
tableName="bitcoin_transaction",
|
||||||
|
primaryKeys = {"crypto_coin_transaction_id"},
|
||||||
|
foreignKeys = {
|
||||||
|
@ForeignKey(
|
||||||
|
entity = CryptoCoinTransaction.class,
|
||||||
|
parentColumns = "id",
|
||||||
|
childColumns = "crypto_coin_transaction_id",
|
||||||
|
onDelete = ForeignKey.CASCADE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class BitcoinTransaction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the base transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="crypto_coin_transaction_id")
|
||||||
|
protected long cryptoCoinTransactionId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The transaction id in the blockchain
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="tx_id")
|
||||||
|
@NonNull protected String txId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The block id in the blockchain
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="block")
|
||||||
|
protected long block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fee of the transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="fee")
|
||||||
|
protected long fee;
|
||||||
|
/**
|
||||||
|
* The confirmations of the transaction in the blockchain
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="confirmations")
|
||||||
|
protected int confirmations;
|
||||||
|
|
||||||
|
public BitcoinTransaction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitcoinTransaction(long cryptoCoinTransactionId, String txId, long block, long fee, int confirmations) {
|
||||||
|
this.cryptoCoinTransactionId = cryptoCoinTransactionId;
|
||||||
|
this.txId = txId;
|
||||||
|
this.block = block;
|
||||||
|
this.fee = fee;
|
||||||
|
this.confirmations = confirmations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCryptoCoinTransactionId() {
|
||||||
|
return cryptoCoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCryptoCoinTransactionId(long cryptoCoinTransactionId) {
|
||||||
|
this.cryptoCoinTransactionId = cryptoCoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTxId() {
|
||||||
|
return txId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTxId(String txId) {
|
||||||
|
this.txId = txId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBlock() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlock(long block) {
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFee() {
|
||||||
|
return fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFee(long fee) {
|
||||||
|
this.fee = fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConfirmations() {
|
||||||
|
return confirmations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfirmations(int confirmations) {
|
||||||
|
this.confirmations = confirmations;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo;
|
||||||
|
import android.arch.persistence.room.Embedded;
|
||||||
|
import android.arch.persistence.room.Entity;
|
||||||
|
import android.arch.persistence.room.ForeignKey;
|
||||||
|
import android.arch.persistence.room.Relation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Bitcoin alike Transaction
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/2/2018.
|
||||||
|
*/
|
||||||
|
public class BitcoinTransactionExtended {
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
public CryptoCoinTransaction cryptoCoinTransaction;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
public BitcoinTransaction bitcoinTransaction;
|
||||||
|
|
||||||
|
@Relation(parentColumn = "id", entityColumn = "bitcoin_transaction_id", entity = BitcoinTransactionGTxIO.class)
|
||||||
|
public List<BitcoinTransactionGTxIO> bitcoinTransactionGTxIOList;
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.arch.persistence.room.ColumnInfo;
|
||||||
|
import android.arch.persistence.room.Entity;
|
||||||
|
import android.arch.persistence.room.ForeignKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Bitcoin alike Transaction Inputs and Outputs
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/2/2018.
|
||||||
|
*/
|
||||||
|
@Entity(
|
||||||
|
tableName="bitcoin_transaction_gt_io",
|
||||||
|
primaryKeys = {"bitcoin_transaction_id", "io_index", "is_output"},
|
||||||
|
foreignKeys = {
|
||||||
|
@ForeignKey(
|
||||||
|
entity = CryptoCoinTransaction.class,
|
||||||
|
parentColumns = "id",
|
||||||
|
childColumns = "bitcoin_transaction_id",
|
||||||
|
onDelete = ForeignKey.CASCADE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class BitcoinTransactionGTxIO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the bitcoin transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="bitcoin_transaction_id")
|
||||||
|
protected long bitcoinTransactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index in the transaction
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="io_index")
|
||||||
|
protected int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The address of the input or output
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="address")
|
||||||
|
protected String address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines if this is an input or output
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name="is_output")
|
||||||
|
protected boolean isOutput;
|
||||||
|
|
||||||
|
@ColumnInfo(name="amount")
|
||||||
|
protected long amount;
|
||||||
|
|
||||||
|
@ColumnInfo(name="script_hex")
|
||||||
|
protected String scriptHex;
|
||||||
|
|
||||||
|
@ColumnInfo(name="original_txid")
|
||||||
|
protected String originalTxId;
|
||||||
|
|
||||||
|
public BitcoinTransactionGTxIO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitcoinTransactionGTxIO(long bitcoinTransactionId, int index, String address, boolean isOutput) {
|
||||||
|
this.bitcoinTransactionId = bitcoinTransactionId;
|
||||||
|
this.index = index;
|
||||||
|
this.address = address;
|
||||||
|
this.isOutput = isOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBitcoinTransactionId() {
|
||||||
|
return bitcoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitcoinTransactionId(long bitcoinTransactionId) {
|
||||||
|
this.bitcoinTransactionId = bitcoinTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOutput() {
|
||||||
|
return isOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutput(boolean output) {
|
||||||
|
isOutput = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getScriptHex() {
|
||||||
|
return scriptHex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScriptHex(String scriptHex) {
|
||||||
|
this.scriptHex = scriptHex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOriginalTxId() {
|
||||||
|
return originalTxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOriginalTxId(String originalTxId) {
|
||||||
|
this.originalTxId = originalTxId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,9 +20,13 @@ import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
*/
|
*/
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName="crypto_coin_transaction",
|
tableName="crypto_coin_transaction",
|
||||||
|
primaryKeys = {
|
||||||
|
|
||||||
|
},
|
||||||
indices={
|
indices={
|
||||||
@Index(value={"account_id"}),
|
@Index(value={"account_id"}),
|
||||||
@Index(value={"id_currency"})
|
@Index(value={"id_currency"}),
|
||||||
|
@Index(value={"date", "account_id", "id_currency", "from", "to"},unique=true)
|
||||||
},
|
},
|
||||||
foreignKeys = {
|
foreignKeys = {
|
||||||
@ForeignKey(
|
@ForeignKey(
|
||||||
|
@ -66,7 +70,7 @@ public class CryptoCoinTransaction {
|
||||||
* The id of the account assoiciated, this is used for the foreign key definition
|
* The id of the account assoiciated, this is used for the foreign key definition
|
||||||
*/
|
*/
|
||||||
@ColumnInfo(name="account_id")
|
@ColumnInfo(name="account_id")
|
||||||
protected long accountId;
|
protected long accountId = -1;
|
||||||
/**
|
/**
|
||||||
* The amount of asset is moved in this transaction
|
* The amount of asset is moved in this transaction
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -45,6 +45,15 @@ public class CryptoCurrency {
|
||||||
@ColumnInfo(name = "precision")
|
@ColumnInfo(name = "precision")
|
||||||
private int mPrecision;
|
private int mPrecision;
|
||||||
|
|
||||||
|
public CryptoCurrency() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CryptoCurrency(String name, CryptoNet cryptoNet, int precision) {
|
||||||
|
this.mName = name;
|
||||||
|
this.mCryptoNet = cryptoNet;
|
||||||
|
this.mPrecision = precision;
|
||||||
|
}
|
||||||
|
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return mId;
|
return mId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package cy.agorise.crystalwallet.models;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.util.DiffUtil;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
|
||||||
|
public class CryptoNetSelection {
|
||||||
|
CryptoNet cryptoNet;
|
||||||
|
Boolean selected;
|
||||||
|
|
||||||
|
public CryptoNetSelection(CryptoNet cryptoNet, Boolean selected) {
|
||||||
|
this.cryptoNet = cryptoNet;
|
||||||
|
this.selected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CryptoNet getCryptoNet() {
|
||||||
|
return cryptoNet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCryptoNet(CryptoNet cryptoNet) {
|
||||||
|
this.cryptoNet = cryptoNet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getSelected() {
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelected(Boolean selected) {
|
||||||
|
this.selected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final DiffUtil.ItemCallback<CryptoNetSelection> DIFF_CALLBACK = new DiffUtil.ItemCallback<CryptoNetSelection>() {
|
||||||
|
@Override
|
||||||
|
public boolean areItemsTheSame(
|
||||||
|
@NonNull CryptoNetSelection oldCryptoNetSelection, @NonNull CryptoNetSelection newCryptoNetSelection) {
|
||||||
|
return oldCryptoNetSelection.getCryptoNet() == newCryptoNetSelection.getCryptoNet();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean areContentsTheSame(
|
||||||
|
@NonNull CryptoNetSelection oldCryptoNetSelection, @NonNull CryptoNetSelection newCryptoNetSelection) {
|
||||||
|
return oldCryptoNetSelection.equals(newCryptoNetSelection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -31,9 +31,16 @@ public class GrapheneAccount extends CryptoNetAccount {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadInfo(GrapheneAccountInfo info){
|
public void loadInfo(GrapheneAccountInfo info){
|
||||||
this.name = info.getName();
|
if(info != null){
|
||||||
this.accountId = info.getAccountId();
|
this.name = info.getName();
|
||||||
this.upgradedToLtm = info.getUpgradedToLtm();
|
this.accountId = info.getAccountId();
|
||||||
|
this.upgradedToLtm = info.getUpgradedToLtm();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this.name = "";
|
||||||
|
this.accountId = "-1";
|
||||||
|
this.upgradedToLtm = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package cy.agorise.crystalwallet.network;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.apigenerator.insightapi.GetGenesisBlock;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
|
||||||
|
public class BitcoinCryptoNetVerifier extends CryptoNetVerifier{
|
||||||
|
|
||||||
|
final CryptoCoin cryptoCoin;
|
||||||
|
|
||||||
|
public BitcoinCryptoNetVerifier(CryptoCoin cryptoCoin) {
|
||||||
|
this.cryptoCoin = cryptoCoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkURL(final String url) {
|
||||||
|
|
||||||
|
final long startTime = System.currentTimeMillis();
|
||||||
|
GetGenesisBlock genesisBloc = new GetGenesisBlock(url, new GetGenesisBlock.genesisBlockListener() {
|
||||||
|
@Override
|
||||||
|
public void genesisBlock(String value) {
|
||||||
|
if(cryptoCoin.getParameters()!= null){
|
||||||
|
if(value.equals(cryptoCoin.getParameters().getGenesisBlock().getHashAsString())){
|
||||||
|
|
||||||
|
CryptoNetManager.verifiedCryptoNetURL(cryptoCoin.getCryptoNet(), url, System.currentTimeMillis() - startTime);
|
||||||
|
}else{
|
||||||
|
System.out.println("BitcoinCryptoNetVerifier bad genesis block " + value + " " + url);
|
||||||
|
}
|
||||||
|
//TODO bad genesis block
|
||||||
|
}else{
|
||||||
|
CryptoNetManager.verifiedCryptoNetURL(cryptoCoin.getCryptoNet(), url, System.currentTimeMillis() - startTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fail() {
|
||||||
|
//TODO failed
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getChainId() {
|
||||||
|
if(cryptoCoin == null || cryptoCoin.getParameters()== null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return cryptoCoin.getParameters().getGenesisBlock().getHashAsString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,6 @@ public abstract class CryptoNetManager {
|
||||||
|
|
||||||
public static String getURL(CryptoNet crypto, int index){
|
public static String getURL(CryptoNet crypto, int index){
|
||||||
if(TestedURLs.containsKey(crypto) && TestedURLs.get(crypto).size()>index){
|
if(TestedURLs.containsKey(crypto) && TestedURLs.get(crypto).size()>index){
|
||||||
System.out.println("Servers url list " + Arrays.toString(TestedURLs.get(crypto).toArray()));
|
|
||||||
return TestedURLs.get(crypto).get(index).getUrl();
|
return TestedURLs.get(crypto).get(index).getUrl();
|
||||||
}
|
}
|
||||||
System.out.println("Servers " + crypto.getLabel()+" dioesn't have testedurl");
|
System.out.println("Servers " + crypto.getLabel()+" dioesn't have testedurl");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cy.agorise.crystalwallet.network;
|
package cy.agorise.crystalwallet.network;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.enums.CryptoNet;
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +16,10 @@ public abstract class CryptoNetVerifier {
|
||||||
static CryptoNetVerifier getNetworkVerify(CryptoNet cryptoNet){
|
static CryptoNetVerifier getNetworkVerify(CryptoNet cryptoNet){
|
||||||
if(cryptoNet.getLabel().equals(CryptoNet.BITSHARES.getLabel())){
|
if(cryptoNet.getLabel().equals(CryptoNet.BITSHARES.getLabel())){
|
||||||
return new BitsharesCryptoNetVerifier();
|
return new BitsharesCryptoNetVerifier();
|
||||||
|
}else if(cryptoNet.getLabel().equals(CryptoNet.BITCOIN.getLabel())){
|
||||||
|
return new BitcoinCryptoNetVerifier(CryptoCoin.BITCOIN);
|
||||||
|
}else if(cryptoNet.getLabel().equals(CryptoNet.STEEM.getLabel())){
|
||||||
|
return new SteemCryptoNetVerifier();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ public class GetChainId extends BaseGrapheneHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
||||||
System.out.println("<<< "+frame.getPayloadText());
|
|
||||||
String response = frame.getPayloadText();
|
String response = frame.getPayloadText();
|
||||||
|
|
||||||
Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType();
|
Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType();
|
||||||
|
@ -55,7 +54,5 @@ public class GetChainId extends BaseGrapheneHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
||||||
if(frame.isTextFrame())
|
|
||||||
System.out.println(">>> "+frame.getPayloadText());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package cy.agorise.crystalwallet.network;
|
||||||
|
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.neovisionaries.ws.client.WebSocket;
|
||||||
|
import com.neovisionaries.ws.client.WebSocketFrame;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import cy.agorise.graphenej.RPC;
|
||||||
|
import cy.agorise.graphenej.api.BaseGrapheneHandler;
|
||||||
|
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
|
||||||
|
import cy.agorise.graphenej.models.ApiCall;
|
||||||
|
import cy.agorise.graphenej.models.WitnessResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by henry on 28/2/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GetDatabaseVersion extends BaseGrapheneHandler {
|
||||||
|
|
||||||
|
private final WitnessResponseListener mListener;
|
||||||
|
|
||||||
|
public GetDatabaseVersion(WitnessResponseListener listener) {
|
||||||
|
super(listener);
|
||||||
|
this.mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
|
||||||
|
ApiCall getAccountByName = new ApiCall(0, "database_api.get_version", new ArrayList<Serializable>(), RPC.VERSION, 1);
|
||||||
|
websocket.sendText(getAccountByName.toJsonString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
||||||
|
String response = frame.getPayloadText();
|
||||||
|
|
||||||
|
Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType();
|
||||||
|
GsonBuilder builder = new GsonBuilder();
|
||||||
|
WitnessResponse<VersionResponse> witnessResponse = builder.create().fromJson(response, GetChainIdResponse);
|
||||||
|
if(witnessResponse.error != null){
|
||||||
|
this.mListener.onError(witnessResponse.error);
|
||||||
|
}else{
|
||||||
|
this.mListener.onSuccess(witnessResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
websocket.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VersionResponse{
|
||||||
|
public String blockchain_version;
|
||||||
|
public String steem_revision;
|
||||||
|
public String fc_revision;
|
||||||
|
public String chain_id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package cy.agorise.crystalwallet.network;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
|
||||||
|
import cy.agorise.graphenej.models.BaseResponse;
|
||||||
|
import cy.agorise.graphenej.models.WitnessResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Created by henry on 28/2/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SteemCryptoNetVerifier extends CryptoNetVerifier {
|
||||||
|
private final CryptoNet cryptoNet = CryptoNet.STEEM;
|
||||||
|
private final String CHAIN_ID = "0000000000000000000000000000000000000000000000000000000000000000";//mainnet
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkURL(final String url) {
|
||||||
|
final long startTime = System.currentTimeMillis();
|
||||||
|
WebSocketThread thread = new WebSocketThread(new GetChainId(new WitnessResponseListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(WitnessResponse response) {
|
||||||
|
if(response.result instanceof GetDatabaseVersion.VersionResponse) {
|
||||||
|
GetDatabaseVersion.VersionResponse result = (GetDatabaseVersion.VersionResponse) response.result;
|
||||||
|
if(result.chain_id.equals(CHAIN_ID)) {
|
||||||
|
CryptoNetManager.verifiedCryptoNetURL(cryptoNet, url, System.currentTimeMillis() - startTime);
|
||||||
|
}else{
|
||||||
|
System.out.println(" BitsharesCryptoNetVerifier Error we are not in the net current chain id " + result.chain_id + " excepted " + CHAIN_ID);
|
||||||
|
//TODO handle error bad chain
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//TODO handle error bad answer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(BaseResponse.Error error) {
|
||||||
|
//TODO handle error
|
||||||
|
System.out.println("Bad server response " + url);
|
||||||
|
}
|
||||||
|
}),url);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getChainId() {
|
||||||
|
return CHAIN_ID;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,16 @@ package cy.agorise.crystalwallet.requestmanagers;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.models.GeneralCoinAccount;
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
import cy.agorise.crystalwallet.models.GrapheneAccount;
|
||||||
|
|
||||||
public class GeneralAccountSendRequest extends CryptoNetInfoRequest {
|
/**
|
||||||
|
* Class used to make a send amount request.
|
||||||
|
*
|
||||||
|
* Created by henry on 8/10/2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BitcoinSendRequest extends CryptoNetInfoRequest {
|
||||||
/**
|
/**
|
||||||
* The status code of this request
|
* The status code of this request
|
||||||
*/
|
*/
|
||||||
|
@ -14,45 +21,48 @@ public class GeneralAccountSendRequest extends CryptoNetInfoRequest {
|
||||||
SUCCEEDED,
|
SUCCEEDED,
|
||||||
NO_INTERNET,
|
NO_INTERNET,
|
||||||
NO_SERVER_CONNECTION,
|
NO_SERVER_CONNECTION,
|
||||||
BAD_TO_ADDRESS,
|
|
||||||
NO_FEE,
|
|
||||||
NO_BALANCE,
|
NO_BALANCE,
|
||||||
|
NO_FEE,
|
||||||
PETITION_FAILED
|
PETITION_FAILED
|
||||||
}
|
}
|
||||||
|
|
||||||
// The app context
|
// The app context
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
//The soruce Account
|
// The source account used to transfer fund from
|
||||||
private GeneralCoinAccount mAccount;
|
private CryptoNetAccount mSourceAccount;
|
||||||
// The destination account address
|
// The destination account id
|
||||||
private String mToAccount;
|
private String mToAccount;
|
||||||
// The amount of the transaction
|
// The amount of the transaction
|
||||||
private long mAmount;
|
private long mAmount;
|
||||||
|
// The asset id of the transaction
|
||||||
|
private CryptoCoin mCryptoCoin;
|
||||||
// The memo, can be null
|
// The memo, can be null
|
||||||
private String mMemo;
|
private String mMemo;
|
||||||
// The state of this request
|
// The state of this request
|
||||||
private StatusCode status = StatusCode.NOT_STARTED;
|
private StatusCode status = StatusCode.NOT_STARTED;
|
||||||
|
|
||||||
public GeneralAccountSendRequest(CryptoCoin coin, Context context, GeneralCoinAccount account, String toAccount, long amount, String memo) {
|
public BitcoinSendRequest(Context context, CryptoNetAccount sourceAccount,
|
||||||
super(coin);
|
String toAccount, long amount, CryptoCoin cryptoCoin, String memo) {
|
||||||
|
super(cryptoCoin);
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
this.mAccount = account;
|
this.mSourceAccount = sourceAccount;
|
||||||
this.mToAccount = toAccount;
|
this.mToAccount = toAccount;
|
||||||
this.mAmount = amount;
|
this.mAmount = amount;
|
||||||
|
this.mCryptoCoin = cryptoCoin;
|
||||||
this.mMemo = memo;
|
this.mMemo = memo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneralAccountSendRequest(CryptoCoin coin, Context context, GeneralCoinAccount account, String toAccount, long amount) {
|
public BitcoinSendRequest(Context context, GrapheneAccount sourceAccount,
|
||||||
this(coin,context,account,toAccount,amount,null);
|
String toAccount, long amount, CryptoCoin cryptoCoin) {
|
||||||
|
this(context, sourceAccount,toAccount,amount,cryptoCoin,null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
return mContext;
|
return mContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneralCoinAccount getAccount() {
|
public CryptoNetAccount getSourceAccount() {
|
||||||
return mAccount;
|
return mSourceAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getToAccount() {
|
public String getToAccount() {
|
||||||
|
@ -63,6 +73,10 @@ public class GeneralAccountSendRequest extends CryptoNetInfoRequest {
|
||||||
return mAmount;
|
return mAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CryptoCoin getCryptoCoin() {
|
||||||
|
return mCryptoCoin;
|
||||||
|
}
|
||||||
|
|
||||||
public String getMemo() {
|
public String getMemo() {
|
||||||
return mMemo;
|
return mMemo;
|
||||||
}
|
}
|
||||||
|
@ -75,11 +89,10 @@ public class GeneralAccountSendRequest extends CryptoNetInfoRequest {
|
||||||
|
|
||||||
public void setStatus(StatusCode code){
|
public void setStatus(StatusCode code){
|
||||||
this.status = code;
|
this.status = code;
|
||||||
this._fireOnCarryOutEvent();
|
this.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatusCode getStatus() {
|
public StatusCode getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package cy.agorise.crystalwallet.requestmanagers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
import cy.agorise.crystalwallet.models.GrapheneAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to make a bitcoin uri parse request.
|
||||||
|
*
|
||||||
|
* Created by henry on 11/13/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BitcoinUriParseRequest extends CryptoNetInfoRequest {
|
||||||
|
/**
|
||||||
|
* The status code of this request
|
||||||
|
*/
|
||||||
|
public enum StatusCode{
|
||||||
|
NOT_STARTED,
|
||||||
|
VALID,
|
||||||
|
NOT_VALID
|
||||||
|
}
|
||||||
|
|
||||||
|
private String uri;
|
||||||
|
|
||||||
|
private String address;
|
||||||
|
private Double amount;
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private StatusCode status = StatusCode.NOT_STARTED;
|
||||||
|
|
||||||
|
public BitcoinUriParseRequest(String uri, CryptoCoin cryptoCoin) {
|
||||||
|
super(cryptoCoin);
|
||||||
|
this.address = "";
|
||||||
|
this.amount = -1.0;
|
||||||
|
this.memo = "";
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(Double amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMemo() {
|
||||||
|
return memo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemo(String memo) {
|
||||||
|
this.memo = memo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(){
|
||||||
|
if ((this.status != StatusCode.NOT_STARTED)){
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusCode code){
|
||||||
|
this.status = code;
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCode getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package cy.agorise.crystalwallet.requestmanagers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoCurrency;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class validates that an account name exist, this can be used to verified the existing accounts
|
||||||
|
* or to verified if the name is available to create an Account
|
||||||
|
*
|
||||||
|
* Created by henry on 8/10/2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CalculateBitcoinUriRequest extends CryptoNetInfoRequest {
|
||||||
|
private CryptoNetAccount account;
|
||||||
|
private CryptoCurrency currency;
|
||||||
|
private double amount;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
private String uri;
|
||||||
|
|
||||||
|
public CalculateBitcoinUriRequest(CryptoCoin coin, CryptoNetAccount account, Context context) {
|
||||||
|
super(coin);
|
||||||
|
this.account = account;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculateBitcoinUriRequest(CryptoCoin coin, CryptoNetAccount account, Context context, double amount) {
|
||||||
|
super(coin);
|
||||||
|
this.account = account;
|
||||||
|
this.context = context;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculateBitcoinUriRequest(CryptoCoin coin, CryptoNetAccount account, CryptoCurrency currency, double amount, Context context) {
|
||||||
|
super(coin);
|
||||||
|
this.account = account;
|
||||||
|
this.currency = currency;
|
||||||
|
this.amount = amount;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CryptoNetAccount getAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CryptoCurrency getCurrency() {
|
||||||
|
return currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUri(String uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(){
|
||||||
|
if ((this.uri != null)){
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package cy.agorise.crystalwallet.requestmanagers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.GrapheneAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates bitcoin accounts using a seed,
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/22/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CreateBitcoinAccountRequest extends CryptoNetInfoRequest {
|
||||||
|
|
||||||
|
private AccountSeed accountSeed;
|
||||||
|
private CryptoNet accountCryptoNet;
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status code of this request
|
||||||
|
*/
|
||||||
|
public enum StatusCode{
|
||||||
|
NOT_STARTED,
|
||||||
|
SUCCEEDED,
|
||||||
|
ACCOUNT_EXIST
|
||||||
|
}
|
||||||
|
|
||||||
|
// The state of this request
|
||||||
|
private StatusCode status = StatusCode.NOT_STARTED;
|
||||||
|
|
||||||
|
public CreateBitcoinAccountRequest(AccountSeed accountSeed, Context context, CryptoCoin cryptoCoin){
|
||||||
|
super(cryptoCoin);
|
||||||
|
this.accountSeed = accountSeed;
|
||||||
|
this.accountCryptoNet = cryptoCoin.getCryptoNet();
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountSeed getAccountSeed() {
|
||||||
|
return this.accountSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(){
|
||||||
|
if(!status.equals(StatusCode.NOT_STARTED))
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CryptoNet getAccountCryptoNet() {
|
||||||
|
return this.accountCryptoNet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusCode code){
|
||||||
|
this.status = code;
|
||||||
|
this.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCode getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,13 +21,6 @@ public abstract class CryptoNetInfoRequest {
|
||||||
*/
|
*/
|
||||||
protected CryptoNetInfoRequestListener listener;
|
protected CryptoNetInfoRequestListener listener;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected CryptoNetInfoRequest(CryptoCoin coin){
|
protected CryptoNetInfoRequest(CryptoCoin coin){
|
||||||
this.coin = coin;
|
this.coin = coin;
|
||||||
}
|
}
|
||||||
|
@ -43,4 +36,7 @@ public abstract class CryptoNetInfoRequest {
|
||||||
CryptoNetInfoRequests.getInstance().removeRequest(this);
|
CryptoNetInfoRequests.getInstance().removeRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CryptoCoin getCoin() {
|
||||||
|
return coin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
package cy.agorise.crystalwallet.requestmanagers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.SeedType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports a bitshares accounts,
|
||||||
|
*
|
||||||
|
* return true if the account exist, and the mnemonic (brainkey provide is for that account
|
||||||
|
* Created by Henry Varona on 10/24/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ImportBitsharesAccountRequest extends CryptoNetInfoRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status code of this request
|
||||||
|
*/
|
||||||
|
public enum StatusCode{
|
||||||
|
NOT_STARTED,
|
||||||
|
SUCCEEDED,
|
||||||
|
NO_INTERNET,
|
||||||
|
NO_SERVER_CONNECTION,
|
||||||
|
ACCOUNT_DOESNT_EXIST,
|
||||||
|
BAD_SEED,
|
||||||
|
NO_ACCOUNT_DATA,
|
||||||
|
PETITION_FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mnemonic words
|
||||||
|
*/
|
||||||
|
private final String mnemonic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this seed is BIP39 or Brainkey
|
||||||
|
*/
|
||||||
|
private SeedType seedType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of this request
|
||||||
|
*/
|
||||||
|
private StatusCode status = StatusCode.NOT_STARTED;
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public ImportBitsharesAccountRequest(String mnemonic, Context context){
|
||||||
|
super(CryptoCoin.BITSHARES);
|
||||||
|
this.mnemonic = mnemonic;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportBitsharesAccountRequest(String mnemonic, Context context, boolean addAccountIfValid){
|
||||||
|
super(CryptoCoin.BITSHARES);
|
||||||
|
this.mnemonic = mnemonic;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(){
|
||||||
|
if (!(this.status.equals(StatusCode.NOT_STARTED))){
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMnemonic() {
|
||||||
|
return mnemonic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SeedType getSeedType() {
|
||||||
|
return seedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeedType(SeedType seedType) {
|
||||||
|
this.seedType = seedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusCode status) {
|
||||||
|
this.status = status;
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCode getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package cy.agorise.crystalwallet.requestmanagers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
|
import cy.agorise.crystalwallet.models.AccountSeed;
|
||||||
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask for the next address of a bitcoin alike account
|
||||||
|
*
|
||||||
|
* Created by Henry Varona on 10/22/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NextBitcoinAccountAddressRequest extends CryptoNetInfoRequest {
|
||||||
|
|
||||||
|
private CryptoNetAccount account;
|
||||||
|
private CryptoCoin cryptoCoin;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
private String address = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status code of this request
|
||||||
|
*/
|
||||||
|
public enum StatusCode{
|
||||||
|
NOT_STARTED,
|
||||||
|
SUCCEEDED
|
||||||
|
}
|
||||||
|
|
||||||
|
// The state of this request
|
||||||
|
private StatusCode status = StatusCode.NOT_STARTED;
|
||||||
|
|
||||||
|
public NextBitcoinAccountAddressRequest(CryptoNetAccount account, CryptoCoin cryptoCoin, Context context){
|
||||||
|
super(cryptoCoin);
|
||||||
|
this.account = account;
|
||||||
|
this.cryptoCoin = cryptoCoin;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CryptoNetAccount getAccount() {
|
||||||
|
return this.account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CryptoCoin getCryptoCoin() {
|
||||||
|
return this.cryptoCoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(){
|
||||||
|
if(!status.equals(StatusCode.NOT_STARTED))
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusCode code){
|
||||||
|
this.status = code;
|
||||||
|
this.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusCode getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package cy.agorise.crystalwallet.requestmanagers;
|
||||||
|
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class validates that an account name exist, this can be used to verified the existing accounts
|
||||||
|
* or to verified if the name is available to create an Account
|
||||||
|
*
|
||||||
|
* Created by henry on 8/10/2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ValidateBitcoinAddressRequest extends CryptoNetInfoRequest {
|
||||||
|
// The account name to validate
|
||||||
|
private String address;
|
||||||
|
// The result of the validation, or null if there isn't a response
|
||||||
|
private Boolean addressValid;
|
||||||
|
|
||||||
|
public ValidateBitcoinAddressRequest(CryptoCoin cryptoCoin, String address) {
|
||||||
|
super(cryptoCoin);
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getAddressValid(){
|
||||||
|
return this.addressValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddressValid(boolean value){
|
||||||
|
this.addressValid = value;
|
||||||
|
this.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(){
|
||||||
|
if ((this.addressValid != null)){
|
||||||
|
this._fireOnCarryOutEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,7 +16,9 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
|
import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
import cy.agorise.crystalwallet.manager.FileBackupManager;
|
import cy.agorise.crystalwallet.manager.FileBackupManager;
|
||||||
|
import cy.agorise.crystalwallet.manager.GeneralAccountManager;
|
||||||
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
|
||||||
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
|
||||||
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
|
@ -43,6 +45,7 @@ public class CrystalWalletService extends LifecycleService {
|
||||||
private Looper mServiceLooper;
|
private Looper mServiceLooper;
|
||||||
private ServiceHandler mServiceHandler;
|
private ServiceHandler mServiceHandler;
|
||||||
private BitsharesAccountManager bitsharesAccountManager;
|
private BitsharesAccountManager bitsharesAccountManager;
|
||||||
|
private GeneralAccountManager generalAccountManager;
|
||||||
private Thread LoadAccountTransactionsThread;
|
private Thread LoadAccountTransactionsThread;
|
||||||
private Thread LoadBitsharesAccountNamesThread;
|
private Thread LoadBitsharesAccountNamesThread;
|
||||||
private EquivalencesThread LoadEquivalencesThread;
|
private EquivalencesThread LoadEquivalencesThread;
|
||||||
|
@ -167,7 +170,15 @@ public class CrystalWalletService extends LifecycleService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final LiveData<List<CryptoNetAccount>> cryptoNetAccountList = db.cryptoNetAccountDao().getAllBitcoins();
|
||||||
|
cryptoNetAccountList.observe(this, new Observer<List<CryptoNetAccount>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable List<CryptoNetAccount> cryptoNetAccounts) {
|
||||||
|
for(CryptoNetAccount nextCryptoNetAccount : cryptoNetAccounts) {
|
||||||
|
generalAccountManager.loadAccountFromDB(nextCryptoNetAccount,thisService);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/*while(this.keepLoadingAccountTransactions){
|
/*while(this.keepLoadingAccountTransactions){
|
||||||
try{
|
try{
|
||||||
|
@ -188,11 +199,13 @@ public class CrystalWalletService extends LifecycleService {
|
||||||
this.cryptoNetInfoRequests = CryptoNetInfoRequests.getInstance();
|
this.cryptoNetInfoRequests = CryptoNetInfoRequests.getInstance();
|
||||||
this.fileServiceRequests = FileServiceRequests.getInstance();
|
this.fileServiceRequests = FileServiceRequests.getInstance();
|
||||||
this.bitsharesAccountManager = new BitsharesAccountManager();
|
this.bitsharesAccountManager = new BitsharesAccountManager();
|
||||||
|
this.generalAccountManager = new GeneralAccountManager(CryptoCoin.BITCOIN,this.getApplicationContext());
|
||||||
this.fileBackupManager = new FileBackupManager();
|
this.fileBackupManager = new FileBackupManager();
|
||||||
|
|
||||||
//Add the managers as listeners of the CryptoNetInfoRequest so
|
//Add the managers as listeners of the CryptoNetInfoRequest so
|
||||||
//they can carry out the info requests from the ui
|
//they can carry out the info requests from the ui
|
||||||
this.cryptoNetInfoRequests.addListener(this.bitsharesAccountManager);
|
this.cryptoNetInfoRequests.addListener(this.bitsharesAccountManager);
|
||||||
|
this.cryptoNetInfoRequests.addListener(this.generalAccountManager);
|
||||||
|
|
||||||
this.fileServiceRequests.addListener(this.fileBackupManager);
|
this.fileServiceRequests.addListener(this.fileBackupManager);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,10 @@ import android.content.Context;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
import android.widget.Scroller;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by xd on 1/18/18.
|
* Created by xd on 1/18/18.
|
||||||
|
@ -14,36 +18,47 @@ import android.view.MotionEvent;
|
||||||
|
|
||||||
public class ChildViewPager extends ViewPager {
|
public class ChildViewPager extends ViewPager {
|
||||||
|
|
||||||
private boolean swipeLocked;
|
|
||||||
|
|
||||||
public ChildViewPager(Context context) {
|
public ChildViewPager(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
|
setMyScroller();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChildViewPager(Context context, AttributeSet attrs) {
|
public ChildViewPager(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getSwipeLocked() {
|
|
||||||
return swipeLocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSwipeLocked(boolean swipeLocked) {
|
|
||||||
this.swipeLocked = swipeLocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
return !swipeLocked && super.onTouchEvent(event);
|
// stop swipe
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||||
return !swipeLocked && super.onInterceptTouchEvent(event);
|
// stop switching pages
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setMyScroller() {
|
||||||
public boolean canScrollHorizontally(int direction) {
|
try {
|
||||||
return !swipeLocked && super.canScrollHorizontally(direction);
|
Class<?> viewpager = ViewPager.class;
|
||||||
|
Field scroller = viewpager.getDeclaredField("mScroller");
|
||||||
|
scroller.setAccessible(true);
|
||||||
|
scroller.set(this, new MyScroller(getContext()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MyScroller extends Scroller {
|
||||||
|
public MyScroller(Context context) {
|
||||||
|
super(context, new DecelerateInterpolator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
|
||||||
|
super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
package cy.agorise.crystalwallet.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Henry Varona on 25/2/2018.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapShader;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
|
|
||||||
import com.squareup.picasso.Transformation;
|
|
||||||
|
|
||||||
public class CircleTransformation implements Transformation {
|
|
||||||
@Override
|
|
||||||
public Bitmap transform(Bitmap source) {
|
|
||||||
int size = Math.min(source.getWidth(), source.getHeight());
|
|
||||||
|
|
||||||
int x = (source.getWidth() - size) / 2;
|
|
||||||
int y = (source.getHeight() - size) / 2;
|
|
||||||
|
|
||||||
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
|
|
||||||
if (squaredBitmap != source) {
|
|
||||||
source.recycle();
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
|
|
||||||
|
|
||||||
Canvas canvas = new Canvas(bitmap);
|
|
||||||
Paint paint = new Paint();
|
|
||||||
BitmapShader shader = new BitmapShader(squaredBitmap,
|
|
||||||
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
|
|
||||||
paint.setShader(shader);
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
|
|
||||||
float r = size / 2f;
|
|
||||||
canvas.drawCircle(r, r, r, paint);
|
|
||||||
|
|
||||||
squaredBitmap.recycle();
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String key() {
|
|
||||||
return "CircleTransformation";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package cy.agorise.crystalwallet.util;
|
||||||
|
|
||||||
|
import com.bumptech.glide.annotation.GlideModule;
|
||||||
|
import com.bumptech.glide.module.AppGlideModule;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used to generate a local Glide API accessible by a GlideApp call
|
||||||
|
* which makes it easier to use more advanced Glide methods.
|
||||||
|
* {more information - https://bumptech.github.io/glide/doc/generatedapi.html}
|
||||||
|
*/
|
||||||
|
@GlideModule
|
||||||
|
public class MyAppGlideModule extends AppGlideModule {}
|
|
@ -1,33 +0,0 @@
|
||||||
package cy.agorise.crystalwallet.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.widget.AppCompatImageView;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by xd on 1/24/18.
|
|
||||||
* ImageView which adjusts its size to always create a square
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class SquaredImageView extends AppCompatImageView {
|
|
||||||
public SquaredImageView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SquaredImageView(Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SquaredImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
|
|
||||||
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
|
|
||||||
setMeasuredDimension(size, size);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,7 +9,6 @@ import android.arch.paging.PagedList;
|
||||||
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
import cy.agorise.crystalwallet.enums.CryptoNet;
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
import cy.agorise.crystalwallet.models.Contact;
|
import cy.agorise.crystalwallet.models.Contact;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Henry Varona on 1/17/2018.
|
* Created by Henry Varona on 1/17/2018.
|
||||||
|
|
|
@ -3,19 +3,12 @@ package cy.agorise.crystalwallet.viewmodels;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.arch.lifecycle.AndroidViewModel;
|
import android.arch.lifecycle.AndroidViewModel;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.ViewModel;
|
|
||||||
import android.arch.paging.DataSource;
|
import android.arch.paging.DataSource;
|
||||||
import android.arch.paging.LivePagedListBuilder;
|
import android.arch.paging.LivePagedListBuilder;
|
||||||
import android.arch.paging.LivePagedListProvider;
|
|
||||||
import android.arch.paging.PagedList;
|
import android.arch.paging.PagedList;
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
|
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended;
|
import cy.agorise.crystalwallet.models.CryptoCoinTransactionExtended;
|
||||||
import cy.agorise.crystalwallet.views.TransactionListView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Henry Varona on 12/9/2017.
|
* Created by Henry Varona on 12/9/2017.
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class ImportSeedValidator extends UIValidator {
|
||||||
super(context);
|
super(context);
|
||||||
this.addField(new PinValidationField(pinEdit));
|
this.addField(new PinValidationField(pinEdit));
|
||||||
this.addField(new PinConfirmationValidationField(pinEdit,pinConfirmationEdit));
|
this.addField(new PinConfirmationValidationField(pinEdit,pinConfirmationEdit));
|
||||||
this.addField(new BitsharesAccountNameValidationField(bitsharesAccountNameEdit));
|
//this.addField(new BitsharesAccountNameValidationField(bitsharesAccountNameEdit));
|
||||||
this.addField(new BitsharesAccountMnemonicValidationField(mnemonicEdit,bitsharesAccountNameEdit));
|
//this.addField(new BitsharesAccountMnemonicValidationField(mnemonicEdit,bitsharesAccountNameEdit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class SendTransactionValidator extends UIValidator {
|
||||||
private CryptoNetAccount account;
|
private CryptoNetAccount account;
|
||||||
|
|
||||||
|
|
||||||
public SendTransactionValidator(Context context, CryptoNetAccount account, MaterialSpinner fromEdit, EditText toEdit, Spinner assetSpinner, EditText amountEdit, EditText memoEdit){
|
public SendTransactionValidator(Context context, CryptoNetAccount account, Spinner fromEdit, EditText toEdit, Spinner assetSpinner, EditText amountEdit, EditText memoEdit){
|
||||||
super(context);
|
super(context);
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.addField(new FromValidationField(fromEdit));
|
this.addField(new FromValidationField(fromEdit));
|
||||||
|
|
|
@ -101,6 +101,7 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
|
||||||
result = false
|
result = false
|
||||||
accountNameField.fieldValidatorModel.setInvalid()
|
accountNameField.fieldValidatorModel.setInvalid()
|
||||||
accountNameField.fieldValidatorModel.message = this.accountNameField.resources.getString(R.string.create_account_window_err_at_least_one_character)
|
accountNameField.fieldValidatorModel.message = this.accountNameField.resources.getString(R.string.create_account_window_err_at_least_one_character)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -5,6 +5,8 @@ import android.widget.Spinner;
|
||||||
|
|
||||||
import cy.agorise.crystalwallet.R;
|
import cy.agorise.crystalwallet.R;
|
||||||
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
import cy.agorise.crystalwallet.dao.CrystalDatabase;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoCoin;
|
||||||
|
import cy.agorise.crystalwallet.enums.CryptoNet;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
|
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
|
||||||
import cy.agorise.crystalwallet.models.CryptoCurrency;
|
import cy.agorise.crystalwallet.models.CryptoCurrency;
|
||||||
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
import cy.agorise.crystalwallet.models.CryptoNetAccount;
|
||||||
|
@ -29,7 +31,12 @@ public class AmountValidationField extends ValidationField {
|
||||||
public void validate(){
|
public void validate(){
|
||||||
try {
|
try {
|
||||||
final float newAmountValue = Float.parseFloat(amountField.getText().toString());
|
final float newAmountValue = Float.parseFloat(amountField.getText().toString());
|
||||||
final CryptoCurrency cryptoCurrency = (CryptoCurrency)assetSpinner.getSelectedItem();
|
final CryptoCurrency cryptoCurrency;
|
||||||
|
if(this.account.getCryptoNet() == CryptoNet.BITSHARES) {
|
||||||
|
cryptoCurrency = (CryptoCurrency) assetSpinner.getSelectedItem();
|
||||||
|
}else{
|
||||||
|
cryptoCurrency = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCurrencyDao().getByNameAndCryptoNet(CryptoCoin.getByCryptoNet(this.account.getCryptoNet()).get(0).getLabel(),this.account.getCryptoNet().name());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validation for the money
|
* Validation for the money
|
||||||
|
@ -48,7 +55,12 @@ public class AmountValidationField extends ValidationField {
|
||||||
|
|
||||||
CryptoCoinBalance balance = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCoinBalanceDao().getBalanceFromAccount(this.account.getId(),cryptoCurrency.getId());
|
CryptoCoinBalance balance = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCoinBalanceDao().getBalanceFromAccount(this.account.getId(),cryptoCurrency.getId());
|
||||||
|
|
||||||
if (newAmountValue > balance.getBalance()){
|
double balanceDouble = 0;
|
||||||
|
if(balance != null){
|
||||||
|
balanceDouble = balance.getBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newAmountValue > balanceDouble){
|
||||||
setMessageForValue(mixedValues, validator.getContext().getResources().getString(R.string.insufficient_amount));
|
setMessageForValue(mixedValues, validator.getContext().getResources().getString(R.string.insufficient_amount));
|
||||||
setValidForValue(mixedValues, false);
|
setValidForValue(mixedValues, false);
|
||||||
} else if (newAmountValue == 0){
|
} else if (newAmountValue == 0){
|
||||||
|
@ -61,6 +73,8 @@ public class AmountValidationField extends ValidationField {
|
||||||
setLastValue("");
|
setLastValue("");
|
||||||
setMessageForValue("",validator.getContext().getResources().getString(R.string.please_enter_valid_amount));
|
setMessageForValue("",validator.getContext().getResources().getString(R.string.please_enter_valid_amount));
|
||||||
setValidForValue("", false);
|
setValidForValue("", false);
|
||||||
|
} catch (Exception e ){
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,22 @@ public class AssetValidationField extends ValidationField {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate(){
|
public void validate(){
|
||||||
final CryptoCurrency cryptoCurrencySelected = (CryptoCurrency) this.assetField.getSelectedItem();
|
if (this.assetField.getSelectedItem() instanceof CryptoCurrency) {
|
||||||
if (cryptoCurrencySelected != null) {
|
final CryptoCurrency cryptoCurrencySelected = (CryptoCurrency) this.assetField.getSelectedItem();
|
||||||
final String newValue = "" + cryptoCurrencySelected.getId();
|
if (cryptoCurrencySelected != null) {
|
||||||
|
final String newValue = "" + cryptoCurrencySelected.getId();
|
||||||
|
this.setLastValue(newValue);
|
||||||
|
setValidForValue(newValue, true);
|
||||||
|
} else {
|
||||||
|
final String newValue = "" + -1;
|
||||||
|
setMessageForValue(newValue, "Select a currency");
|
||||||
|
this.setLastValue(newValue);
|
||||||
|
setValidForValue(newValue, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final String newValue = "" + -1;
|
||||||
this.setLastValue(newValue);
|
this.setLastValue(newValue);
|
||||||
setValidForValue(newValue, true);
|
setValidForValue(newValue, true);
|
||||||
} else {
|
|
||||||
final String newValue = ""+-1;
|
|
||||||
setMessageForValue(newValue,"Select a currency");
|
|
||||||
this.setLastValue(newValue);
|
|
||||||
setValidForValue(newValue, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue