mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-06 19:00:30 +02:00
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c9927edbd1 | ||
![]() |
f0a3c05a9a | ||
![]() |
d6eb82c457 | ||
![]() |
7f47307307 | ||
![]() |
165dd3dfd1 | ||
![]() |
171727c9db | ||
![]() |
1492814ec9 | ||
![]() |
9b1225fe4b | ||
![]() |
595d88e42e | ||
![]() |
0e207d7401 | ||
![]() |
5920d6c9e8 | ||
![]() |
44fd3c10fa | ||
![]() |
91ab8a681c | ||
![]() |
d843bdb451 | ||
![]() |
2884fc711c | ||
![]() |
8ea2081270 | ||
![]() |
2296329962 | ||
![]() |
fc1bff2160 | ||
![]() |
e61c2b616e | ||
![]() |
ea1e8ac2c3 | ||
![]() |
1082175089 | ||
![]() |
90d64089a6 | ||
![]() |
b689628975 | ||
![]() |
f8e701aa07 | ||
![]() |
d855328c52 |
11
README.md
11
README.md
@@ -11,22 +11,19 @@ Another Android Monero Wallet
|
|||||||
You may lose all your Moneroj if you use this App. Be cautious when spending on the mainnet.
|
You may lose all your Moneroj if you use this App. Be cautious when spending on the mainnet.
|
||||||
|
|
||||||
### Random Notes
|
### Random Notes
|
||||||
- Based off monero v0.11.0.0 with PR #2289 applied
|
- Based off monero v0.11.1.0
|
||||||
- currently only android32 (runs on 64-bit as well)
|
- currently only android32 (runs on 64-bit as well)
|
||||||
- works on the testnet & mainnet
|
- works on the testnet & mainnet
|
||||||
- sync is slow due to 32-bit architecture
|
- sync is slow due to 32-bit architecture
|
||||||
- use your own daemon - it's easy
|
- use your own daemon - it's easy
|
||||||
- screen stays on until first sync is complete
|
- screen stays on until first sync is complete
|
||||||
- saves wallet only on first sync and when sending transactions or editing notes
|
|
||||||
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
|
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- more sensible error dialogs
|
- see taiga.getmonero.org & issues on github
|
||||||
|
|
||||||
### Issues / Pitfalls
|
### Issues / Pitfalls
|
||||||
- The backups folder is now called "backups" and not ".backups" - which in most file explorers was a hidden folder
|
- You should backup your wallet files in the "monerujo" folder periodically.
|
||||||
- Wallets are now created directly in the "monerujo" folder, and not in the ".new" folder as before
|
|
||||||
- You may want to check the old folders with a file browsing app and delete the ".new" and ".backups" folders AFTER moving neccessary wallet files to the new locations. Or simply make new backups from within Monerujo.
|
|
||||||
- Also note, that on some devices the backups will only be visible on a PC over USB after a reboot of the device (it's an Android bug/feature)
|
- Also note, that on some devices the backups will only be visible on a PC over USB after a reboot of the device (it's an Android bug/feature)
|
||||||
- Created wallets on a private testnet are unusable because the restore height is set to that
|
- Created wallets on a private testnet are unusable because the restore height is set to that
|
||||||
of the "real" testnet. After creating a new wallet, make a **new** one by recovering from the seed.
|
of the "real" testnet. After creating a new wallet, make a **new** one by recovering from the seed.
|
||||||
@@ -36,7 +33,7 @@ The official monero client shows the same behaviour.
|
|||||||
No need to build. Binaries are included:
|
No need to build. Binaries are included:
|
||||||
|
|
||||||
- openssl-1.0.2l
|
- openssl-1.0.2l
|
||||||
- monero-v0.11.0.0 + pull requests #2289
|
- monero-v0.11.1.0
|
||||||
- boost_1_64_0
|
- boost_1_64_0
|
||||||
|
|
||||||
If you want to build them yourself (recommended) check out [the instructions](doc/BUILDING-external-libs.md)
|
If you want to build them yourself (recommended) check out [the instructions](doc/BUILDING-external-libs.md)
|
||||||
|
@@ -8,8 +8,8 @@ android {
|
|||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 51
|
versionCode 70
|
||||||
versionName "1.2.11"
|
versionName "1.3.10 'Satoshis Dream'"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
@@ -27,6 +27,9 @@ android {
|
|||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
|
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
4
app/src/debug/res/values/strings.xml
Normal file
4
app/src/debug/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name" translatable="false">monerujo - Debug</string>
|
||||||
|
</resources>
|
@@ -291,41 +291,48 @@ Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject i
|
|||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring mnemonic,
|
jstring path, jstring password,
|
||||||
|
jstring mnemonic,
|
||||||
jboolean isTestNet,
|
jboolean isTestNet,
|
||||||
jlong restoreHeight) {
|
jlong restoreHeight) {
|
||||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
const char *_mnemonic = env->GetStringUTFChars(mnemonic, NULL);
|
const char *_mnemonic = env->GetStringUTFChars(mnemonic, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
||||||
std::string(_path),
|
std::string(_path),
|
||||||
|
std::string(_password),
|
||||||
std::string(_mnemonic),
|
std::string(_mnemonic),
|
||||||
isTestNet,
|
isTestNet,
|
||||||
restoreHeight);
|
restoreHeight);
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
env->ReleaseStringUTFChars(mnemonic, _mnemonic);
|
env->ReleaseStringUTFChars(mnemonic, _mnemonic);
|
||||||
return reinterpret_cast<jlong>(wallet);
|
return reinterpret_cast<jlong>(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletWithKeysJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring language,
|
jstring path, jstring password,
|
||||||
|
jstring language,
|
||||||
jboolean isTestNet,
|
jboolean isTestNet,
|
||||||
jlong restoreHeight,
|
jlong restoreHeight,
|
||||||
jstring addressString,
|
jstring addressString,
|
||||||
jstring viewKeyString,
|
jstring viewKeyString,
|
||||||
jstring spendKeyString) {
|
jstring spendKeyString) {
|
||||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
const char *_language = env->GetStringUTFChars(language, NULL);
|
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||||
const char *_addressString = env->GetStringUTFChars(addressString, NULL);
|
const char *_addressString = env->GetStringUTFChars(addressString, NULL);
|
||||||
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, NULL);
|
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, NULL);
|
||||||
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, NULL);
|
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
|
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletWithKeys(
|
||||||
std::string(_path),
|
std::string(_path),
|
||||||
|
std::string(_password),
|
||||||
std::string(_language),
|
std::string(_language),
|
||||||
isTestNet,
|
isTestNet,
|
||||||
restoreHeight,
|
restoreHeight,
|
||||||
@@ -334,6 +341,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env,
|
|||||||
std::string(_spendKeyString));
|
std::string(_spendKeyString));
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
env->ReleaseStringUTFChars(language, _language);
|
env->ReleaseStringUTFChars(language, _language);
|
||||||
env->ReleaseStringUTFChars(addressString, _addressString);
|
env->ReleaseStringUTFChars(addressString, _addressString);
|
||||||
env->ReleaseStringUTFChars(viewKeyString, _viewKeyString);
|
env->ReleaseStringUTFChars(viewKeyString, _viewKeyString);
|
||||||
|
@@ -103,6 +103,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
copyAddress();
|
copyAddress();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
bCopyAddress.setClickable(false);
|
||||||
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -213,7 +214,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
tvWalletViewKey.setText(viewKey);
|
tvWalletViewKey.setText(viewKey);
|
||||||
tvWalletSpendKey.setText(spendKey);
|
tvWalletSpendKey.setText(spendKey);
|
||||||
bAdvancedInfo.setVisibility(View.VISIBLE);
|
bAdvancedInfo.setVisibility(View.VISIBLE);
|
||||||
bCopyAddress.setEnabled(true);
|
bCopyAddress.setClickable(true);
|
||||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||||
activityCallback.setTitle(name, getString(R.string.details_title));
|
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||||
activityCallback.setToolbarButton(
|
activityCallback.setToolbarButton(
|
||||||
|
@@ -278,7 +278,7 @@ public class LoginActivity extends SecureActivity
|
|||||||
// set dialog message
|
// set dialog message
|
||||||
alertDialogBuilder
|
alertDialogBuilder
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setPositiveButton("OK",
|
.setPositiveButton(getString(R.string.label_ok),
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
Helper.hideKeyboardAlways(LoginActivity.this);
|
Helper.hideKeyboardAlways(LoginActivity.this);
|
||||||
@@ -286,7 +286,7 @@ public class LoginActivity extends SecureActivity
|
|||||||
new AsyncRename().execute(walletName, newName);
|
new AsyncRename().execute(walletName, newName);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setNegativeButton("Cancel",
|
.setNegativeButton(getString(R.string.label_cancel),
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
Helper.hideKeyboardAlways(LoginActivity.this);
|
Helper.hideKeyboardAlways(LoginActivity.this);
|
||||||
@@ -482,8 +482,8 @@ public class LoginActivity extends SecureActivity
|
|||||||
// set dialog message
|
// set dialog message
|
||||||
alertDialogBuilder
|
alertDialogBuilder
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setPositiveButton("OK", null)
|
.setPositiveButton(getString(R.string.label_ok), null)
|
||||||
.setNegativeButton("Cancel",
|
.setNegativeButton(getString(R.string.label_cancel),
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
Helper.hideKeyboardAlways(LoginActivity.this);
|
Helper.hideKeyboardAlways(LoginActivity.this);
|
||||||
@@ -778,13 +778,14 @@ public class LoginActivity extends SecureActivity
|
|||||||
static final String MNEMONIC_LANGUAGE = "English"; // see mnemonics/electrum-words.cpp for more
|
static final String MNEMONIC_LANGUAGE = "English"; // see mnemonics/electrum-words.cpp for more
|
||||||
|
|
||||||
private class AsyncCreateWallet extends AsyncTask<Void, Void, Boolean> {
|
private class AsyncCreateWallet extends AsyncTask<Void, Void, Boolean> {
|
||||||
String walletName;
|
final String walletName;
|
||||||
String walletPassword;
|
final String walletPassword;
|
||||||
WalletCreator walletCreator;
|
final WalletCreator walletCreator;
|
||||||
|
|
||||||
File newWalletFile;
|
File newWalletFile;
|
||||||
|
|
||||||
public AsyncCreateWallet(String name, String password, WalletCreator walletCreator) {
|
public AsyncCreateWallet(final String name, final String password,
|
||||||
|
final WalletCreator walletCreator) {
|
||||||
super();
|
super();
|
||||||
this.walletName = name;
|
this.walletName = name;
|
||||||
this.walletPassword = password;
|
this.walletPassword = password;
|
||||||
@@ -814,12 +815,7 @@ public class LoginActivity extends SecureActivity
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
File newWalletFolder = Helper.getNewWalletDir(getApplicationContext());
|
newWalletFile = new File(walletFolder, walletName);
|
||||||
if (!newWalletFolder.isDirectory()) {
|
|
||||||
Timber.e("New Wallet dir " + newWalletFolder.getAbsolutePath() + "is not a directory");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
newWalletFile = new File(newWalletFolder, walletName);
|
|
||||||
boolean success = walletCreator.createWallet(newWalletFile, walletPassword);
|
boolean success = walletCreator.createWallet(newWalletFile, walletPassword);
|
||||||
if (success) {
|
if (success) {
|
||||||
return true;
|
return true;
|
||||||
@@ -844,7 +840,8 @@ public class LoginActivity extends SecureActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createWallet(String name, String password, WalletCreator walletCreator) {
|
public void createWallet(final String name, final String password,
|
||||||
|
final WalletCreator walletCreator) {
|
||||||
new AsyncCreateWallet(name, password, walletCreator)
|
new AsyncCreateWallet(name, password, walletCreator)
|
||||||
.executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR);
|
.executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
@@ -865,7 +862,7 @@ public class LoginActivity extends SecureActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGenerate(String name, String password) {
|
public void onGenerate(final String name, final String password) {
|
||||||
createWallet(name, password,
|
createWallet(name, password,
|
||||||
new WalletCreator() {
|
new WalletCreator() {
|
||||||
public boolean createWallet(File aFile, String password) {
|
public boolean createWallet(File aFile, String password) {
|
||||||
@@ -883,16 +880,15 @@ public class LoginActivity extends SecureActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGenerate(String name, String password, final String seed, final long restoreHeight) {
|
public void onGenerate(final String name, final String password, final String seed,
|
||||||
|
final long restoreHeight) {
|
||||||
createWallet(name, password,
|
createWallet(name, password,
|
||||||
new WalletCreator() {
|
new WalletCreator() {
|
||||||
public boolean createWallet(File aFile, String password) {
|
public boolean createWallet(File aFile, String password) {
|
||||||
Wallet newWallet = WalletManager.getInstance().recoveryWallet(aFile, seed, restoreHeight);
|
Wallet newWallet = WalletManager.getInstance().
|
||||||
|
recoveryWallet(aFile, password, seed, restoreHeight);
|
||||||
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
|
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
|
||||||
if (success) {
|
if (!success) {
|
||||||
newWallet.setPassword(password);
|
|
||||||
success = success && newWallet.store();
|
|
||||||
} else {
|
|
||||||
Timber.e(newWallet.getErrorString());
|
Timber.e(newWallet.getErrorString());
|
||||||
toast(newWallet.getErrorString());
|
toast(newWallet.getErrorString());
|
||||||
}
|
}
|
||||||
@@ -903,19 +899,17 @@ public class LoginActivity extends SecureActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGenerate(String name, String password,
|
public void onGenerate(final String name, final String password,
|
||||||
final String address, final String viewKey, final String spendKey, final long restoreHeight) {
|
final String address, final String viewKey, final String spendKey,
|
||||||
|
final long restoreHeight) {
|
||||||
createWallet(name, password,
|
createWallet(name, password,
|
||||||
new WalletCreator() {
|
new WalletCreator() {
|
||||||
public boolean createWallet(File aFile, String password) {
|
public boolean createWallet(File aFile, String password) {
|
||||||
Wallet newWallet = WalletManager.getInstance()
|
Wallet newWallet = WalletManager.getInstance()
|
||||||
.createWalletFromKeys(aFile, MNEMONIC_LANGUAGE, restoreHeight,
|
.createWalletWithKeys(aFile, password, MNEMONIC_LANGUAGE, restoreHeight,
|
||||||
address, viewKey, spendKey);
|
address, viewKey, spendKey);
|
||||||
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
|
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
|
||||||
if (success) {
|
if (!success) {
|
||||||
newWallet.setPassword(password);
|
|
||||||
success = success && newWallet.store();
|
|
||||||
} else {
|
|
||||||
Timber.e(newWallet.getErrorString());
|
Timber.e(newWallet.getErrorString());
|
||||||
toast(newWallet.getErrorString());
|
toast(newWallet.getErrorString());
|
||||||
}
|
}
|
||||||
@@ -936,16 +930,10 @@ public class LoginActivity extends SecureActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccept(final String name, final String password) {
|
public void onAccept(final String name, final String password) {
|
||||||
File newWalletFile = new File(Helper.getNewWalletDir(getApplicationContext()), name);
|
File walletFolder = getStorageRoot();
|
||||||
Timber.d("New Wallet %s", newWalletFile.getAbsolutePath());
|
File walletFile = new File(walletFolder, name);
|
||||||
newWalletFile.delete(); // when recovering wallets, the cache seems corrupt
|
Timber.d("New Wallet %s", walletFile.getAbsolutePath());
|
||||||
// TODO: figure out why this is so? Only for a private testnet?
|
walletFile.delete(); // when recovering wallets, the cache seems corrupt
|
||||||
|
|
||||||
// now copy the new wallet to the wallet folder
|
|
||||||
File walletFile = new File(getStorageRoot(), name);
|
|
||||||
Timber.d("Wallet %s", walletFile.getAbsolutePath());
|
|
||||||
copyWallet(newWalletFile, walletFile, false, true);
|
|
||||||
deleteWallet(newWalletFile); // delete it no matter what (can't recover from this anyway)
|
|
||||||
|
|
||||||
boolean rc = testWallet(walletFile.getAbsolutePath(), password) == Wallet.Status.Status_Ok;
|
boolean rc = testWallet(walletFile.getAbsolutePath(), password) == Wallet.Status.Status_Ok;
|
||||||
|
|
||||||
|
@@ -43,6 +43,7 @@ import android.widget.RelativeLayout;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||||
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
@@ -61,15 +62,18 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
|
|
||||||
private WalletInfoAdapter adapter;
|
private WalletInfoAdapter adapter;
|
||||||
|
|
||||||
List<WalletManager.WalletInfo> walletList = new ArrayList<>();
|
private List<WalletManager.WalletInfo> walletList = new ArrayList<>();
|
||||||
List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
|
private List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
|
||||||
|
|
||||||
EditText etDummy;
|
private EditText etDummy;
|
||||||
ImageView ivGunther;
|
private ImageView ivGunther;
|
||||||
DropDownEditText etDaemonAddress;
|
private DropDownEditText etDaemonAddress;
|
||||||
ArrayAdapter<String> nodeAdapter;
|
private ArrayAdapter<String> nodeAdapter;
|
||||||
|
|
||||||
Listener activityCallback;
|
private View llXmrToEnabled;
|
||||||
|
private View ibXmrToInfoClose;
|
||||||
|
|
||||||
|
private Listener activityCallback;
|
||||||
|
|
||||||
// Container Activity must implement this interface
|
// Container Activity must implement this interface
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
@@ -165,6 +169,25 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
etDummy = (EditText) view.findViewById(R.id.etDummy);
|
etDummy = (EditText) view.findViewById(R.id.etDummy);
|
||||||
|
|
||||||
|
llXmrToEnabled = view.findViewById(R.id.llXmrToEnabled);
|
||||||
|
llXmrToEnabled.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
HelpFragment.display(getChildFragmentManager(), R.string.help_xmrto);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ibXmrToInfoClose = view.findViewById(R.id.ibXmrToInfoClose);
|
||||||
|
ibXmrToInfoClose.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
llXmrToEnabled.setVisibility(View.GONE);
|
||||||
|
showXmrtoEnabled = false;
|
||||||
|
saveXmrToPrefs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
etDaemonAddress = (DropDownEditText) view.findViewById(R.id.etDaemonAddress);
|
etDaemonAddress = (DropDownEditText) view.findViewById(R.id.etDaemonAddress);
|
||||||
nodeAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_dropdown_item_1line);
|
nodeAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_dropdown_item_1line);
|
||||||
etDaemonAddress.setAdapter(nodeAdapter);
|
etDaemonAddress.setAdapter(nodeAdapter);
|
||||||
@@ -211,6 +234,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
});
|
});
|
||||||
|
|
||||||
loadPrefs();
|
loadPrefs();
|
||||||
|
if (!showXmrtoEnabled) {
|
||||||
|
llXmrToEnabled.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@@ -290,9 +316,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
activityCallback.onWalletDetails(name, isTestnet());
|
activityCallback.onWalletDetails(name, isTestnet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean showReceive(@NonNull String name) {
|
private void showReceive(@NonNull String name) {
|
||||||
activityCallback.onWalletReceive(name, isTestnet());
|
activityCallback.onWalletReceive(name, isTestnet());
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -308,7 +333,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean testnet = false;
|
private boolean testnet = BuildConfig.DEBUG;
|
||||||
|
|
||||||
boolean isTestnet() {
|
boolean isTestnet() {
|
||||||
return testnet;
|
return testnet;
|
||||||
@@ -336,6 +361,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
|
|
||||||
private static final String PREF_DAEMON_TESTNET = "daemon_testnet";
|
private static final String PREF_DAEMON_TESTNET = "daemon_testnet";
|
||||||
private static final String PREF_DAEMON_MAINNET = "daemon_mainnet";
|
private static final String PREF_DAEMON_MAINNET = "daemon_mainnet";
|
||||||
|
private static final String PREF_SHOW_XMRTO_ENABLED = "info_xmrto_enabled_login";
|
||||||
|
|
||||||
private static final String PREF_DAEMONLIST_MAINNET =
|
private static final String PREF_DAEMONLIST_MAINNET =
|
||||||
"node.moneroworld.com:18089;node.xmrbackb.one;node.xmr.be";
|
"node.moneroworld.com:18089;node.xmrbackb.one;node.xmr.be";
|
||||||
@@ -346,22 +372,33 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
private NodeList daemonTestNet;
|
private NodeList daemonTestNet;
|
||||||
private NodeList daemonMainNet;
|
private NodeList daemonMainNet;
|
||||||
|
|
||||||
|
boolean showXmrtoEnabled = true;
|
||||||
|
|
||||||
void loadPrefs() {
|
void loadPrefs() {
|
||||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
SharedPreferences sharedPref = activityCallback.getPrefs();
|
||||||
|
|
||||||
daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET));
|
daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET));
|
||||||
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, PREF_DAEMONLIST_TESTNET));
|
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, PREF_DAEMONLIST_TESTNET));
|
||||||
setNet(isTestnet(), false);
|
setNet(isTestnet(), false);
|
||||||
|
|
||||||
|
showXmrtoEnabled = sharedPref.getBoolean(PREF_SHOW_XMRTO_ENABLED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveXmrToPrefs() {
|
||||||
|
SharedPreferences sharedPref = activityCallback.getPrefs();
|
||||||
|
SharedPreferences.Editor editor = sharedPref.edit();
|
||||||
|
editor.putBoolean(PREF_SHOW_XMRTO_ENABLED, showXmrtoEnabled);
|
||||||
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
void savePrefs() {
|
void savePrefs() {
|
||||||
savePrefs(false);
|
savePrefs(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void savePrefs(boolean usePreviousState) {
|
void savePrefs(boolean usePreviousTestnetState) {
|
||||||
Timber.d("SAVE / %s", usePreviousState);
|
Timber.d("SAVE / %s", usePreviousTestnetState);
|
||||||
// save the daemon address for the net
|
// save the daemon address for the net
|
||||||
boolean testnet = isTestnet() ^ usePreviousState;
|
boolean testnet = isTestnet() ^ usePreviousTestnetState;
|
||||||
String daemon = getDaemon();
|
String daemon = getDaemon();
|
||||||
if (testnet) {
|
if (testnet) {
|
||||||
daemonTestNet.setRecent(daemon);
|
daemonTestNet.setRecent(daemon);
|
||||||
@@ -373,6 +410,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
SharedPreferences.Editor editor = sharedPref.edit();
|
SharedPreferences.Editor editor = sharedPref.edit();
|
||||||
editor.putString(PREF_DAEMON_MAINNET, daemonMainNet.toString());
|
editor.putString(PREF_DAEMON_MAINNET, daemonMainNet.toString());
|
||||||
editor.putString(PREF_DAEMON_TESTNET, daemonTestNet.toString());
|
editor.putString(PREF_DAEMON_TESTNET, daemonTestNet.toString());
|
||||||
|
editor.putBoolean(PREF_SHOW_XMRTO_ENABLED, showXmrtoEnabled);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,6 +46,7 @@ import com.google.zxing.WriterException;
|
|||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
import com.google.zxing.qrcode.QRCodeWriter;
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||||
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
@@ -105,6 +106,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
copyAddress();
|
copyAddress();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
bCopyAddress.setClickable(false);
|
||||||
|
|
||||||
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
|
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -239,7 +241,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
tvAddress.setText(address);
|
tvAddress.setText(address);
|
||||||
etPaymentId.setEnabled(true);
|
etPaymentId.setEnabled(true);
|
||||||
bPaymentId.setEnabled(true);
|
bPaymentId.setEnabled(true);
|
||||||
bCopyAddress.setEnabled(true);
|
bCopyAddress.setClickable(true);
|
||||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||||
hideProgress();
|
hideProgress();
|
||||||
generateQr();
|
generateQr();
|
||||||
@@ -304,14 +306,14 @@ public class ReceiveFragment extends Fragment {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append(ScannerFragment.QR_SCHEME).append(address);
|
sb.append(BarcodeData.XMR_SCHEME).append(address);
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
if (!paymentId.isEmpty()) {
|
if (!paymentId.isEmpty()) {
|
||||||
if (first) {
|
if (first) {
|
||||||
sb.append("?");
|
sb.append("?");
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
sb.append(ScannerFragment.QR_PAYMENTID).append('=').append(paymentId);
|
sb.append(BarcodeData.XMR_PAYMENTID).append('=').append(paymentId);
|
||||||
}
|
}
|
||||||
if (!xmrAmount.isEmpty()) {
|
if (!xmrAmount.isEmpty()) {
|
||||||
if (first) {
|
if (first) {
|
||||||
@@ -319,7 +321,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
} else {
|
} else {
|
||||||
sb.append("&");
|
sb.append("&");
|
||||||
}
|
}
|
||||||
sb.append(ScannerFragment.QR_AMOUNT).append('=').append(xmrAmount);
|
sb.append(BarcodeData.XMR_AMOUNT).append('=').append(xmrAmount);
|
||||||
}
|
}
|
||||||
String text = sb.toString();
|
String text = sb.toString();
|
||||||
int size = Math.min(qrCode.getHeight(), qrCode.getWidth());
|
int size = Math.min(qrCode.getHeight(), qrCode.getWidth());
|
||||||
|
@@ -36,7 +36,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
private OnScannedListener onScannedListener;
|
private OnScannedListener onScannedListener;
|
||||||
|
|
||||||
public interface OnScannedListener {
|
public interface OnScannedListener {
|
||||||
boolean onScanned(String uri);
|
boolean onScanned(String qrCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ZXingScannerView mScannerView;
|
private ZXingScannerView mScannerView;
|
||||||
@@ -56,10 +56,6 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
mScannerView.startCamera();
|
mScannerView.startCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
static final String QR_SCHEME = "monero:";
|
|
||||||
static final String QR_PAYMENTID = "tx_payment_id";
|
|
||||||
static final String QR_AMOUNT = "tx_amount";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleResult(Result rawResult) {
|
public void handleResult(Result rawResult) {
|
||||||
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE)) {
|
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE)) {
|
||||||
|
@@ -20,6 +20,10 @@ 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 com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import static android.view.WindowManager.LayoutParams;
|
import static android.view.WindowManager.LayoutParams;
|
||||||
|
|
||||||
public abstract class SecureActivity extends AppCompatActivity {
|
public abstract class SecureActivity extends AppCompatActivity {
|
||||||
|
@@ -30,10 +30,13 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Transfer;
|
import com.m2049r.xmrwallet.model.Transfer;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.UserNotes;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -68,12 +71,23 @@ public class TxFragment extends Fragment {
|
|||||||
private TextView etTxNotes;
|
private TextView etTxNotes;
|
||||||
private Button bTxNotes;
|
private Button bTxNotes;
|
||||||
|
|
||||||
|
// XMRTO stuff
|
||||||
|
private View cvXmrTo;
|
||||||
|
private TextView tvTxXmrToKey;
|
||||||
|
private TextView tvDestinationBtc;
|
||||||
|
private TextView tvTxAmountBtc;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.fragment_tx_info, container, false);
|
View view = inflater.inflate(R.layout.fragment_tx_info, container, false);
|
||||||
|
|
||||||
|
cvXmrTo = view.findViewById(R.id.cvXmrTo);
|
||||||
|
tvTxXmrToKey = (TextView) view.findViewById(R.id.tvTxXmrToKey);
|
||||||
|
tvDestinationBtc = (TextView) view.findViewById(R.id.tvDestinationBtc);
|
||||||
|
tvTxAmountBtc = (TextView) view.findViewById(R.id.tvTxAmountBtc);
|
||||||
|
|
||||||
tvTxTimestamp = (TextView) view.findViewById(R.id.tvTxTimestamp);
|
tvTxTimestamp = (TextView) view.findViewById(R.id.tvTxTimestamp);
|
||||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||||
tvTxKey = (TextView) view.findViewById(R.id.tvTxKey);
|
tvTxKey = (TextView) view.findViewById(R.id.tvTxKey);
|
||||||
@@ -94,7 +108,16 @@ public class TxFragment extends Fragment {
|
|||||||
info.notes = null; // force reload on next view
|
info.notes = null; // force reload on next view
|
||||||
bTxNotes.setEnabled(false);
|
bTxNotes.setEnabled(false);
|
||||||
etTxNotes.setEnabled(false);
|
etTxNotes.setEnabled(false);
|
||||||
activityCallback.onSetNote(info.hash, etTxNotes.getText().toString());
|
userNotes.setNote(etTxNotes.getText().toString());
|
||||||
|
activityCallback.onSetNote(info.hash, userNotes.txNotes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tvTxXmrToKey.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_xmrtokey), tvTxXmrToKey.getText().toString());
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.message_copy_xmrtokey), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -175,12 +198,14 @@ public class TxFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TransactionInfo info = null;
|
TransactionInfo info = null;
|
||||||
|
UserNotes userNotes = null;
|
||||||
|
|
||||||
void loadNotes(TransactionInfo info) {
|
void loadNotes(TransactionInfo info) {
|
||||||
if (info.notes == null) {
|
if ((userNotes == null) || (info.notes == null)) {
|
||||||
info.notes = activityCallback.getTxNotes(info.hash);
|
info.notes = activityCallback.getTxNotes(info.hash);
|
||||||
}
|
}
|
||||||
etTxNotes.setText(info.notes);
|
userNotes = new UserNotes(info.notes);
|
||||||
|
etTxNotes.setText(userNotes.note);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTxColour(int clr) {
|
private void setTxColour(int clr) {
|
||||||
@@ -266,8 +291,21 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxTransfers.setText(sb.toString());
|
tvTxTransfers.setText(sb.toString());
|
||||||
tvDestination.setText(dstSb.toString());
|
tvDestination.setText(dstSb.toString());
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
showBtcInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showBtcInfo() {
|
||||||
|
if (userNotes.xmrtoKey != null) {
|
||||||
|
cvXmrTo.setVisibility(View.VISIBLE);
|
||||||
|
tvTxXmrToKey.setText(userNotes.xmrtoKey);
|
||||||
|
tvDestinationBtc.setText(userNotes.xmrtoDestination);
|
||||||
|
tvTxAmountBtc.setText(userNotes.xmrtoAmount + " BTC");
|
||||||
|
} else {
|
||||||
|
cvXmrTo.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@@ -22,8 +22,8 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
@@ -38,17 +38,18 @@ import com.m2049r.xmrwallet.data.BarcodeData;
|
|||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.dialog.DonationFragment;
|
import com.m2049r.xmrwallet.dialog.DonationFragment;
|
||||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||||
|
import com.m2049r.xmrwallet.fragment.send.SendAddressWizardFragment;
|
||||||
|
import com.m2049r.xmrwallet.fragment.send.SendFragment;
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.service.WalletService;
|
import com.m2049r.xmrwallet.service.WalletService;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.UserNotes;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
@@ -140,6 +141,9 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
Timber.d("onDestroy()");
|
Timber.d("onDestroy()");
|
||||||
|
if ((mBoundService != null) && !isSynced() && (getWallet() != null)) {
|
||||||
|
saveWallet();
|
||||||
|
}
|
||||||
stopWalletService();
|
stopWalletService();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
@@ -465,7 +469,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransactionCreated(final PendingTransaction pendingTransaction) {
|
public void onTransactionCreated(final String txTag, final PendingTransaction pendingTransaction) {
|
||||||
try {
|
try {
|
||||||
final SendFragment sendFragment = (SendFragment)
|
final SendFragment sendFragment = (SendFragment)
|
||||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||||
@@ -477,7 +481,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
getWallet().disposePendingTransaction();
|
getWallet().disposePendingTransaction();
|
||||||
sendFragment.onCreateTransactionFailed(errorText);
|
sendFragment.onCreateTransactionFailed(errorText);
|
||||||
} else {
|
} else {
|
||||||
sendFragment.onTransactionCreated(pendingTransaction);
|
sendFragment.onTransactionCreated(txTag, pendingTransaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -560,19 +564,20 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProgress(final int n) {
|
public void onProgress(final int n) {
|
||||||
try {
|
runOnUiThread(new Runnable() {
|
||||||
final WalletFragment walletFragment = (WalletFragment)
|
public void run() {
|
||||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
try {
|
||||||
runOnUiThread(new Runnable() {
|
WalletFragment walletFragment = (WalletFragment)
|
||||||
public void run() {
|
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
||||||
walletFragment.setProgress(n);
|
if (walletFragment != null)
|
||||||
|
walletFragment.setProgress(n);
|
||||||
|
} catch (ClassCastException ex) {
|
||||||
|
// not in wallet fragment (probably send monero)
|
||||||
|
Timber.d(ex.getLocalizedMessage());
|
||||||
|
// keep calm and carry on
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
} catch (ClassCastException ex) {
|
});
|
||||||
// not in wallet fragment (probably send monero)
|
|
||||||
Timber.d(ex.getLocalizedMessage());
|
|
||||||
// keep calm and carry on
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateProgress() {
|
private void updateProgress() {
|
||||||
@@ -588,11 +593,11 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSend(String notes) {
|
public void onSend(UserNotes notes) {
|
||||||
if (mIsBound) { // no point in talking to unbound service
|
if (mIsBound) { // no point in talking to unbound service
|
||||||
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
||||||
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_SEND);
|
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_SEND);
|
||||||
intent.putExtra(WalletService.REQUEST_CMD_SEND_NOTES, notes);
|
intent.putExtra(WalletService.REQUEST_CMD_SEND_NOTES, notes.txNotes);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
Timber.d("SEND TX request sent");
|
Timber.d("SEND TX request sent");
|
||||||
} else {
|
} else {
|
||||||
@@ -617,11 +622,12 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareSend(TxData txData) {
|
public void onPrepareSend(final String tag, final TxData txData) {
|
||||||
if (mIsBound) { // no point in talking to unbound service
|
if (mIsBound) { // no point in talking to unbound service
|
||||||
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
||||||
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_TX);
|
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_TX);
|
||||||
intent.putExtra(WalletService.REQUEST_CMD_TX_DATA, txData);
|
intent.putExtra(WalletService.REQUEST_CMD_TX_DATA, txData);
|
||||||
|
intent.putExtra(WalletService.REQUEST_CMD_TX_TAG, tag);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
Timber.d("CREATE TX request sent");
|
Timber.d("CREATE TX request sent");
|
||||||
} else {
|
} else {
|
||||||
@@ -694,6 +700,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisposeRequest() {
|
public void onDisposeRequest() {
|
||||||
|
//TODO consider doing this through the WalletService to avoid concurrency issues
|
||||||
getWallet().disposePendingTransaction();
|
getWallet().disposePendingTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,9 +811,6 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!isSynced()) {
|
|
||||||
saveWallet();
|
|
||||||
}
|
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -815,4 +819,10 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
public void onFragmentDone() {
|
public void onFragmentDone() {
|
||||||
popFragmentStack(null);
|
popFragmentStack(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SharedPreferences getPrefs() {
|
||||||
|
return getPreferences(Context.MODE_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -313,7 +313,7 @@ public class WalletFragment extends Fragment
|
|||||||
if (wallet == null) return;
|
if (wallet == null) return;
|
||||||
walletTitle = wallet.getName();
|
walletTitle = wallet.getName();
|
||||||
String watchOnly = (wallet.isWatchOnly() ? getString(R.string.label_watchonly) : "");
|
String watchOnly = (wallet.isWatchOnly() ? getString(R.string.label_watchonly) : "");
|
||||||
walletSubtitle = wallet.getAddress().substring(0, 16) + "…" + watchOnly;
|
walletSubtitle = wallet.getAddress().substring(0, 10) + "…" + watchOnly;
|
||||||
activityCallback.setTitle(walletTitle, walletSubtitle);
|
activityCallback.setTitle(walletTitle, walletSubtitle);
|
||||||
Timber.d("wallet title is %s", walletTitle);
|
Timber.d("wallet title is %s", walletTitle);
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,8 @@ package com.m2049r.xmrwallet.data;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -34,7 +36,7 @@ public class BarcodeData {
|
|||||||
static final String BTC_AMOUNT = "amount";
|
static final String BTC_AMOUNT = "amount";
|
||||||
|
|
||||||
public enum Asset {
|
public enum Asset {
|
||||||
XMR
|
XMR, BTC
|
||||||
}
|
}
|
||||||
|
|
||||||
public Asset asset = null;
|
public Asset asset = null;
|
||||||
@@ -67,6 +69,14 @@ public class BarcodeData {
|
|||||||
if (bcData == null) {
|
if (bcData == null) {
|
||||||
bcData = parseMoneroNaked(qrCode);
|
bcData = parseMoneroNaked(qrCode);
|
||||||
}
|
}
|
||||||
|
// check for btc uri
|
||||||
|
if (bcData == null) {
|
||||||
|
bcData = parseBitcoinUri(qrCode);
|
||||||
|
}
|
||||||
|
// check for naked btc addres
|
||||||
|
if (bcData == null) {
|
||||||
|
bcData = parseBitcoinNaked(qrCode);
|
||||||
|
}
|
||||||
return bcData;
|
return bcData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,4 +144,57 @@ public class BarcodeData {
|
|||||||
|
|
||||||
return new BarcodeData(Asset.XMR, address);
|
return new BarcodeData(Asset.XMR, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bitcoin:mpQ84J43EURZHkCnXbyQ4PpNDLLBqdsMW2?amount=0.01
|
||||||
|
static public BarcodeData parseBitcoinUri(String uri) {
|
||||||
|
Timber.d("parseBitcoinUri=%s", uri);
|
||||||
|
|
||||||
|
if (uri == null) return null;
|
||||||
|
|
||||||
|
if (!uri.startsWith(BTC_SCHEME)) return null;
|
||||||
|
|
||||||
|
String noScheme = uri.substring(BTC_SCHEME.length());
|
||||||
|
Uri bitcoin = Uri.parse(noScheme);
|
||||||
|
Map<String, String> parms = new HashMap<>();
|
||||||
|
String query = bitcoin.getQuery();
|
||||||
|
if (query != null) {
|
||||||
|
String[] args = query.split("&");
|
||||||
|
for (String arg : args) {
|
||||||
|
String[] namevalue = arg.split("=");
|
||||||
|
if (namevalue.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parms.put(Uri.decode(namevalue[0]).toLowerCase(),
|
||||||
|
namevalue.length > 1 ? Uri.decode(namevalue[1]) : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String address = bitcoin.getPath();
|
||||||
|
String amount = parms.get(BTC_AMOUNT);
|
||||||
|
if (amount != null) {
|
||||||
|
try {
|
||||||
|
Double.parseDouble(amount);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
Timber.d(ex.getLocalizedMessage());
|
||||||
|
return null; // we have an amount but its not a number!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet())) {
|
||||||
|
Timber.d("address invalid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new BarcodeData(BarcodeData.Asset.BTC, address, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public BarcodeData parseBitcoinNaked(String address) {
|
||||||
|
Timber.d("parseBitcoinNaked=%s", address);
|
||||||
|
|
||||||
|
if (address == null) return null;
|
||||||
|
|
||||||
|
if (!BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet())) {
|
||||||
|
Timber.d("address invalid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BarcodeData(BarcodeData.Asset.BTC, address);
|
||||||
|
}
|
||||||
}
|
}
|
@@ -20,36 +20,38 @@ import android.os.Parcel;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
import com.m2049r.xmrwallet.util.UserNotes;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
||||||
public class TxData implements Parcelable {
|
public class TxData implements Parcelable {
|
||||||
|
|
||||||
|
public TxData() {
|
||||||
|
}
|
||||||
|
|
||||||
public TxData(TxData txData) {
|
public TxData(TxData txData) {
|
||||||
this.dst_addr = txData.dst_addr;
|
this.dstAddr = txData.dstAddr;
|
||||||
this.paymentId = txData.paymentId;
|
this.paymentId = txData.paymentId;
|
||||||
this.amount = txData.amount;
|
this.amount = txData.amount;
|
||||||
this.mixin = txData.mixin;
|
this.mixin = txData.mixin;
|
||||||
this.priority = txData.priority;
|
this.priority = txData.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TxData(String dst_addr,
|
public TxData(String dstAddr,
|
||||||
String paymentId,
|
String paymentId,
|
||||||
long amount,
|
long amount,
|
||||||
int mixin,
|
int mixin,
|
||||||
PendingTransaction.Priority priority) {
|
PendingTransaction.Priority priority) {
|
||||||
this.dst_addr = dst_addr;
|
this.dstAddr = dstAddr;
|
||||||
this.paymentId = paymentId;
|
this.paymentId = paymentId;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.mixin = mixin;
|
this.mixin = mixin;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFee() {
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDestinationAddress() {
|
public String getDestinationAddress() {
|
||||||
return dst_addr;
|
return dstAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPaymentId() {
|
public String getPaymentId() {
|
||||||
@@ -68,15 +70,45 @@ public class TxData implements Parcelable {
|
|||||||
return priority;
|
return priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
final private String dst_addr;
|
public void setDestinationAddress(String dstAddr) {
|
||||||
final private String paymentId;
|
this.dstAddr = dstAddr;
|
||||||
final private long amount;
|
}
|
||||||
final private int mixin;
|
|
||||||
final private PendingTransaction.Priority priority;
|
public void setPaymentId(String paymentId) {
|
||||||
|
this.paymentId = paymentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMixin(int mixin) {
|
||||||
|
this.mixin = mixin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(PendingTransaction.Priority priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserNotes getUserNotes() {
|
||||||
|
return userNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserNotes(UserNotes userNotes) {
|
||||||
|
this.userNotes = userNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String dstAddr;
|
||||||
|
private String paymentId;
|
||||||
|
private long amount;
|
||||||
|
private int mixin;
|
||||||
|
private PendingTransaction.Priority priority;
|
||||||
|
|
||||||
|
private UserNotes userNotes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel out, int flags) {
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
out.writeString(dst_addr);
|
out.writeString(dstAddr);
|
||||||
out.writeString(paymentId);
|
out.writeString(paymentId);
|
||||||
out.writeLong(amount);
|
out.writeLong(amount);
|
||||||
out.writeInt(mixin);
|
out.writeInt(mixin);
|
||||||
@@ -94,8 +126,8 @@ public class TxData implements Parcelable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private TxData(Parcel in) {
|
protected TxData(Parcel in) {
|
||||||
dst_addr = in.readString();
|
dstAddr = in.readString();
|
||||||
paymentId = in.readString();
|
paymentId = in.readString();
|
||||||
amount = in.readLong();
|
amount = in.readLong();
|
||||||
mixin = in.readInt();
|
mixin = in.readInt();
|
||||||
@@ -111,8 +143,8 @@ public class TxData implements Parcelable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append("dst_addr:");
|
sb.append("dstAddr:");
|
||||||
sb.append(dst_addr);
|
sb.append(dstAddr);
|
||||||
sb.append(",paymentId:");
|
sb.append(",paymentId:");
|
||||||
sb.append(paymentId);
|
sb.append(paymentId);
|
||||||
sb.append(",amount:");
|
sb.append(",amount:");
|
||||||
|
98
app/src/main/java/com/m2049r/xmrwallet/data/TxDataBtc.java
Normal file
98
app/src/main/java/com/m2049r/xmrwallet/data/TxDataBtc.java
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
|
||||||
|
public class TxDataBtc extends TxData {
|
||||||
|
|
||||||
|
private String xmrtoUuid;
|
||||||
|
private String btcAddress;
|
||||||
|
private double btcAmount;
|
||||||
|
|
||||||
|
public TxDataBtc() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TxDataBtc(TxDataBtc txDataBtc) {
|
||||||
|
super(txDataBtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getXmrtoUuid() {
|
||||||
|
return xmrtoUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXmrtoUuid(String xmrtoUuid) {
|
||||||
|
this.xmrtoUuid = xmrtoUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBtcAddress() {
|
||||||
|
return btcAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtcAddress(String btcAddress) {
|
||||||
|
this.btcAddress = btcAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBtcAmount() {
|
||||||
|
return btcAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtcAmount(double btcAmount) {
|
||||||
|
this.btcAmount = btcAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
super.writeToParcel(out, flags);
|
||||||
|
out.writeString(xmrtoUuid);
|
||||||
|
out.writeString(btcAddress);
|
||||||
|
out.writeDouble(btcAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
|
||||||
|
public static final Creator<TxDataBtc> CREATOR = new Creator<TxDataBtc>() {
|
||||||
|
public TxDataBtc createFromParcel(Parcel in) {
|
||||||
|
return new TxDataBtc(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TxDataBtc[] newArray(int size) {
|
||||||
|
return new TxDataBtc[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected TxDataBtc(Parcel in) {
|
||||||
|
super(in);
|
||||||
|
xmrtoUuid = in.readString();
|
||||||
|
btcAddress = in.readString();
|
||||||
|
btcAmount = in.readDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(",xmrtoUuid:");
|
||||||
|
sb.append(xmrtoUuid);
|
||||||
|
sb.append(",btcAddress:");
|
||||||
|
sb.append(btcAddress);
|
||||||
|
sb.append(",btcAmount:");
|
||||||
|
sb.append(btcAmount);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
@@ -14,13 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.TextInputLayout;
|
import android.support.design.widget.TextInputLayout;
|
||||||
import android.support.v7.widget.CardView;
|
import android.support.v7.widget.CardView;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.Html;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@@ -32,9 +33,13 @@ import android.widget.Button;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
|
import com.m2049r.xmrwallet.data.TxDataBtc;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
@@ -56,12 +61,12 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Listener {
|
public interface Listener {
|
||||||
void setAddress(final String address);
|
|
||||||
|
|
||||||
void setPaymentId(final String paymentId);
|
|
||||||
|
|
||||||
void setBarcodeData(BarcodeData data);
|
void setBarcodeData(BarcodeData data);
|
||||||
|
|
||||||
|
void setMode(SendFragment.Mode mode);
|
||||||
|
|
||||||
|
TxData getTxData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private EditText etDummy;
|
private EditText etDummy;
|
||||||
@@ -71,6 +76,8 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
private CardView cvScan;
|
private CardView cvScan;
|
||||||
private View tvPaymentIdIntegrated;
|
private View tvPaymentIdIntegrated;
|
||||||
private View llPaymentId;
|
private View llPaymentId;
|
||||||
|
private TextView tvXmrTo;
|
||||||
|
private View llXmrTo;
|
||||||
|
|
||||||
OnScanListener onScanListener;
|
OnScanListener onScanListener;
|
||||||
|
|
||||||
@@ -89,6 +96,9 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
tvPaymentIdIntegrated = view.findViewById(R.id.tvPaymentIdIntegrated);
|
tvPaymentIdIntegrated = view.findViewById(R.id.tvPaymentIdIntegrated);
|
||||||
llPaymentId = view.findViewById(R.id.llPaymentId);
|
llPaymentId = view.findViewById(R.id.llPaymentId);
|
||||||
|
llXmrTo = view.findViewById(R.id.llXmrTo);
|
||||||
|
tvXmrTo = (TextView) view.findViewById(R.id.tvXmrTo);
|
||||||
|
tvXmrTo.setText(Html.fromHtml(getString(R.string.info_xmrto)));
|
||||||
|
|
||||||
etAddress = (TextInputLayout) view.findViewById(R.id.etAddress);
|
etAddress = (TextInputLayout) view.findViewById(R.id.etAddress);
|
||||||
etAddress.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
etAddress.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
@@ -113,12 +123,25 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
public void afterTextChanged(Editable editable) {
|
public void afterTextChanged(Editable editable) {
|
||||||
etAddress.setError(null);
|
etAddress.setError(null);
|
||||||
if (isIntegratedAddress()) {
|
if (isIntegratedAddress()) {
|
||||||
|
Timber.d("isIntegratedAddress");
|
||||||
etPaymentId.getEditText().getText().clear();
|
etPaymentId.getEditText().getText().clear();
|
||||||
llPaymentId.setVisibility(View.GONE);
|
llPaymentId.setVisibility(View.INVISIBLE);
|
||||||
tvPaymentIdIntegrated.setVisibility(View.VISIBLE);
|
tvPaymentIdIntegrated.setVisibility(View.VISIBLE);
|
||||||
} else { // we don't
|
llXmrTo.setVisibility(View.INVISIBLE);
|
||||||
|
sendListener.setMode(SendFragment.Mode.XMR);
|
||||||
|
} else if (isBitcoinAddress()) {
|
||||||
|
Timber.d("isBitcoinAddress");
|
||||||
|
etPaymentId.getEditText().getText().clear();
|
||||||
|
llPaymentId.setVisibility(View.INVISIBLE);
|
||||||
|
tvPaymentIdIntegrated.setVisibility(View.INVISIBLE);
|
||||||
|
llXmrTo.setVisibility(View.VISIBLE);
|
||||||
|
sendListener.setMode(SendFragment.Mode.BTC);
|
||||||
|
} else {
|
||||||
|
Timber.d("isStandardAddress");
|
||||||
llPaymentId.setVisibility(View.VISIBLE);
|
llPaymentId.setVisibility(View.VISIBLE);
|
||||||
tvPaymentIdIntegrated.setVisibility(View.GONE);
|
tvPaymentIdIntegrated.setVisibility(View.INVISIBLE);
|
||||||
|
llXmrTo.setVisibility(View.INVISIBLE);
|
||||||
|
sendListener.setMode(SendFragment.Mode.XMR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,13 +211,14 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
private boolean checkAddressNoError() {
|
private boolean checkAddressNoError() {
|
||||||
String address = etAddress.getEditText().getText().toString();
|
String address = etAddress.getEditText().getText().toString();
|
||||||
return Wallet.isAddressValid(address);
|
return Wallet.isAddressValid(address)
|
||||||
|
|| BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkAddress() {
|
private boolean checkAddress() {
|
||||||
boolean ok = checkAddressNoError();
|
boolean ok = checkAddressNoError();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
etAddress.setError(getString(R.string.send_qr_address_invalid));
|
etAddress.setError(getString(R.string.send_address_invalid));
|
||||||
} else {
|
} else {
|
||||||
etAddress.setError(null);
|
etAddress.setError(null);
|
||||||
}
|
}
|
||||||
@@ -203,7 +227,16 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
private boolean isIntegratedAddress() {
|
private boolean isIntegratedAddress() {
|
||||||
String address = etAddress.getEditText().getText().toString();
|
String address = etAddress.getEditText().getText().toString();
|
||||||
return (address.length() == INTEGRATED_ADDRESS_LENGTH) && Wallet.isAddressValid(address);
|
return (address.length() == INTEGRATED_ADDRESS_LENGTH)
|
||||||
|
&& Wallet.isAddressValid(address, WalletManager.getInstance().isTestNet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBitcoinAddress() {
|
||||||
|
String address = etAddress.getEditText().getText().toString();
|
||||||
|
if ((address.length() >= 27) && (address.length() <= 34))
|
||||||
|
return BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet());
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkPaymentId() {
|
private boolean checkPaymentId() {
|
||||||
@@ -235,8 +268,15 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
}
|
}
|
||||||
if (!ok) return false;
|
if (!ok) return false;
|
||||||
if (sendListener != null) {
|
if (sendListener != null) {
|
||||||
sendListener.setAddress(etAddress.getEditText().getText().toString());
|
TxData txData = sendListener.getTxData();
|
||||||
sendListener.setPaymentId(etPaymentId.getEditText().getText().toString());
|
if (isBitcoinAddress()) {
|
||||||
|
((TxDataBtc) txData).setBtcAddress(etAddress.getEditText().getText().toString());
|
||||||
|
txData.setDestinationAddress(null);
|
||||||
|
txData.setPaymentId("");
|
||||||
|
} else {
|
||||||
|
txData.setDestinationAddress(etAddress.getEditText().getText().toString());
|
||||||
|
txData.setPaymentId(etPaymentId.getEditText().getText().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -22,10 +22,12 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.widget.ExchangeTextView;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.widget.ExchangeTextView;
|
||||||
import com.m2049r.xmrwallet.widget.NumberPadView;
|
import com.m2049r.xmrwallet.widget.NumberPadView;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
@@ -48,7 +50,7 @@ public class SendAmountWizardFragment extends SendWizardFragment {
|
|||||||
interface Listener {
|
interface Listener {
|
||||||
SendFragment.Listener getActivityCallback();
|
SendFragment.Listener getActivityCallback();
|
||||||
|
|
||||||
void setAmount(final long amount);
|
TxData getTxData();
|
||||||
|
|
||||||
BarcodeData popBarcodeData();
|
BarcodeData popBarcodeData();
|
||||||
}
|
}
|
||||||
@@ -99,9 +101,9 @@ public class SendAmountWizardFragment extends SendWizardFragment {
|
|||||||
if (sendListener != null) {
|
if (sendListener != null) {
|
||||||
String xmr = evAmount.getAmount();
|
String xmr = evAmount.getAmount();
|
||||||
if (xmr != null) {
|
if (xmr != null) {
|
||||||
sendListener.setAmount(Wallet.getAmountFromString(xmr));
|
sendListener.getTxData().setAmount(Wallet.getAmountFromString(xmr));
|
||||||
} else {
|
} else {
|
||||||
sendListener.setAmount(0L);
|
sendListener.getTxData().setAmount(0L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
|
||||||
|
interface SendConfirm {
|
||||||
|
void sendFailed();
|
||||||
|
|
||||||
|
void createTransactionFailed(String errorText);
|
||||||
|
|
||||||
|
void transactionCreated(String txTag, PendingTransaction pendingTransaction);
|
||||||
|
}
|
@@ -14,12 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.TextInputLayout;
|
import android.support.design.widget.TextInputLayout;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@@ -30,14 +31,16 @@ import android.view.inputmethod.EditorInfo;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.UserNotes;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class SendConfirmWizardFragment extends SendWizardFragment {
|
public class SendConfirmWizardFragment extends SendWizardFragment implements SendConfirm {
|
||||||
|
|
||||||
public static SendConfirmWizardFragment newInstance(Listener listener) {
|
public static SendConfirmWizardFragment newInstance(Listener listener) {
|
||||||
SendConfirmWizardFragment instance = new SendConfirmWizardFragment();
|
SendConfirmWizardFragment instance = new SendConfirmWizardFragment();
|
||||||
@@ -57,11 +60,11 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
TxData getTxData();
|
TxData getTxData();
|
||||||
|
|
||||||
String getNotes();
|
|
||||||
|
|
||||||
void commitTransaction();
|
void commitTransaction();
|
||||||
|
|
||||||
void disposeTransaction();
|
void disposeTransaction();
|
||||||
|
|
||||||
|
SendFragment.Mode getMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextView tvTxAddress;
|
private TextView tvTxAddress;
|
||||||
@@ -122,8 +125,11 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
PendingTransaction pendingTransaction = null;
|
PendingTransaction pendingTransaction = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
// callback from wallet when PendingTransaction created
|
// callback from wallet when PendingTransaction created
|
||||||
void transactionCreated(PendingTransaction pendingTransaction) {
|
public void transactionCreated(String txTag, PendingTransaction pendingTransaction) {
|
||||||
|
// ignore txTag - the app flow ensures this is the correct tx
|
||||||
|
// TODO: use the txTag
|
||||||
hideProgress();
|
hideProgress();
|
||||||
if (isResumed) {
|
if (isResumed) {
|
||||||
this.pendingTransaction = pendingTransaction;
|
this.pendingTransaction = pendingTransaction;
|
||||||
@@ -138,10 +144,22 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
|||||||
pbProgressSend.setVisibility(View.VISIBLE);
|
pbProgressSend.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendFailed() {
|
@Override
|
||||||
|
public void sendFailed() {
|
||||||
pbProgressSend.setVisibility(View.INVISIBLE);
|
pbProgressSend.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createTransactionFailed(String errorText) {
|
||||||
|
hideProgress();
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
|
builder.setCancelable(true).
|
||||||
|
setTitle(getString(R.string.send_create_tx_error_title)).
|
||||||
|
setMessage(errorText).
|
||||||
|
create().
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onValidateFields() {
|
public boolean onValidateFields() {
|
||||||
return true;
|
return true;
|
||||||
@@ -173,9 +191,9 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
|||||||
} else {
|
} else {
|
||||||
tvTxPaymentId.setText("-");
|
tvTxPaymentId.setText("-");
|
||||||
}
|
}
|
||||||
String notes = sendListener.getNotes();
|
UserNotes notes = sendListener.getTxData().getUserNotes();
|
||||||
if ((notes != null) && (!notes.isEmpty())) {
|
if ((notes != null) && (!notes.note.isEmpty())) {
|
||||||
tvTxNotes.setText(sendListener.getNotes());
|
tvTxNotes.setText(notes.note);
|
||||||
} else {
|
} else {
|
||||||
tvTxNotes.setText("-");
|
tvTxNotes.setText("-");
|
||||||
}
|
}
|
||||||
@@ -232,7 +250,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
alertDialogBuilder
|
alertDialogBuilder
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
.setPositiveButton(getString(R.string.label_ok), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
String pass = etPassword.getEditText().getText().toString();
|
String pass = etPassword.getEditText().getText().toString();
|
||||||
if (getActivityCallback().verifyWalletPassword(pass)) {
|
if (getActivityCallback().verifyWalletPassword(pass)) {
|
||||||
@@ -244,7 +262,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setNegativeButton("Cancel",
|
.setNegativeButton(getString(R.string.label_cancel),
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
Helper.hideKeyboardAlways(activity);
|
Helper.hideKeyboardAlways(activity);
|
||||||
@@ -296,8 +314,10 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
|||||||
passwordDialog.show();
|
passwordDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// creates a pending transaction and calls us back with transactionCreated()
|
||||||
|
// or createTransactionFailed()
|
||||||
void prepareSend(TxData txData) {
|
void prepareSend(TxData txData) {
|
||||||
getActivityCallback().onPrepareSend(txData);
|
getActivityCallback().onPrepareSend(null, txData);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendFragment.Listener getActivityCallback() {
|
SendFragment.Listener getActivityCallback() {
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
@@ -27,8 +27,11 @@ import android.widget.EditText;
|
|||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.R;
|
||||||
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.UserNotes;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
@@ -48,12 +51,7 @@ public class SendSettingsWizardFragment extends SendWizardFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
|
TxData getTxData();
|
||||||
void setPriority(final PendingTransaction.Priority priority);
|
|
||||||
|
|
||||||
void setMixin(final int mixin);
|
|
||||||
|
|
||||||
void setNotes(final String notes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final static int Mixins[] = {4, 7, 12, 25}; // must match the layout XML
|
final static int Mixins[] = {4, 7, 12, 25}; // must match the layout XML
|
||||||
@@ -103,13 +101,10 @@ public class SendSettingsWizardFragment extends SendWizardFragment {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onValidateFields() {
|
public boolean onValidateFields() {
|
||||||
if (sendListener != null) {
|
if (sendListener != null) {
|
||||||
int mixin = Mixins[sMixin.getSelectedItemPosition()];
|
TxData txData = sendListener.getTxData();
|
||||||
int priorityIndex = sPriority.getSelectedItemPosition();
|
txData.setPriority(Priorities[sPriority.getSelectedItemPosition()]);
|
||||||
PendingTransaction.Priority priority = Priorities[priorityIndex];
|
txData.setMixin(Mixins[sMixin.getSelectedItemPosition()]);
|
||||||
sendListener.setPriority(priority);
|
txData.setUserNotes(new UserNotes(etNotes.getText().toString()));
|
||||||
sendListener.setMixin(mixin);
|
|
||||||
String notes = etNotes.getText().toString();
|
|
||||||
sendListener.setNotes(notes);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -24,10 +24,10 @@ import android.widget.ImageButton;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
|
||||||
import com.m2049r.xmrwallet.data.PendingTx;
|
import com.m2049r.xmrwallet.data.PendingTx;
|
||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
@@ -47,23 +47,21 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
String getNotes();
|
|
||||||
|
|
||||||
TxData getTxData();
|
TxData getTxData();
|
||||||
|
|
||||||
PendingTx getCommittedTx();
|
PendingTx getCommittedTx();
|
||||||
|
|
||||||
void enableDone();
|
void enableDone();
|
||||||
|
|
||||||
|
SendFragment.Mode getMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButton bCopyAddress;
|
ImageButton bCopyTxId;
|
||||||
private TextView tvTxId;
|
private TextView tvTxId;
|
||||||
private TextView tvTxAddress;
|
private TextView tvTxAddress;
|
||||||
private TextView tvTxPaymentId;
|
private TextView tvTxPaymentId;
|
||||||
private TextView tvTxNotes;
|
|
||||||
private TextView tvTxAmount;
|
private TextView tvTxAmount;
|
||||||
private TextView tvTxFee;
|
private TextView tvTxFee;
|
||||||
private TextView tvTxTotal;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
@@ -74,21 +72,20 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
|
|||||||
View view = inflater.inflate(
|
View view = inflater.inflate(
|
||||||
R.layout.fragment_send_success, container, false);
|
R.layout.fragment_send_success, container, false);
|
||||||
|
|
||||||
bCopyAddress = (ImageButton) view.findViewById(R.id.bCopyAddress);
|
bCopyTxId = (ImageButton) view.findViewById(R.id.bCopyTxId);
|
||||||
bCopyAddress.setOnClickListener(new View.OnClickListener() {
|
bCopyTxId.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
copyAddress();
|
Helper.clipBoardCopy(getActivity(), getString(R.string.label_send_txid), tvTxId.getText().toString());
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||||
tvTxAddress = (TextView) view.findViewById(R.id.tvTxAddress);
|
tvTxAddress = (TextView) view.findViewById(R.id.tvTxAddress);
|
||||||
tvTxPaymentId = (TextView) view.findViewById(R.id.tvTxPaymentId);
|
tvTxPaymentId = (TextView) view.findViewById(R.id.tvTxPaymentId);
|
||||||
tvTxNotes = (TextView) view.findViewById(R.id.tvTxNotes);
|
|
||||||
tvTxAmount = ((TextView) view.findViewById(R.id.tvTxAmount));
|
tvTxAmount = ((TextView) view.findViewById(R.id.tvTxAmount));
|
||||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||||
tvTxTotal = (TextView) view.findViewById(R.id.tvTxTotal);
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@@ -117,30 +114,15 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
|
|||||||
} else {
|
} else {
|
||||||
tvTxPaymentId.setText("-");
|
tvTxPaymentId.setText("-");
|
||||||
}
|
}
|
||||||
String notes = sendListener.getNotes();
|
|
||||||
if ((notes != null) && (!notes.isEmpty())) {
|
|
||||||
tvTxNotes.setText(sendListener.getNotes());
|
|
||||||
} else {
|
|
||||||
tvTxNotes.setText("-");
|
|
||||||
}
|
|
||||||
|
|
||||||
final PendingTx committedTx = sendListener.getCommittedTx();
|
final PendingTx committedTx = sendListener.getCommittedTx();
|
||||||
if (committedTx != null) {
|
if (committedTx != null) {
|
||||||
tvTxId.setText(committedTx.txId);
|
tvTxId.setText(committedTx.txId);
|
||||||
bCopyAddress.setEnabled(true);
|
bCopyTxId.setEnabled(true);
|
||||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
bCopyTxId.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||||
tvTxAmount.setText(Wallet.getDisplayAmount(committedTx.amount));
|
tvTxAmount.setText(getString(R.string.send_amount, Helper.getDisplayAmount(committedTx.amount)));
|
||||||
tvTxFee.setText(Wallet.getDisplayAmount(committedTx.fee));
|
tvTxFee.setText(getString(R.string.send_fee, Helper.getDisplayAmount(committedTx.fee)));
|
||||||
//tvTxDust.setText(Wallet.getDisplayAmount(pendingTransaction.getDust()));
|
|
||||||
tvTxTotal.setText(Wallet.getDisplayAmount(
|
|
||||||
committedTx.fee + committedTx.amount));
|
|
||||||
}
|
}
|
||||||
sendListener.enableDone();
|
sendListener.enableDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyAddress() {
|
|
||||||
Helper.clipBoardCopy(getActivity(), getString(R.string.label_send_txid), tvTxId.getText().toString());
|
|
||||||
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user