mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-04 00:53:36 +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.
|
||||
|
||||
### 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)
|
||||
- works on the testnet & mainnet
|
||||
- sync is slow due to 32-bit architecture
|
||||
- use your own daemon - it's easy
|
||||
- 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/
|
||||
|
||||
### TODO
|
||||
- more sensible error dialogs
|
||||
- see taiga.getmonero.org & issues on github
|
||||
|
||||
### Issues / Pitfalls
|
||||
- The backups folder is now called "backups" and not ".backups" - which in most file explorers was a hidden folder
|
||||
- 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.
|
||||
- You should backup your wallet files in the "monerujo" folder periodically.
|
||||
- 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
|
||||
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:
|
||||
|
||||
- openssl-1.0.2l
|
||||
- monero-v0.11.0.0 + pull requests #2289
|
||||
- monero-v0.11.1.0
|
||||
- boost_1_64_0
|
||||
|
||||
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"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
versionCode 51
|
||||
versionName "1.2.11"
|
||||
versionCode 70
|
||||
versionName "1.3.10 'Satoshis Dream'"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
@@ -27,6 +27,9 @@ android {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
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
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject instance,
|
||||
jstring path, jstring mnemonic,
|
||||
jstring path, jstring password,
|
||||
jstring mnemonic,
|
||||
jboolean isTestNet,
|
||||
jlong restoreHeight) {
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||
const char *_mnemonic = env->GetStringUTFChars(mnemonic, NULL);
|
||||
|
||||
Bitmonero::Wallet *wallet =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
||||
std::string(_path),
|
||||
std::string(_password),
|
||||
std::string(_mnemonic),
|
||||
isTestNet,
|
||||
restoreHeight);
|
||||
|
||||
env->ReleaseStringUTFChars(path, _path);
|
||||
env->ReleaseStringUTFChars(password, _password);
|
||||
env->ReleaseStringUTFChars(mnemonic, _mnemonic);
|
||||
return reinterpret_cast<jlong>(wallet);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env, jobject instance,
|
||||
jstring path, jstring language,
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletWithKeysJ(JNIEnv *env, jobject instance,
|
||||
jstring path, jstring password,
|
||||
jstring language,
|
||||
jboolean isTestNet,
|
||||
jlong restoreHeight,
|
||||
jstring addressString,
|
||||
jstring viewKeyString,
|
||||
jstring spendKeyString) {
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||
const char *_addressString = env->GetStringUTFChars(addressString, NULL);
|
||||
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, NULL);
|
||||
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, NULL);
|
||||
|
||||
Bitmonero::Wallet *wallet =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletWithKeys(
|
||||
std::string(_path),
|
||||
std::string(_password),
|
||||
std::string(_language),
|
||||
isTestNet,
|
||||
restoreHeight,
|
||||
@@ -334,6 +341,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env,
|
||||
std::string(_spendKeyString));
|
||||
|
||||
env->ReleaseStringUTFChars(path, _path);
|
||||
env->ReleaseStringUTFChars(password, _password);
|
||||
env->ReleaseStringUTFChars(language, _language);
|
||||
env->ReleaseStringUTFChars(addressString, _addressString);
|
||||
env->ReleaseStringUTFChars(viewKeyString, _viewKeyString);
|
||||
|
@@ -103,6 +103,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||
copyAddress();
|
||||
}
|
||||
});
|
||||
bCopyAddress.setClickable(false);
|
||||
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -213,7 +214,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||
tvWalletViewKey.setText(viewKey);
|
||||
tvWalletSpendKey.setText(spendKey);
|
||||
bAdvancedInfo.setVisibility(View.VISIBLE);
|
||||
bCopyAddress.setEnabled(true);
|
||||
bCopyAddress.setClickable(true);
|
||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||
activityCallback.setToolbarButton(
|
||||
|
@@ -278,7 +278,7 @@ public class LoginActivity extends SecureActivity
|
||||
// set dialog message
|
||||
alertDialogBuilder
|
||||
.setCancelable(false)
|
||||
.setPositiveButton("OK",
|
||||
.setPositiveButton(getString(R.string.label_ok),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
Helper.hideKeyboardAlways(LoginActivity.this);
|
||||
@@ -286,7 +286,7 @@ public class LoginActivity extends SecureActivity
|
||||
new AsyncRename().execute(walletName, newName);
|
||||
}
|
||||
})
|
||||
.setNegativeButton("Cancel",
|
||||
.setNegativeButton(getString(R.string.label_cancel),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
Helper.hideKeyboardAlways(LoginActivity.this);
|
||||
@@ -482,8 +482,8 @@ public class LoginActivity extends SecureActivity
|
||||
// set dialog message
|
||||
alertDialogBuilder
|
||||
.setCancelable(false)
|
||||
.setPositiveButton("OK", null)
|
||||
.setNegativeButton("Cancel",
|
||||
.setPositiveButton(getString(R.string.label_ok), null)
|
||||
.setNegativeButton(getString(R.string.label_cancel),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
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
|
||||
|
||||
private class AsyncCreateWallet extends AsyncTask<Void, Void, Boolean> {
|
||||
String walletName;
|
||||
String walletPassword;
|
||||
WalletCreator walletCreator;
|
||||
final String walletName;
|
||||
final String walletPassword;
|
||||
final WalletCreator walletCreator;
|
||||
|
||||
File newWalletFile;
|
||||
|
||||
public AsyncCreateWallet(String name, String password, WalletCreator walletCreator) {
|
||||
public AsyncCreateWallet(final String name, final String password,
|
||||
final WalletCreator walletCreator) {
|
||||
super();
|
||||
this.walletName = name;
|
||||
this.walletPassword = password;
|
||||
@@ -814,12 +815,7 @@ public class LoginActivity extends SecureActivity
|
||||
return false;
|
||||
}
|
||||
|
||||
File newWalletFolder = Helper.getNewWalletDir(getApplicationContext());
|
||||
if (!newWalletFolder.isDirectory()) {
|
||||
Timber.e("New Wallet dir " + newWalletFolder.getAbsolutePath() + "is not a directory");
|
||||
return false;
|
||||
}
|
||||
newWalletFile = new File(newWalletFolder, walletName);
|
||||
newWalletFile = new File(walletFolder, walletName);
|
||||
boolean success = walletCreator.createWallet(newWalletFile, walletPassword);
|
||||
if (success) {
|
||||
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)
|
||||
.executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
@@ -865,7 +862,7 @@ public class LoginActivity extends SecureActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGenerate(String name, String password) {
|
||||
public void onGenerate(final String name, final String password) {
|
||||
createWallet(name, password,
|
||||
new WalletCreator() {
|
||||
public boolean createWallet(File aFile, String password) {
|
||||
@@ -883,16 +880,15 @@ public class LoginActivity extends SecureActivity
|
||||
}
|
||||
|
||||
@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,
|
||||
new WalletCreator() {
|
||||
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);
|
||||
if (success) {
|
||||
newWallet.setPassword(password);
|
||||
success = success && newWallet.store();
|
||||
} else {
|
||||
if (!success) {
|
||||
Timber.e(newWallet.getErrorString());
|
||||
toast(newWallet.getErrorString());
|
||||
}
|
||||
@@ -903,19 +899,17 @@ public class LoginActivity extends SecureActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGenerate(String name, String password,
|
||||
final String address, final String viewKey, final String spendKey, final long restoreHeight) {
|
||||
public void onGenerate(final String name, final String password,
|
||||
final String address, final String viewKey, final String spendKey,
|
||||
final long restoreHeight) {
|
||||
createWallet(name, password,
|
||||
new WalletCreator() {
|
||||
public boolean createWallet(File aFile, String password) {
|
||||
Wallet newWallet = WalletManager.getInstance()
|
||||
.createWalletFromKeys(aFile, MNEMONIC_LANGUAGE, restoreHeight,
|
||||
.createWalletWithKeys(aFile, password, MNEMONIC_LANGUAGE, restoreHeight,
|
||||
address, viewKey, spendKey);
|
||||
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
|
||||
if (success) {
|
||||
newWallet.setPassword(password);
|
||||
success = success && newWallet.store();
|
||||
} else {
|
||||
if (!success) {
|
||||
Timber.e(newWallet.getErrorString());
|
||||
toast(newWallet.getErrorString());
|
||||
}
|
||||
@@ -936,16 +930,10 @@ public class LoginActivity extends SecureActivity
|
||||
|
||||
@Override
|
||||
public void onAccept(final String name, final String password) {
|
||||
File newWalletFile = new File(Helper.getNewWalletDir(getApplicationContext()), name);
|
||||
Timber.d("New Wallet %s", newWalletFile.getAbsolutePath());
|
||||
newWalletFile.delete(); // when recovering wallets, the cache seems corrupt
|
||||
// TODO: figure out why this is so? Only for a private testnet?
|
||||
|
||||
// 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)
|
||||
File walletFolder = getStorageRoot();
|
||||
File walletFile = new File(walletFolder, name);
|
||||
Timber.d("New Wallet %s", walletFile.getAbsolutePath());
|
||||
walletFile.delete(); // when recovering wallets, the cache seems corrupt
|
||||
|
||||
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.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
@@ -61,15 +62,18 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
|
||||
private WalletInfoAdapter adapter;
|
||||
|
||||
List<WalletManager.WalletInfo> walletList = new ArrayList<>();
|
||||
List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
|
||||
private List<WalletManager.WalletInfo> walletList = new ArrayList<>();
|
||||
private List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
|
||||
|
||||
EditText etDummy;
|
||||
ImageView ivGunther;
|
||||
DropDownEditText etDaemonAddress;
|
||||
ArrayAdapter<String> nodeAdapter;
|
||||
private EditText etDummy;
|
||||
private ImageView ivGunther;
|
||||
private DropDownEditText etDaemonAddress;
|
||||
private ArrayAdapter<String> nodeAdapter;
|
||||
|
||||
Listener activityCallback;
|
||||
private View llXmrToEnabled;
|
||||
private View ibXmrToInfoClose;
|
||||
|
||||
private Listener activityCallback;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface Listener {
|
||||
@@ -165,6 +169,25 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
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);
|
||||
nodeAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_dropdown_item_1line);
|
||||
etDaemonAddress.setAdapter(nodeAdapter);
|
||||
@@ -211,6 +234,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
});
|
||||
|
||||
loadPrefs();
|
||||
if (!showXmrtoEnabled) {
|
||||
llXmrToEnabled.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
@@ -290,9 +316,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
activityCallback.onWalletDetails(name, isTestnet());
|
||||
}
|
||||
|
||||
private boolean showReceive(@NonNull String name) {
|
||||
private void showReceive(@NonNull String name) {
|
||||
activityCallback.onWalletReceive(name, isTestnet());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,7 +333,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
boolean testnet = false;
|
||||
private boolean testnet = BuildConfig.DEBUG;
|
||||
|
||||
boolean isTestnet() {
|
||||
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_MAINNET = "daemon_mainnet";
|
||||
private static final String PREF_SHOW_XMRTO_ENABLED = "info_xmrto_enabled_login";
|
||||
|
||||
private static final String PREF_DAEMONLIST_MAINNET =
|
||||
"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 daemonMainNet;
|
||||
|
||||
boolean showXmrtoEnabled = true;
|
||||
|
||||
void loadPrefs() {
|
||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
||||
|
||||
daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET));
|
||||
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, PREF_DAEMONLIST_TESTNET));
|
||||
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() {
|
||||
savePrefs(false);
|
||||
}
|
||||
|
||||
void savePrefs(boolean usePreviousState) {
|
||||
Timber.d("SAVE / %s", usePreviousState);
|
||||
void savePrefs(boolean usePreviousTestnetState) {
|
||||
Timber.d("SAVE / %s", usePreviousTestnetState);
|
||||
// save the daemon address for the net
|
||||
boolean testnet = isTestnet() ^ usePreviousState;
|
||||
boolean testnet = isTestnet() ^ usePreviousTestnetState;
|
||||
String daemon = getDaemon();
|
||||
if (testnet) {
|
||||
daemonTestNet.setRecent(daemon);
|
||||
@@ -373,6 +410,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putString(PREF_DAEMON_MAINNET, daemonMainNet.toString());
|
||||
editor.putString(PREF_DAEMON_TESTNET, daemonTestNet.toString());
|
||||
editor.putBoolean(PREF_SHOW_XMRTO_ENABLED, showXmrtoEnabled);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
|
@@ -46,6 +46,7 @@ import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
@@ -105,6 +106,7 @@ public class ReceiveFragment extends Fragment {
|
||||
copyAddress();
|
||||
}
|
||||
});
|
||||
bCopyAddress.setClickable(false);
|
||||
|
||||
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
|
||||
@Override
|
||||
@@ -239,7 +241,7 @@ public class ReceiveFragment extends Fragment {
|
||||
tvAddress.setText(address);
|
||||
etPaymentId.setEnabled(true);
|
||||
bPaymentId.setEnabled(true);
|
||||
bCopyAddress.setEnabled(true);
|
||||
bCopyAddress.setClickable(true);
|
||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||
hideProgress();
|
||||
generateQr();
|
||||
@@ -304,14 +306,14 @@ public class ReceiveFragment extends Fragment {
|
||||
return;
|
||||
}
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(ScannerFragment.QR_SCHEME).append(address);
|
||||
sb.append(BarcodeData.XMR_SCHEME).append(address);
|
||||
boolean first = true;
|
||||
if (!paymentId.isEmpty()) {
|
||||
if (first) {
|
||||
sb.append("?");
|
||||
first = false;
|
||||
}
|
||||
sb.append(ScannerFragment.QR_PAYMENTID).append('=').append(paymentId);
|
||||
sb.append(BarcodeData.XMR_PAYMENTID).append('=').append(paymentId);
|
||||
}
|
||||
if (!xmrAmount.isEmpty()) {
|
||||
if (first) {
|
||||
@@ -319,7 +321,7 @@ public class ReceiveFragment extends Fragment {
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(ScannerFragment.QR_AMOUNT).append('=').append(xmrAmount);
|
||||
sb.append(BarcodeData.XMR_AMOUNT).append('=').append(xmrAmount);
|
||||
}
|
||||
String text = sb.toString();
|
||||
int size = Math.min(qrCode.getHeight(), qrCode.getWidth());
|
||||
|
@@ -36,7 +36,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
private OnScannedListener onScannedListener;
|
||||
|
||||
public interface OnScannedListener {
|
||||
boolean onScanned(String uri);
|
||||
boolean onScanned(String qrCode);
|
||||
}
|
||||
|
||||
private ZXingScannerView mScannerView;
|
||||
@@ -56,10 +56,6 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
mScannerView.startCamera();
|
||||
}
|
||||
|
||||
static final String QR_SCHEME = "monero:";
|
||||
static final String QR_PAYMENTID = "tx_payment_id";
|
||||
static final String QR_AMOUNT = "tx_amount";
|
||||
|
||||
@Override
|
||||
public void handleResult(Result rawResult) {
|
||||
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE)) {
|
||||
|
@@ -20,6 +20,10 @@ import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams;
|
||||
|
||||
public abstract class SecureActivity extends AppCompatActivity {
|
||||
|
@@ -30,10 +30,13 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Transfer;
|
||||
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 java.text.SimpleDateFormat;
|
||||
@@ -68,12 +71,23 @@ public class TxFragment extends Fragment {
|
||||
private TextView etTxNotes;
|
||||
private Button bTxNotes;
|
||||
|
||||
// XMRTO stuff
|
||||
private View cvXmrTo;
|
||||
private TextView tvTxXmrToKey;
|
||||
private TextView tvDestinationBtc;
|
||||
private TextView tvTxAmountBtc;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
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);
|
||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||
tvTxKey = (TextView) view.findViewById(R.id.tvTxKey);
|
||||
@@ -94,7 +108,16 @@ public class TxFragment extends Fragment {
|
||||
info.notes = null; // force reload on next view
|
||||
bTxNotes.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;
|
||||
UserNotes userNotes = null;
|
||||
|
||||
void loadNotes(TransactionInfo info) {
|
||||
if (info.notes == null) {
|
||||
if ((userNotes == null) || (info.notes == null)) {
|
||||
info.notes = activityCallback.getTxNotes(info.hash);
|
||||
}
|
||||
etTxNotes.setText(info.notes);
|
||||
userNotes = new UserNotes(info.notes);
|
||||
etTxNotes.setText(userNotes.note);
|
||||
}
|
||||
|
||||
private void setTxColour(int clr) {
|
||||
@@ -266,8 +291,21 @@ public class TxFragment extends Fragment {
|
||||
tvTxTransfers.setText(sb.toString());
|
||||
tvDestination.setText(dstSb.toString());
|
||||
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
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@@ -22,8 +22,8 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
@@ -38,17 +38,18 @@ import com.m2049r.xmrwallet.data.BarcodeData;
|
||||
import com.m2049r.xmrwallet.data.TxData;
|
||||
import com.m2049r.xmrwallet.dialog.DonationFragment;
|
||||
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.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.service.WalletService;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.UserNotes;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
@@ -140,6 +141,9 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Timber.d("onDestroy()");
|
||||
if ((mBoundService != null) && !isSynced() && (getWallet() != null)) {
|
||||
saveWallet();
|
||||
}
|
||||
stopWalletService();
|
||||
super.onDestroy();
|
||||
}
|
||||
@@ -465,7 +469,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionCreated(final PendingTransaction pendingTransaction) {
|
||||
public void onTransactionCreated(final String txTag, final PendingTransaction pendingTransaction) {
|
||||
try {
|
||||
final SendFragment sendFragment = (SendFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
@@ -477,7 +481,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
getWallet().disposePendingTransaction();
|
||||
sendFragment.onCreateTransactionFailed(errorText);
|
||||
} else {
|
||||
sendFragment.onTransactionCreated(pendingTransaction);
|
||||
sendFragment.onTransactionCreated(txTag, pendingTransaction);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -560,19 +564,20 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
|
||||
@Override
|
||||
public void onProgress(final int n) {
|
||||
try {
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
walletFragment.setProgress(n);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
||||
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() {
|
||||
@@ -588,11 +593,11 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
///////////////////////////
|
||||
|
||||
@Override
|
||||
public void onSend(String notes) {
|
||||
public void onSend(UserNotes notes) {
|
||||
if (mIsBound) { // no point in talking to unbound service
|
||||
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
||||
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);
|
||||
Timber.d("SEND TX request sent");
|
||||
} else {
|
||||
@@ -617,11 +622,12 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareSend(TxData txData) {
|
||||
public void onPrepareSend(final String tag, final TxData txData) {
|
||||
if (mIsBound) { // no point in talking to unbound service
|
||||
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
||||
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_TX);
|
||||
intent.putExtra(WalletService.REQUEST_CMD_TX_DATA, txData);
|
||||
intent.putExtra(WalletService.REQUEST_CMD_TX_TAG, tag);
|
||||
startService(intent);
|
||||
Timber.d("CREATE TX request sent");
|
||||
} else {
|
||||
@@ -694,6 +700,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
|
||||
@Override
|
||||
public void onDisposeRequest() {
|
||||
//TODO consider doing this through the WalletService to avoid concurrency issues
|
||||
getWallet().disposePendingTransaction();
|
||||
}
|
||||
|
||||
@@ -804,9 +811,6 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
super.onBackPressed();
|
||||
}
|
||||
} else {
|
||||
if (!isSynced()) {
|
||||
saveWallet();
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
@@ -815,4 +819,10 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
public void onFragmentDone() {
|
||||
popFragmentStack(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SharedPreferences getPrefs() {
|
||||
return getPreferences(Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -313,7 +313,7 @@ public class WalletFragment extends Fragment
|
||||
if (wallet == null) return;
|
||||
walletTitle = wallet.getName();
|
||||
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);
|
||||
Timber.d("wallet title is %s", walletTitle);
|
||||
}
|
||||
|
@@ -19,6 +19,8 @@ package com.m2049r.xmrwallet.data;
|
||||
import android.net.Uri;
|
||||
|
||||
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.Map;
|
||||
@@ -34,7 +36,7 @@ public class BarcodeData {
|
||||
static final String BTC_AMOUNT = "amount";
|
||||
|
||||
public enum Asset {
|
||||
XMR
|
||||
XMR, BTC
|
||||
}
|
||||
|
||||
public Asset asset = null;
|
||||
@@ -67,6 +69,14 @@ public class BarcodeData {
|
||||
if (bcData == null) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -134,4 +144,57 @@ public class BarcodeData {
|
||||
|
||||
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 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
|
||||
public class TxData implements Parcelable {
|
||||
|
||||
public TxData() {
|
||||
}
|
||||
|
||||
public TxData(TxData txData) {
|
||||
this.dst_addr = txData.dst_addr;
|
||||
this.dstAddr = txData.dstAddr;
|
||||
this.paymentId = txData.paymentId;
|
||||
this.amount = txData.amount;
|
||||
this.mixin = txData.mixin;
|
||||
this.priority = txData.priority;
|
||||
}
|
||||
|
||||
public TxData(String dst_addr,
|
||||
public TxData(String dstAddr,
|
||||
String paymentId,
|
||||
long amount,
|
||||
int mixin,
|
||||
PendingTransaction.Priority priority) {
|
||||
this.dst_addr = dst_addr;
|
||||
this.dstAddr = dstAddr;
|
||||
this.paymentId = paymentId;
|
||||
this.amount = amount;
|
||||
this.mixin = mixin;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public long getFee() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public String getDestinationAddress() {
|
||||
return dst_addr;
|
||||
return dstAddr;
|
||||
}
|
||||
|
||||
public String getPaymentId() {
|
||||
@@ -68,15 +70,45 @@ public class TxData implements Parcelable {
|
||||
return priority;
|
||||
}
|
||||
|
||||
final private String dst_addr;
|
||||
final private String paymentId;
|
||||
final private long amount;
|
||||
final private int mixin;
|
||||
final private PendingTransaction.Priority priority;
|
||||
public void setDestinationAddress(String dstAddr) {
|
||||
this.dstAddr = dstAddr;
|
||||
}
|
||||
|
||||
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
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(dst_addr);
|
||||
out.writeString(dstAddr);
|
||||
out.writeString(paymentId);
|
||||
out.writeLong(amount);
|
||||
out.writeInt(mixin);
|
||||
@@ -94,8 +126,8 @@ public class TxData implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
private TxData(Parcel in) {
|
||||
dst_addr = in.readString();
|
||||
protected TxData(Parcel in) {
|
||||
dstAddr = in.readString();
|
||||
paymentId = in.readString();
|
||||
amount = in.readLong();
|
||||
mixin = in.readInt();
|
||||
@@ -111,8 +143,8 @@ public class TxData implements Parcelable {
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("dst_addr:");
|
||||
sb.append(dst_addr);
|
||||
sb.append("dstAddr:");
|
||||
sb.append(dstAddr);
|
||||
sb.append(",paymentId:");
|
||||
sb.append(paymentId);
|
||||
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.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
package com.m2049r.xmrwallet.fragment.send;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
@@ -32,9 +33,13 @@ import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.R;
|
||||
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.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import timber.log.Timber;
|
||||
@@ -56,12 +61,12 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||
return this;
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
void setAddress(final String address);
|
||||
|
||||
void setPaymentId(final String paymentId);
|
||||
|
||||
public interface Listener {
|
||||
void setBarcodeData(BarcodeData data);
|
||||
|
||||
void setMode(SendFragment.Mode mode);
|
||||
|
||||
TxData getTxData();
|
||||
}
|
||||
|
||||
private EditText etDummy;
|
||||
@@ -71,6 +76,8 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||
private CardView cvScan;
|
||||
private View tvPaymentIdIntegrated;
|
||||
private View llPaymentId;
|
||||
private TextView tvXmrTo;
|
||||
private View llXmrTo;
|
||||
|
||||
OnScanListener onScanListener;
|
||||
|
||||
@@ -89,6 +96,9 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||
|
||||
tvPaymentIdIntegrated = view.findViewById(R.id.tvPaymentIdIntegrated);
|
||||
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.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||
@@ -113,12 +123,25 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||
public void afterTextChanged(Editable editable) {
|
||||
etAddress.setError(null);
|
||||
if (isIntegratedAddress()) {
|
||||
Timber.d("isIntegratedAddress");
|
||||
etPaymentId.getEditText().getText().clear();
|
||||
llPaymentId.setVisibility(View.GONE);
|
||||
llPaymentId.setVisibility(View.INVISIBLE);
|
||||
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);
|
||||
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() {
|
||||
String address = etAddress.getEditText().getText().toString();
|
||||
return Wallet.isAddressValid(address);
|
||||
return Wallet.isAddressValid(address)
|
||||
|| BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet());
|
||||
}
|
||||
|
||||
private boolean checkAddress() {
|
||||
boolean ok = checkAddressNoError();
|
||||
if (!ok) {
|
||||
etAddress.setError(getString(R.string.send_qr_address_invalid));
|
||||
etAddress.setError(getString(R.string.send_address_invalid));
|
||||
} else {
|
||||
etAddress.setError(null);
|
||||
}
|
||||
@@ -203,7 +227,16 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||
|
||||
private boolean isIntegratedAddress() {
|
||||
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() {
|
||||
@@ -235,8 +268,15 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||
}
|
||||
if (!ok) return false;
|
||||
if (sendListener != null) {
|
||||
sendListener.setAddress(etAddress.getEditText().getText().toString());
|
||||
sendListener.setPaymentId(etPaymentId.getEditText().getText().toString());
|
||||
TxData txData = sendListener.getTxData();
|
||||
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;
|
||||
}
|
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
package com.m2049r.xmrwallet.fragment.send;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -22,10 +22,12 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.R;
|
||||
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.util.Helper;
|
||||
import com.m2049r.xmrwallet.widget.ExchangeTextView;
|
||||
import com.m2049r.xmrwallet.widget.NumberPadView;
|
||||
|
||||
import timber.log.Timber;
|
||||
@@ -48,7 +50,7 @@ public class SendAmountWizardFragment extends SendWizardFragment {
|
||||
interface Listener {
|
||||
SendFragment.Listener getActivityCallback();
|
||||
|
||||
void setAmount(final long amount);
|
||||
TxData getTxData();
|
||||
|
||||
BarcodeData popBarcodeData();
|
||||
}
|
||||
@@ -99,9 +101,9 @@ public class SendAmountWizardFragment extends SendWizardFragment {
|
||||
if (sendListener != null) {
|
||||
String xmr = evAmount.getAmount();
|
||||
if (xmr != null) {
|
||||
sendListener.setAmount(Wallet.getAmountFromString(xmr));
|
||||
sendListener.getTxData().setAmount(Wallet.getAmountFromString(xmr));
|
||||
} else {
|
||||
sendListener.setAmount(0L);
|
||||
sendListener.getTxData().setAmount(0L);
|
||||
}
|
||||
}
|
||||
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.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
package com.m2049r.xmrwallet.fragment.send;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.KeyEvent;
|
||||
@@ -30,14 +31,16 @@ import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
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.Wallet;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.UserNotes;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
public class SendConfirmWizardFragment extends SendWizardFragment implements SendConfirm {
|
||||
|
||||
public static SendConfirmWizardFragment newInstance(Listener listener) {
|
||||
SendConfirmWizardFragment instance = new SendConfirmWizardFragment();
|
||||
@@ -57,11 +60,11 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
|
||||
TxData getTxData();
|
||||
|
||||
String getNotes();
|
||||
|
||||
void commitTransaction();
|
||||
|
||||
void disposeTransaction();
|
||||
|
||||
SendFragment.Mode getMode();
|
||||
}
|
||||
|
||||
private TextView tvTxAddress;
|
||||
@@ -122,8 +125,11 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
|
||||
PendingTransaction pendingTransaction = null;
|
||||
|
||||
@Override
|
||||
// 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();
|
||||
if (isResumed) {
|
||||
this.pendingTransaction = pendingTransaction;
|
||||
@@ -138,10 +144,22 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
pbProgressSend.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
void sendFailed() {
|
||||
@Override
|
||||
public void sendFailed() {
|
||||
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
|
||||
public boolean onValidateFields() {
|
||||
return true;
|
||||
@@ -173,9 +191,9 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
} else {
|
||||
tvTxPaymentId.setText("-");
|
||||
}
|
||||
String notes = sendListener.getNotes();
|
||||
if ((notes != null) && (!notes.isEmpty())) {
|
||||
tvTxNotes.setText(sendListener.getNotes());
|
||||
UserNotes notes = sendListener.getTxData().getUserNotes();
|
||||
if ((notes != null) && (!notes.note.isEmpty())) {
|
||||
tvTxNotes.setText(notes.note);
|
||||
} else {
|
||||
tvTxNotes.setText("-");
|
||||
}
|
||||
@@ -232,7 +250,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
|
||||
alertDialogBuilder
|
||||
.setCancelable(false)
|
||||
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
.setPositiveButton(getString(R.string.label_ok), new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
String pass = etPassword.getEditText().getText().toString();
|
||||
if (getActivityCallback().verifyWalletPassword(pass)) {
|
||||
@@ -244,7 +262,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton("Cancel",
|
||||
.setNegativeButton(getString(R.string.label_cancel),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
Helper.hideKeyboardAlways(activity);
|
||||
@@ -296,8 +314,10 @@ public class SendConfirmWizardFragment extends SendWizardFragment {
|
||||
passwordDialog.show();
|
||||
}
|
||||
|
||||
// creates a pending transaction and calls us back with transactionCreated()
|
||||
// or createTransactionFailed()
|
||||
void prepareSend(TxData txData) {
|
||||
getActivityCallback().onPrepareSend(txData);
|
||||
getActivityCallback().onPrepareSend(null, txData);
|
||||
}
|
||||
|
||||
SendFragment.Listener getActivityCallback() {
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
package com.m2049r.xmrwallet.fragment.send;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
@@ -27,8 +27,11 @@ import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
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.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.UserNotes;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
@@ -48,12 +51,7 @@ public class SendSettingsWizardFragment extends SendWizardFragment {
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
|
||||
void setPriority(final PendingTransaction.Priority priority);
|
||||
|
||||
void setMixin(final int mixin);
|
||||
|
||||
void setNotes(final String notes);
|
||||
TxData getTxData();
|
||||
}
|
||||
|
||||
final static int Mixins[] = {4, 7, 12, 25}; // must match the layout XML
|
||||
@@ -103,13 +101,10 @@ public class SendSettingsWizardFragment extends SendWizardFragment {
|
||||
@Override
|
||||
public boolean onValidateFields() {
|
||||
if (sendListener != null) {
|
||||
int mixin = Mixins[sMixin.getSelectedItemPosition()];
|
||||
int priorityIndex = sPriority.getSelectedItemPosition();
|
||||
PendingTransaction.Priority priority = Priorities[priorityIndex];
|
||||
sendListener.setPriority(priority);
|
||||
sendListener.setMixin(mixin);
|
||||
String notes = etNotes.getText().toString();
|
||||
sendListener.setNotes(notes);
|
||||
TxData txData = sendListener.getTxData();
|
||||
txData.setPriority(Priorities[sPriority.getSelectedItemPosition()]);
|
||||
txData.setMixin(Mixins[sMixin.getSelectedItemPosition()]);
|
||||
txData.setUserNotes(new UserNotes(etNotes.getText().toString()));
|
||||
}
|
||||
return true;
|
||||
}
|
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
package com.m2049r.xmrwallet.fragment.send;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -24,10 +24,10 @@ import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.R;
|
||||
import com.m2049r.xmrwallet.data.PendingTx;
|
||||
import com.m2049r.xmrwallet.data.TxData;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
@@ -47,23 +47,21 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
String getNotes();
|
||||
|
||||
TxData getTxData();
|
||||
|
||||
PendingTx getCommittedTx();
|
||||
|
||||
void enableDone();
|
||||
|
||||
SendFragment.Mode getMode();
|
||||
}
|
||||
|
||||
ImageButton bCopyAddress;
|
||||
ImageButton bCopyTxId;
|
||||
private TextView tvTxId;
|
||||
private TextView tvTxAddress;
|
||||
private TextView tvTxPaymentId;
|
||||
private TextView tvTxNotes;
|
||||
private TextView tvTxAmount;
|
||||
private TextView tvTxFee;
|
||||
private TextView tvTxTotal;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -74,21 +72,20 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
|
||||
View view = inflater.inflate(
|
||||
R.layout.fragment_send_success, container, false);
|
||||
|
||||
bCopyAddress = (ImageButton) view.findViewById(R.id.bCopyAddress);
|
||||
bCopyAddress.setOnClickListener(new View.OnClickListener() {
|
||||
bCopyTxId = (ImageButton) view.findViewById(R.id.bCopyTxId);
|
||||
bCopyTxId.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
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);
|
||||
tvTxAddress = (TextView) view.findViewById(R.id.tvTxAddress);
|
||||
tvTxPaymentId = (TextView) view.findViewById(R.id.tvTxPaymentId);
|
||||
tvTxNotes = (TextView) view.findViewById(R.id.tvTxNotes);
|
||||
tvTxAmount = ((TextView) view.findViewById(R.id.tvTxAmount));
|
||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||
tvTxTotal = (TextView) view.findViewById(R.id.tvTxTotal);
|
||||
|
||||
return view;
|
||||
}
|
||||
@@ -117,30 +114,15 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
|
||||
} else {
|
||||
tvTxPaymentId.setText("-");
|
||||
}
|
||||
String notes = sendListener.getNotes();
|
||||
if ((notes != null) && (!notes.isEmpty())) {
|
||||
tvTxNotes.setText(sendListener.getNotes());
|
||||
} else {
|
||||
tvTxNotes.setText("-");
|
||||
}
|
||||
|
||||
final PendingTx committedTx = sendListener.getCommittedTx();
|
||||
if (committedTx != null) {
|
||||
tvTxId.setText(committedTx.txId);
|
||||
bCopyAddress.setEnabled(true);
|
||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||
tvTxAmount.setText(Wallet.getDisplayAmount(committedTx.amount));
|
||||
tvTxFee.setText(Wallet.getDisplayAmount(committedTx.fee));
|
||||
//tvTxDust.setText(Wallet.getDisplayAmount(pendingTransaction.getDust()));
|
||||
tvTxTotal.setText(Wallet.getDisplayAmount(
|
||||
committedTx.fee + committedTx.amount));
|
||||
bCopyTxId.setEnabled(true);
|
||||
bCopyTxId.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||
tvTxAmount.setText(getString(R.string.send_amount, Helper.getDisplayAmount(committedTx.amount)));
|
||||
tvTxFee.setText(getString(R.string.send_fee, Helper.getDisplayAmount(committedTx.fee)));
|
||||
}
|
||||
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.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
package com.m2049r.xmrwallet.fragment.send;
|
||||
|
||||
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