1
mirror of https://github.com/m2049r/xmrwallet synced 2025-09-06 02:27:11 +02:00

Compare commits

...

41 Commits

Author SHA1 Message Date
m2049r
ead8564688 bump version 2018-10-09 19:38:06 +02:00
m2049r
b71b3badd8 remove settings & fix prio to default (#433) 2018-10-09 19:33:29 +02:00
ProkhorZ
5ad46e2f54 Add node version warning (#432)
for monero v0.13 upgrade.
2018-10-09 07:59:49 +02:00
m2049r
9d6895b60f adding missing resources 2018-10-08 23:10:25 +02:00
m2049r
a8755ee0da correct error message 2018-10-08 22:50:40 +02:00
m2049r
f186bc9d4f core wallet api 0.13 2018-10-08 22:50:16 +02:00
ProkhorZ
9cb961a368 Translate missing strings (#429)
As requested in #411
2018-10-08 22:34:00 +02:00
m2049r
aa78541b6f fix build 2018-10-08 20:58:26 +02:00
v1docq47
eba6a78004 Update for Russian translation #370 (#422)
* Update for Russian translation
- strings.xml
- help.xml
2018-10-08 19:44:56 +02:00
m2049r
8587eab41c whitespace & cleanup 2018-10-08 19:02:00 +02:00
m2049r
4271c743c7 update wallet balance on refresh 2018-10-08 19:02:00 +02:00
m2049r
5b60987692 remove beta flavor 2018-10-08 19:02:00 +02:00
m2049r
e1bd04c945 tweaks & new version 2018-10-08 19:02:00 +02:00
m2049r
ef29db62c4 change error message 2018-10-08 19:02:00 +02:00
m2049r
82ce12e27c increase mixin to 10 as per protocol v8 2018-10-08 19:02:00 +02:00
m2049r
4211687981 rework build process 2018-10-08 19:02:00 +02:00
m2049r
d398416a3d translation prep 2018-10-08 19:02:00 +02:00
m2049r
1844d84be8 whitespace 2018-10-08 19:02:00 +02:00
m2049r
5101b7da5e flavor alpha,beta 2018-10-08 19:02:00 +02:00
m2049r
3e90f2e22e new Ledger interface 2018-10-08 19:02:00 +02:00
m2049r
f01a8eac5d bump version 2018-10-08 19:02:00 +02:00
m2049r
0c13338dc0 link with libsodium 2018-10-08 19:02:00 +02:00
m2049r
78d6fef3e4 getDeviceType 2018-10-08 19:02:00 +02:00
m2049r
cbddcdc92d new api & queryWalletDevice 2018-10-08 19:02:00 +02:00
jaro Lee
4289aaac77 Update strings.xml (#428)
Minor translation misssteps. Bringing to context.
Regarding `send_settings_title` - NASTAVENIA string is too long (wrapping the text in a button). Changed to `Možnosti`  (options in english)
2018-10-08 19:00:55 +02:00
m2049r
fd15da9c84 cleaned old/irrelevant stuff 2018-10-08 18:59:36 +02:00
m2049r
c3357087d5 add missing strings 2018-10-08 13:35:10 +02:00
m2049r
47e0bc86fd fixed positional formatting 2018-10-08 13:35:10 +02:00
Wobole
dbd45ea4f5 Update german translation (#425) 2018-10-08 13:02:06 +02:00
ProkhorZ
90c3e6ef8b Add Dutch translation in values-nl (#411) 2018-10-08 13:00:17 +02:00
m2049r
bc6a816462 upgrade AndroidStudio 2018-09-25 22:39:07 +02:00
m2049r
274a1a25f1 correct cstdio files to patch 2018-09-25 21:27:05 +02:00
m2049r
9e3a2b102e correct sed syntax 2018-09-25 20:53:58 +02:00
Johan Lindqvist
647ae9a565 Patch 1 (#414)
* Added Swedish translations

* Fixed spelling error
2018-09-23 08:38:20 +02:00
m2049r
2bbd20855f deal correctly with escaped strings (#419) 2018-09-22 11:20:31 +02:00
erciccione
b8fc5f910a add 'ErCiccione' to the credits (#417) 2018-09-21 18:26:22 +02:00
erciccione
01700cf780 update values-it/strings.xml (#413) 2018-09-21 14:39:05 +02:00
Lafudoci
2fa6286b0e Update zh-rTW translation for OpenAlias (#415) 2018-09-21 14:37:24 +02:00
jar'o Lee
0ac1680e75 Update strings.xml (#416)
new strings translated , minor fix of weird-sounding old translation (restore height)
2018-09-21 14:37:06 +02:00
el00ruobuob
bd9a98e0d8 French translation OpenAlias & Language menu (#412) 2018-09-21 14:36:47 +02:00
jenniferberger
8a5121e792 enhance build description (#271)
Writing a script to build the artifacts in a reproducible environment
- PATH for openssl build was not set
- branch for m2049r/monero.git was not set
2018-09-21 09:52:07 +02:00
75 changed files with 2056 additions and 534 deletions

1
.idea/gradle.xml generated
View File

@@ -3,6 +3,7 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="disableWrapperSourceDistributionNotification" value="true" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules"> <option name="modules">

View File

@@ -22,12 +22,8 @@ Help us translate Monerujo! You can find instructions [On Taiga](https://taiga.g
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.1.0 - works on the mainnet & stagenet
- 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 - use your own daemon - it's easy
- screen stays on until first sync is complete
- 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
@@ -43,13 +39,8 @@ of the "real" testnet. After creating a new wallet, make a **new** one by recov
The official monero client shows the same behaviour. The official monero client shows the same behaviour.
### HOW TO BUILD ### HOW TO BUILD
No need to build. Binaries are included:
- openssl-1.0.2l See [the instructions](doc/BUILDING-external-libs.md)
- monero-v0.12
- boost_1_58_0
If you want to build them yourself (recommended) check out [the instructions](doc/BUILDING-external-libs.md)
Then, fire up Android Studio and build the APK. Then, fire up Android Studio and build the APK.

View File

@@ -7,13 +7,21 @@ add_library( monerujo
set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../external-libs) set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../external-libs)
############
# libsodium
############
add_library(sodium STATIC IMPORTED)
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/libsodium/lib/${ANDROID_ABI}/libsodium.a)
############ ############
# OpenSSL # OpenSSL
############ ############
add_library(crypto STATIC IMPORTED) add_library(crypto STATIC IMPORTED)
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libcrypto.a) ${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libcrypto.a)
add_library(ssl STATIC IMPORTED) add_library(ssl STATIC IMPORTED)
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
@@ -184,5 +192,7 @@ target_link_libraries( monerujo
ssl ssl
crypto crypto
sodium
${log-lib} ${log-lib}
) )

View File

@@ -7,8 +7,8 @@ android {
applicationId "com.m2049r.xmrwallet" applicationId "com.m2049r.xmrwallet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 27 targetSdkVersion 27
versionCode 123 versionCode 132
versionName "1.7.3 'OpenAlias'" versionName "1.8.2 'Bullets And Octane-Pirates'"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {
@@ -18,6 +18,16 @@ android {
} }
} }
flavorDimensions "version"
productFlavors {
alpha {
applicationIdSuffix ".alpha"
versionNameSuffix " (alpha)"
}
prod {
}
}
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
@@ -27,6 +37,7 @@ android {
applicationIdSuffix ".debug" applicationIdSuffix ".debug"
} }
} }
externalNativeBuild { externalNativeBuild {
cmake { cmake {
path "CMakeLists.txt" path "CMakeLists.txt"
@@ -61,9 +72,13 @@ android {
output -> output ->
def abiName = output.getFilter(com.android.build.OutputFile.ABI) def abiName = output.getFilter(com.android.build.OutputFile.ABI)
output.versionCodeOverride = abiCodes.get(abiName, 0) + 10 * variant.versionCode output.versionCodeOverride = abiCodes.get(abiName, 0) + 10 * variant.versionCode
//def flavor = output.getFilter(flavor)
if (abiName == null) abiName = "universal" if (abiName == null) abiName = "universal"
def v = "${variant.versionName}".replaceFirst(" .*\$", "").replace(".", "x") def v = "${variant.versionName}".replaceFirst(" '.*' ?", "")
.replace(".", "x")
.replace("(", "-")
.replace(")", "")
outputFileName = "$rootProject.ext.apkName-" + v + "_" + abiName + ".apk" outputFileName = "$rootProject.ext.apkName-" + v + "_" + abiName + ".apk"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,88 @@
// Copyright (c) 2017-2018, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#if defined(HAVE_MONERUJO)
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief LedgerFind - find Ledger Device and return it's name
* @param buffer - buffer for name of found device
* @param len - length of buffer
* @return 0 - success
* -1 - no device connected / found
* -2 - JVM not found
*/
int LedgerFind(char *buffer, size_t len);
/**
* @brief LedgerExchange - exchange data with Ledger Device
* @param command - buffer for data to send
* @param cmd_len - length of send to send
* @param response - buffer for received data
* @param max_resp_len - size of receive buffer
*
* @return length of received data in response or -1 if error
*/
int LedgerExchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len);
#ifdef __cplusplus
}
#endif
#include "device_io.hpp"
#pragma once
namespace hw {
namespace io {
class device_io_monerujo: device_io {
public:
device_io_monerujo() {};
~device_io_monerujo() {};
void init() {};
void release() {};
void connect(void *params) {};
void disconnect() {};
bool connected() const {return true;}; // monerujo is always connected before it gets here
// returns number of bytes read or -1 on error
int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len) {
return LedgerExchange(command, cmd_len, response, max_resp_len);
}
};
};
};
#endif //#if defined(HAVE_MONERUJO)

View File

@@ -416,17 +416,20 @@ Java_com_m2049r_xmrwallet_model_WalletManager_verifyWalletPassword(JNIEnv *env,
//virtual int queryWalletHardware(const std::string &keys_file_name, const std::string &password) const = 0; //virtual int queryWalletHardware(const std::string &keys_file_name, const std::string &password) const = 0;
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_com_m2049r_xmrwallet_model_WalletManager_queryWalletHardware(JNIEnv *env, jobject instance, Java_com_m2049r_xmrwallet_model_WalletManager_queryWalletDeviceJ(JNIEnv *env, jobject instance,
jstring keys_file_name, jstring keys_file_name,
jstring password) { jstring password) {
const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, NULL); const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, NULL);
const char *_password = env->GetStringUTFChars(password, NULL); const char *_password = env->GetStringUTFChars(password, NULL);
int hardwareId = Bitmonero::Wallet::Device device_type;
Bitmonero::WalletManagerFactory::getWalletManager()-> bool ok = Bitmonero::WalletManagerFactory::getWalletManager()->
queryWalletHardware(std::string(_keys_file_name), std::string(_password)); queryWalletDevice(device_type, std::string(_keys_file_name), std::string(_password));
env->ReleaseStringUTFChars(keys_file_name, _keys_file_name); env->ReleaseStringUTFChars(keys_file_name, _keys_file_name);
env->ReleaseStringUTFChars(password, _password); env->ReleaseStringUTFChars(password, _password);
return static_cast<jint>(hardwareId); if (ok)
return static_cast<jint>(device_type);
else
return -1;
} }
JNIEXPORT jobject JNICALL JNIEXPORT jobject JNICALL
@@ -775,11 +778,11 @@ Java_com_m2049r_xmrwallet_model_Wallet_isSynchronized(JNIEnv *env, jobject insta
return static_cast<jboolean>(wallet->synchronized()); return static_cast<jboolean>(wallet->synchronized());
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jint JNICALL
Java_com_m2049r_xmrwallet_model_Wallet_isKeyOnDevice(JNIEnv *env, jobject instance) { Java_com_m2049r_xmrwallet_model_Wallet_getDeviceTypeJ(JNIEnv *env, jobject instance) {
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance); Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
bool key_on_device = wallet->isKeyOnDevice(); Bitmonero::Wallet::Device device_type = wallet->getDeviceType();
return static_cast<jboolean>(key_on_device); return static_cast<jint>(device_type);
} }
//void cn_slow_hash(const void *data, size_t length, char *hash); // from crypto/hash-ops.h //void cn_slow_hash(const void *data, size_t length, char *hash); // from crypto/hash-ops.h
@@ -1383,24 +1386,22 @@ Java_com_m2049r_xmrwallet_model_WalletManager_setLogLevel(JNIEnv *env, jobject i
// Ledger Stuff // Ledger Stuff
// //
#include "monerujo_ledger.h" #include "device_io_monerujo.hpp"
/** /**
* @brief LedgerExchange - exchange data with Ledger Device * @brief LedgerExchange - exchange data with Ledger Device
* @param pbSendBuffer - buffer for data to send * @param command - buffer for data to send
* @param cbSendLength - length of send buffer * @param cmd_len - length of send to send
* @param pbRecvBuffer - buffer for received data * @param response - buffer for received data
* @param pcbRecvLength - pointer to size of receive buffer * @param max_resp_len - size of receive buffer
* gets set with length of received data on successful return *
* @return SCARD_S_SUCCESS - success * @return length of received data in response or -1 if error
* SCARD_E_NO_READERS_AVAILABLE - no device connected / found
* SCARD_E_INSUFFICIENT_BUFFER - pbRecvBuffer is too small for the response
*/ */
LONG LedgerExchange( int LedgerExchange(
LPCBYTE pbSendBuffer, unsigned char *command,
DWORD cbSendLength, unsigned int cmd_len,
LPBYTE pbRecvBuffer, unsigned char *response,
LPDWORD pcbRecvLength) { unsigned int max_resp_len) {
LOGD("LedgerExchange"); LOGD("LedgerExchange");
JNIEnv *jenv; JNIEnv *jenv;
int envStat = attachJVM(&jenv); int envStat = attachJVM(&jenv);
@@ -1408,30 +1409,29 @@ LONG LedgerExchange(
jmethodID exchangeMethod = jenv->GetStaticMethodID(class_Ledger, "Exchange", "([B)[B"); jmethodID exchangeMethod = jenv->GetStaticMethodID(class_Ledger, "Exchange", "([B)[B");
jsize sendLen = static_cast<jsize>(cbSendLength); jsize sendLen = static_cast<jsize>(cmd_len);
jbyteArray dataSend = jenv->NewByteArray(sendLen); jbyteArray dataSend = jenv->NewByteArray(sendLen);
jenv->SetByteArrayRegion(dataSend, 0, sendLen, (jbyte *) pbSendBuffer); jenv->SetByteArrayRegion(dataSend, 0, sendLen, (jbyte *) command);
jbyteArray dataRecv = (jbyteArray) jenv->CallStaticObjectMethod(class_Ledger, exchangeMethod, jbyteArray dataRecv = (jbyteArray) jenv->CallStaticObjectMethod(class_Ledger, exchangeMethod,
dataSend); dataSend);
jenv->DeleteLocalRef(dataSend); jenv->DeleteLocalRef(dataSend);
if (dataRecv == nullptr) { if (dataRecv == nullptr) {
detachJVM(jenv, envStat); detachJVM(jenv, envStat);
LOGD("LedgerExchange SCARD_E_NO_READERS_AVAILABLE"); LOGD("LedgerExchange SCARD_E_NO_READERS_AVAILABLE");
return SCARD_E_NO_READERS_AVAILABLE; return -1;
} }
jsize len = jenv->GetArrayLength(dataRecv); jsize len = jenv->GetArrayLength(dataRecv);
LOGD("LedgerExchange SCARD_S_SUCCESS %ld/%d", cbSendLength, len); LOGD("LedgerExchange SCARD_S_SUCCESS %ld/%d", cmd_len, len);
if (len <= *pcbRecvLength) { if (len <= max_resp_len) {
*pcbRecvLength = static_cast<DWORD>(len); jenv->GetByteArrayRegion(dataRecv, 0, len, (jbyte *) response);
jenv->GetByteArrayRegion(dataRecv, 0, len, (jbyte *) pbRecvBuffer);
jenv->DeleteLocalRef(dataRecv); jenv->DeleteLocalRef(dataRecv);
detachJVM(jenv, envStat); detachJVM(jenv, envStat);
return SCARD_S_SUCCESS; return static_cast<int>(len);;
} else { } else {
jenv->DeleteLocalRef(dataRecv); jenv->DeleteLocalRef(dataRecv);
detachJVM(jenv, envStat); detachJVM(jenv, envStat);
LOGE("LedgerExchange SCARD_E_INSUFFICIENT_BUFFER"); LOGE("LedgerExchange SCARD_E_INSUFFICIENT_BUFFER");
return SCARD_E_INSUFFICIENT_BUFFER; return -1;
} }
} }

View File

@@ -1,46 +0,0 @@
/**
* Copyright (c) 2018 m2049r
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.
*/
#ifndef XMRWALLET_LEDGER_H
#define XMRWALLET_LEDGER_H
#ifdef __cplusplus
extern "C"
{
#endif
#define SCARD_S_SUCCESS ((LONG)0x00000000) /**< No error was encountered. */
#define SCARD_E_INSUFFICIENT_BUFFER ((LONG)0x80100008) /**< The data buffer to receive returned data is too small for the returned data. */
#define SCARD_E_NO_READERS_AVAILABLE ((LONG)0x8010002E) /**< Cannot find a smart card reader. */
typedef long LONG;
typedef unsigned long DWORD;
typedef DWORD *LPDWORD;
typedef unsigned char BYTE;
typedef BYTE *LPBYTE;
typedef const BYTE *LPCBYTE;
typedef char CHAR;
typedef CHAR *LPSTR;
int LedgerFind(char *buffer, size_t len);
LONG LedgerExchange(LPCBYTE pbSendBuffer, DWORD cbSendLength, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
#ifdef __cplusplus
}
#endif
#endif //XMRWALLET_LEDGER_H

View File

@@ -200,7 +200,8 @@ public class GenerateReviewFragment extends Fragment {
super.onPreExecute(); super.onPreExecute();
showProgress(); showProgress();
if ((walletPath != null) if ((walletPath != null)
&& (WalletManager.getInstance().queryWalletHardware(walletPath + ".keys", getPassword()) == 1) && (WalletManager.getInstance().queryWalletDevice(walletPath + ".keys", getPassword())
== Wallet.Device.Device_Ledger)
&& (progressCallback != null)) { && (progressCallback != null)) {
progressCallback.showLedgerProgressDialog(LedgerProgressDialog.TYPE_RESTORE); progressCallback.showLedgerProgressDialog(LedgerProgressDialog.TYPE_RESTORE);
dialogOpened = true; dialogOpened = true;
@@ -231,10 +232,15 @@ public class GenerateReviewFragment extends Fragment {
address = wallet.getAddress(); address = wallet.getAddress();
seed = wallet.getSeed(); seed = wallet.getSeed();
if (wallet.isKeyOnDevice()) { switch (wallet.getDeviceType()) {
viewKey = Ledger.Key(); case Device_Ledger:
} else { viewKey = Ledger.Key();
viewKey = wallet.getSecretViewKey(); break;
case Device_Software:
viewKey = wallet.getSecretViewKey();
break;
default:
throw new IllegalStateException("Hardware backing not supported. At all!");
} }
spendKey = isWatchOnly ? getActivity().getString(R.string.label_watchonly) : wallet.getSecretSpendKey(); spendKey = isWatchOnly ? getActivity().getString(R.string.label_watchonly) : wallet.getSecretSpendKey();
isWatchOnly = wallet.isWatchOnly(); isWatchOnly = wallet.isWatchOnly();

View File

@@ -1171,18 +1171,27 @@ public class LoginActivity extends BaseActivity
String keyPath = new File(Helper.getWalletRoot(LoginActivity.this), String keyPath = new File(Helper.getWalletRoot(LoginActivity.this),
walletName + ".keys").getAbsolutePath(); walletName + ".keys").getAbsolutePath();
// check if we need connected hardware // check if we need connected hardware
int hw = WalletManager.getInstance().queryWalletHardware(keyPath, password); Wallet.Device device =
if ((hw == 1) && (!hasLedger())) { WalletManager.getInstance().queryWalletDevice(keyPath, password);
toast(R.string.open_wallet_ledger_missing); switch (device) {
} else { case Device_Ledger:
// hw could be < 0 meaning the password is wrong - this gets dealt with later if (!hasLedger()) {
startWallet(walletName, password, fingerprintUsed); toast(R.string.open_wallet_ledger_missing);
} else {
startWallet(walletName, password, fingerprintUsed);
}
break;
default:
// device could be undefined meaning the password is wrong
// this gets dealt with later
startWallet(walletName, password, fingerprintUsed);
} }
} }
}); });
} else { // this cannot really happen as we prefilter choices } else { // this cannot really happen as we prefilter choices
Toast.makeText(this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show(); Toast.makeText(this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show();
} }
} }
// USB Stuff - (Ledger) // USB Stuff - (Ledger)

View File

@@ -320,7 +320,8 @@ public class ReceiveFragment extends Fragment {
super.onPreExecute(); super.onPreExecute();
showProgress(); showProgress();
if ((walletPath != null) if ((walletPath != null)
&& (WalletManager.getInstance().queryWalletHardware(walletPath + ".keys", password) == 1) && (WalletManager.getInstance().queryWalletDevice(walletPath + ".keys", password)
== Wallet.Device.Device_Ledger)
&& (progressCallback != null)) { && (progressCallback != null)) {
progressCallback.showLedgerProgressDialog(LedgerProgressDialog.TYPE_RESTORE); progressCallback.showLedgerProgressDialog(LedgerProgressDialog.TYPE_RESTORE);
dialogOpened = true; dialogOpened = true;
@@ -513,7 +514,7 @@ public class ReceiveFragment extends Fragment {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
super.onPreExecute(); super.onPreExecute();
if (wallet.isKeyOnDevice() && (progressCallback != null)) { if ((wallet.getDeviceType() == Wallet.Device.Device_Ledger) && (progressCallback != null)) {
progressCallback.showLedgerProgressDialog(LedgerProgressDialog.TYPE_SUBADDRESS); progressCallback.showLedgerProgressDialog(LedgerProgressDialog.TYPE_SUBADDRESS);
dialogOpened = true; dialogOpened = true;
} }

View File

@@ -51,6 +51,7 @@ import com.m2049r.xmrwallet.dialog.CreditsFragment;
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.SendAddressWizardFragment;
import com.m2049r.xmrwallet.fragment.send.SendFragment; import com.m2049r.xmrwallet.fragment.send.SendFragment;
import com.m2049r.xmrwallet.ledger.Ledger;
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog; import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
import com.m2049r.xmrwallet.model.PendingTransaction; import com.m2049r.xmrwallet.model.PendingTransaction;
import com.m2049r.xmrwallet.model.TransactionInfo; import com.m2049r.xmrwallet.model.TransactionInfo;
@@ -461,6 +462,11 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
@Override @Override
public boolean onRefreshed(final Wallet wallet, final boolean full) { public boolean onRefreshed(final Wallet wallet, final boolean full) {
Timber.d("onRefreshed()"); Timber.d("onRefreshed()");
runOnUiThread(new Runnable() {
public void run() {
updateAccountsBalance();
}
});
if (numAccounts != wallet.getNumAccounts()) { if (numAccounts != wallet.getNumAccounts()) {
numAccounts = wallet.getNumAccounts(); numAccounts = wallet.getNumAccounts();
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@@ -516,26 +522,35 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
boolean haveWallet = false; boolean haveWallet = false;
@Override @Override
public void onWalletOpen(final int hardware) { public void onWalletOpen(final Wallet.Device device) {
if (hardware > 0) switch (device) {
runOnUiThread(new Runnable() { case Device_Ledger:
public void run() { runOnUiThread(new Runnable() {
showLedgerProgressDialog(LedgerProgressDialog.TYPE_RESTORE); public void run() {
} showLedgerProgressDialog(LedgerProgressDialog.TYPE_RESTORE);
}); }
});
}
} }
@Override @Override
public void onWalletStarted(final boolean success) { public void onWalletStarted(final Wallet.ConnectionStatus connStatus) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
dismissProgressDialog(); dismissProgressDialog();
if (!success) { switch (connStatus) {
Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_connect_failed), Toast.LENGTH_LONG).show(); case ConnectionStatus_Disconnected:
Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_connect_failed), Toast.LENGTH_LONG).show();
break;
case ConnectionStatus_WrongVersion:
Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_connect_wrongversion), Toast.LENGTH_LONG).show();
break;
case ConnectionStatus_Connected:
break;
} }
} }
}); });
if (!success) { if (connStatus != Wallet.ConnectionStatus.ConnectionStatus_Connected) {
finish(); finish();
} else { } else {
haveWallet = true; haveWallet = true;
@@ -545,6 +560,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
getSupportFragmentManager().findFragmentById(R.id.fragment_container); getSupportFragmentManager().findFragmentById(R.id.fragment_container);
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
updateAccountsHeader();
if (walletFragment != null) { if (walletFragment != null) {
walletFragment.onLoaded(); walletFragment.onLoaded();
} }
@@ -716,7 +732,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
intent.putExtra(WalletService.REQUEST_CMD_TX_TAG, tag); intent.putExtra(WalletService.REQUEST_CMD_TX_TAG, tag);
startService(intent); startService(intent);
Timber.d("CREATE TX request sent"); Timber.d("CREATE TX request sent");
if (getWallet().isKeyOnDevice()) if (getWallet().getDeviceType() == Wallet.Device.Device_Ledger)
showLedgerProgressDialog(LedgerProgressDialog.TYPE_SEND); showLedgerProgressDialog(LedgerProgressDialog.TYPE_SEND);
} else { } else {
Timber.e("Service not bound"); Timber.e("Service not bound");
@@ -953,13 +969,22 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
} }
// drawer stuff // drawer stuff
void updateAccountsList() {
void updateAccountsBalance() {
final Wallet wallet = getWallet(); final Wallet wallet = getWallet();
final TextView tvName = (TextView) accountsView.getHeaderView(0).findViewById(R.id.tvName);
tvName.setText(wallet.getName());
final TextView tvBalance = (TextView) accountsView.getHeaderView(0).findViewById(R.id.tvBalance); final TextView tvBalance = (TextView) accountsView.getHeaderView(0).findViewById(R.id.tvBalance);
tvBalance.setText(getString(R.string.accounts_balance, tvBalance.setText(getString(R.string.accounts_balance,
Helper.getDisplayAmount(wallet.getBalanceAll(), 5))); Helper.getDisplayAmount(wallet.getBalanceAll(), 5)));
}
void updateAccountsHeader() {
final Wallet wallet = getWallet();
final TextView tvName = (TextView) accountsView.getHeaderView(0).findViewById(R.id.tvName);
tvName.setText(wallet.getName());
}
void updateAccountsList() {
final Wallet wallet = getWallet();
Menu menu = accountsView.getMenu(); Menu menu = accountsView.getMenu();
menu.removeGroup(R.id.accounts_list); menu.removeGroup(R.id.accounts_list);
final int n = wallet.getNumAccounts(); final int n = wallet.getNumAccounts();
@@ -1072,12 +1097,17 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
super.onPreExecute(); super.onPreExecute();
if (getWallet().isKeyOnDevice()) { switch (getWallet().getDeviceType()) {
showLedgerProgressDialog(LedgerProgressDialog.TYPE_ACCOUNT); case Device_Ledger:
dialogOpened = true; showLedgerProgressDialog(LedgerProgressDialog.TYPE_ACCOUNT);
} else { dialogOpened = true;
showProgressDialog(R.string.accounts_progress_new); break;
dialogOpened = true; case Device_Software:
showProgressDialog(R.string.accounts_progress_new);
dialogOpened = true;
break;
default:
throw new IllegalStateException("Hardware backing not supported. At all!");
} }
} }

View File

@@ -162,7 +162,7 @@ public class BarcodeData {
String noScheme = uri.substring(XMR_SCHEME.length()); String noScheme = uri.substring(XMR_SCHEME.length());
Uri monero = Uri.parse(noScheme); Uri monero = Uri.parse(noScheme);
Map<String, String> parms = new HashMap<>(); Map<String, String> parms = new HashMap<>();
String query = monero.getQuery(); String query = monero.getEncodedQuery();
if (query != null) { if (query != null) {
String[] args = query.split("&"); String[] args = query.split("&");
for (String arg : args) { for (String arg : args) {

View File

@@ -39,6 +39,7 @@ 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.TxData;
import com.m2049r.xmrwallet.data.TxDataBtc; import com.m2049r.xmrwallet.data.TxDataBtc;
import com.m2049r.xmrwallet.model.PendingTransaction;
import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.util.BitcoinAddressValidator; import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
@@ -350,6 +351,8 @@ public class SendAddressWizardFragment extends SendWizardFragment {
txData.setPaymentId(etPaymentId.getEditText().getText().toString()); txData.setPaymentId(etPaymentId.getEditText().getText().toString());
} }
txData.setUserNotes(new UserNotes(etNotes.getEditText().getText().toString())); txData.setUserNotes(new UserNotes(etNotes.getEditText().getText().toString()));
txData.setPriority(PendingTransaction.Priority.Priority_Default);
txData.setMixin(SendFragment.MIXIN);
} }
return true; return true;
} }

View File

@@ -58,11 +58,12 @@ import timber.log.Timber;
public class SendFragment extends Fragment public class SendFragment extends Fragment
implements SendAddressWizardFragment.Listener, implements SendAddressWizardFragment.Listener,
SendAmountWizardFragment.Listener, SendAmountWizardFragment.Listener,
SendSettingsWizardFragment.Listener,
SendConfirmWizardFragment.Listener, SendConfirmWizardFragment.Listener,
SendSuccessWizardFragment.Listener, SendSuccessWizardFragment.Listener,
OnBackPressedListener, OnUriScannedListener { OnBackPressedListener, OnUriScannedListener {
final static public int MIXIN = 10;
private Listener activityCallback; private Listener activityCallback;
public interface Listener { public interface Listener {
@@ -301,10 +302,9 @@ public class SendFragment extends Fragment
public class SpendPagerAdapter extends FragmentStatePagerAdapter { public class SpendPagerAdapter extends FragmentStatePagerAdapter {
private static final int POS_ADDRESS = 0; private static final int POS_ADDRESS = 0;
private static final int POS_AMOUNT = 1; private static final int POS_AMOUNT = 1;
private static final int POS_SETTINGS = 2; private static final int POS_CONFIRM = 2;
private static final int POS_CONFIRM = 3; private static final int POS_SUCCESS = 3;
private static final int POS_SUCCESS = 4; private int numPages = 3;
private int numPages = 4;
SparseArray<WeakReference<SendWizardFragment>> myFragments = new SparseArray<>(); SparseArray<WeakReference<SendWizardFragment>> myFragments = new SparseArray<>();
@@ -355,8 +355,6 @@ public class SendFragment extends Fragment
return SendAddressWizardFragment.newInstance(SendFragment.this); return SendAddressWizardFragment.newInstance(SendFragment.this);
case POS_AMOUNT: case POS_AMOUNT:
return SendAmountWizardFragment.newInstance(SendFragment.this); return SendAmountWizardFragment.newInstance(SendFragment.this);
case POS_SETTINGS:
return SendSettingsWizardFragment.newInstance(SendFragment.this);
case POS_CONFIRM: case POS_CONFIRM:
return SendConfirmWizardFragment.newInstance(SendFragment.this); return SendConfirmWizardFragment.newInstance(SendFragment.this);
case POS_SUCCESS: case POS_SUCCESS:
@@ -370,8 +368,6 @@ public class SendFragment extends Fragment
return SendAddressWizardFragment.newInstance(SendFragment.this); return SendAddressWizardFragment.newInstance(SendFragment.this);
case POS_AMOUNT: case POS_AMOUNT:
return SendBtcAmountWizardFragment.newInstance(SendFragment.this); return SendBtcAmountWizardFragment.newInstance(SendFragment.this);
case POS_SETTINGS:
return SendSettingsWizardFragment.newInstance(SendFragment.this);
case POS_CONFIRM: case POS_CONFIRM:
return SendBtcConfirmWizardFragment.newInstance(SendFragment.this); return SendBtcConfirmWizardFragment.newInstance(SendFragment.this);
case POS_SUCCESS: case POS_SUCCESS:
@@ -393,8 +389,6 @@ public class SendFragment extends Fragment
return getString(R.string.send_address_title); return getString(R.string.send_address_title);
case POS_AMOUNT: case POS_AMOUNT:
return getString(R.string.send_amount_title); return getString(R.string.send_amount_title);
case POS_SETTINGS:
return getString(R.string.send_settings_title);
case POS_CONFIRM: case POS_CONFIRM:
return getString(R.string.send_confirm_title); return getString(R.string.send_confirm_title);
case POS_SUCCESS: case POS_SUCCESS:
@@ -407,7 +401,8 @@ public class SendFragment extends Fragment
@Override @Override
public int getItemPosition(Object object) { public int getItemPosition(Object object) {
Timber.d("getItemPosition %s", String.valueOf(object)); Timber.d("getItemPosition %s", String.valueOf(object));
if ((object instanceof SendAddressWizardFragment) || (object instanceof SendSettingsWizardFragment)) { if (object instanceof SendAddressWizardFragment) {
// keep these pages
return POSITION_UNCHANGED; return POSITION_UNCHANGED;
} else { } else {
return POSITION_NONE; return POSITION_NONE;

View File

@@ -1,101 +0,0 @@
/*
* 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 android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
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;
public class SendSettingsWizardFragment extends SendWizardFragment {
final static public int MIXIN = 6;
public static SendSettingsWizardFragment newInstance(Listener listener) {
SendSettingsWizardFragment instance = new SendSettingsWizardFragment();
instance.setSendListener(listener);
return instance;
}
Listener sendListener;
public SendSettingsWizardFragment setSendListener(Listener listener) {
this.sendListener = listener;
return this;
}
interface Listener {
TxData getTxData();
}
final static PendingTransaction.Priority Priorities[] =
{PendingTransaction.Priority.Priority_Default,
PendingTransaction.Priority.Priority_Low,
PendingTransaction.Priority.Priority_Medium,
PendingTransaction.Priority.Priority_High}; // must match the layout XML
private Spinner sPriority;
private EditText etDummy;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Timber.d("onCreateView() %s", (String.valueOf(savedInstanceState)));
View view = inflater.inflate(
R.layout.fragment_send_settings, container, false);
sPriority = (Spinner) view.findViewById(R.id.sPriority);
etDummy = (EditText) view.findViewById(R.id.etDummy);
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
return view;
}
@Override
public boolean onValidateFields() {
if (sendListener != null) {
TxData txData = sendListener.getTxData();
txData.setPriority(Priorities[sPriority.getSelectedItemPosition()]);
txData.setMixin(MIXIN);
}
return true;
}
@Override
public void onResumeFragment() {
super.onResumeFragment();
Timber.d("onResumeFragment()");
Helper.hideKeyboard(getActivity());
etDummy.requestFocus();
}
}

View File

@@ -34,11 +34,9 @@ import java.io.IOException;
import timber.log.Timber; import timber.log.Timber;
public class Ledger { public class Ledger {
// lookahead parameters as suggest on // 5:20 is same as wallet2.cpp::restore()
// https://monero.stackexchange.com/a/9902/8977 (Step 8) static public final int LOOKAHEAD_ACCOUNTS = 5;
// by dEBRUYNE static public final int LOOKAHEAD_SUBADDRESSES = 20;
static public final int LOOKAHEAD_ACCOUNTS = 3;
static public final int LOOKAHEAD_SUBADDRESSES = 100;
static public final String SUBADDRESS_LOOKAHEAD = LOOKAHEAD_ACCOUNTS + ":" + LOOKAHEAD_SUBADDRESSES; static public final String SUBADDRESS_LOOKAHEAD = LOOKAHEAD_ACCOUNTS + ":" + LOOKAHEAD_SUBADDRESSES;
public static final int SW_OK = 0x9000; public static final int SW_OK = 0x9000;

View File

@@ -60,6 +60,12 @@ public class Wallet {
this.accountIndex = accountIndex; this.accountIndex = accountIndex;
} }
public enum Device {
Device_Undefined,
Device_Software,
Device_Ledger
};
public enum Status { public enum Status {
Status_Ok, Status_Ok,
Status_Error, Status_Error,
@@ -394,5 +400,11 @@ public class Wallet {
return getSubaddress(accountIndex, getNumSubaddresses(accountIndex) - 1); return getSubaddress(accountIndex, getNumSubaddresses(accountIndex) - 1);
} }
public native boolean isKeyOnDevice(); public Wallet.Device getDeviceType() {
int device = getDeviceTypeJ();
return Wallet.Device.values()[device + 1]; // mapping is monero+1=android
}
private native int getDeviceTypeJ();
} }

View File

@@ -178,10 +178,15 @@ public class WalletManager {
public native boolean verifyWalletPassword(String keys_file_name, String password, boolean watch_only); public native boolean verifyWalletPassword(String keys_file_name, String password, boolean watch_only);
public boolean verifyWalletPasswordOnly(String keys_file_name, String password) { public boolean verifyWalletPasswordOnly(String keys_file_name, String password) {
return queryWalletHardware(keys_file_name, password) >= 0; return queryWalletDevice(keys_file_name, password) != Wallet.Device.Device_Undefined;
} }
public native int queryWalletHardware(String keys_file_name, String password); public Wallet.Device queryWalletDevice(String keys_file_name, String password) {
int device = queryWalletDeviceJ(keys_file_name, password);
return Wallet.Device.values()[device + 1]; // mapping is monero+1=android
}
private native int queryWalletDeviceJ(String keys_file_name, String password);
//public native List<String> findWallets(String path); // this does not work - some error in boost //public native List<String> findWallets(String path); // this does not work - some error in boost

View File

@@ -226,9 +226,9 @@ public class WalletService extends Service {
void onSetNotes(boolean success); void onSetNotes(boolean success);
void onWalletStarted(boolean success); void onWalletStarted(Wallet.ConnectionStatus walletStatus);
void onWalletOpen(int hardware); void onWalletOpen(Wallet.Device device);
} }
String progressText = null; String progressText = null;
@@ -293,9 +293,9 @@ public class WalletService extends Service {
if (walletId != null) { if (walletId != null) {
showProgress(getString(R.string.status_wallet_loading)); showProgress(getString(R.string.status_wallet_loading));
showProgress(10); showProgress(10);
boolean success = start(walletId, walletPw); Wallet.ConnectionStatus connStatus = start(walletId, walletPw);
if (observer != null) observer.onWalletStarted(success); if (observer != null) observer.onWalletStarted(connStatus);
if (!success) { if (connStatus != Wallet.ConnectionStatus.ConnectionStatus_Connected) {
errorState = true; errorState = true;
stop(); stop();
} }
@@ -490,7 +490,7 @@ public class WalletService extends Service {
return true; // true is important so that onUnbind is also called next time return true; // true is important so that onUnbind is also called next time
} }
private boolean start(String walletName, String walletPassword) { private Wallet.ConnectionStatus start(String walletName, String walletPassword) {
Timber.d("start()"); Timber.d("start()");
startNotfication(); startNotfication();
showProgress(getString(R.string.status_wallet_loading)); showProgress(getString(R.string.status_wallet_loading));
@@ -498,9 +498,11 @@ public class WalletService extends Service {
if (listener == null) { if (listener == null) {
Timber.d("start() loadWallet"); Timber.d("start() loadWallet");
Wallet aWallet = loadWallet(walletName, walletPassword); Wallet aWallet = loadWallet(walletName, walletPassword);
if ((aWallet == null) || (aWallet.getConnectionStatus() != Wallet.ConnectionStatus.ConnectionStatus_Connected)) { Wallet.ConnectionStatus connStatus = Wallet.ConnectionStatus.ConnectionStatus_Disconnected;
if (aWallet != null) connStatus = aWallet.getConnectionStatus();
if (connStatus != Wallet.ConnectionStatus.ConnectionStatus_Connected) {
if (aWallet != null) aWallet.close(); if (aWallet != null) aWallet.close();
return false; return connStatus;
} }
listener = new MyWalletListener(); listener = new MyWalletListener();
listener.start(); listener.start();
@@ -511,7 +513,7 @@ public class WalletService extends Service {
// if we try to refresh the history here we get occasional segfaults! // if we try to refresh the history here we get occasional segfaults!
// doesnt matter since we update as soon as we get a new block anyway // doesnt matter since we update as soon as we get a new block anyway
Timber.d("start() done"); Timber.d("start() done");
return true; return Wallet.ConnectionStatus.ConnectionStatus_Connected;
} }
public void stop() { public void stop() {
@@ -550,8 +552,9 @@ public class WalletService extends Service {
showProgress(30); showProgress(30);
if (walletMgr.walletExists(path)) { if (walletMgr.walletExists(path)) {
Timber.d("open wallet %s", path); Timber.d("open wallet %s", path);
int hw = WalletManager.getInstance().queryWalletHardware(path + ".keys", walletPassword); Wallet.Device device = WalletManager.getInstance().queryWalletDevice(path + ".keys", walletPassword);
if (observer != null) observer.onWalletOpen(hw); Timber.d("device is %s", device.toString());
if (observer != null) observer.onWalletOpen(device);
wallet = walletMgr.openWallet(path, walletPassword); wallet = walletMgr.openWallet(path, walletPassword);
showProgress(60); showProgress(60);
Timber.d("wallet opened"); Timber.d("wallet opened");

View File

@@ -76,10 +76,14 @@ import okhttp3.HttpUrl;
import timber.log.Timber; import timber.log.Timber;
public class Helper { public class Helper {
static private final String FLAVOR_SUFFIX =
(BuildConfig.FLAVOR.equals("prod") ? "" : "." + BuildConfig.FLAVOR)
+ (BuildConfig.DEBUG ? "-debug" : "");
static public final String CRYPTO = "XMR"; static public final String CRYPTO = "XMR";
static private final String WALLET_DIR = "monerujo" + (BuildConfig.DEBUG ? "-debug" : ""); static private final String WALLET_DIR = "monerujo" + FLAVOR_SUFFIX;
static private final String HOME_DIR = "monero" + (BuildConfig.DEBUG ? "-debug" : ""); static private final String HOME_DIR = "monero" + FLAVOR_SUFFIX;
static public int DISPLAY_DIGITS_INFO = 5; static public int DISPLAY_DIGITS_INFO = 5;

View File

@@ -53,7 +53,7 @@
app:activeDot="0" app:activeDot="0"
app:dotSize="12dp" app:dotSize="12dp"
app:inactiveColor="@color/dotGray" app:inactiveColor="@color/dotGray"
app:numberDots="4" /> app:numberDots="3" />
<Button <Button
android:id="@+id/bNext" android:id="@+id/bNext"

View File

@@ -1,51 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/etDummy"
android:layout_width="0dp"
android:layout_height="0dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16sp"
android:layout_marginTop="16sp"
android:orientation="horizontal">
<TextView
style="@style/MoneroLabel.Caps.Gray.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:layout_marginEnd="8dp"
android:text="@string/label_send_settings_advanced"
android:textAlignment="textEnd" />
<Spinner
android:id="@+id/sPriority"
style="@style/MoneroSpinner"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:entries="@array/priority"
android:textAlignment="center" />
</LinearLayout>
<TextView
style="@style/MoneroFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_info_outline_gray_24dp"
android:gravity="center"
android:text="@string/info_send_prio_fees" />
</LinearLayout>

View File

@@ -235,7 +235,6 @@
<string name="send_available">Verfügbar: %1$s XMR</string> <string name="send_available">Verfügbar: %1$s XMR</string>
<string name="send_address_title">Adresse</string> <string name="send_address_title">Adresse</string>
<string name="send_amount_title">Betrag</string> <string name="send_amount_title">Betrag</string>
<string name="send_settings_title">Einstellungen</string>
<string name="send_confirm_title">Bestätigen</string> <string name="send_confirm_title">Bestätigen</string>
<string name="send_success_title">Fertig</string> <string name="send_success_title">Fertig</string>
@@ -345,13 +344,15 @@
<string name="send_address_no_dnssec">OpenAlias ohne DNSSEC - Adresse kann gefälscht sein!</string> <string name="send_address_no_dnssec">OpenAlias ohne DNSSEC - Adresse kann gefälscht sein!</string>
<string name="send_address_hint">Empfänger XMR/BTC Adresse oder OpenAlias</string> <string name="send_address_hint">Empfänger XMR/BTC Adresse oder OpenAlias</string>
<string name="progress_nfc_write">Writing Tag</string> <string name="progress_nfc_write">Schreibe Tag</string>
<string name="nfc_write_failed">Writing Tag failed!</string> <string name="nfc_write_failed">Schreiben des Tags fehlgeschlagen!</string>
<string name="nfc_write_successful">Writing Tag successful</string> <string name="nfc_write_successful">Tag erfolgreich geschrieben</string>
<string name="nfc_tag_unsupported">Tag does not support NDEF!</string> <string name="nfc_tag_unsupported">Tag unterstützt NDEF nicht!</string>
<string name="nfc_tag_size">Tag provides %d bytes, but we need %d!</string> <string name="nfc_tag_size">Tag bietet %1$d Bytes, aber wir brauchen %2$d!</string>
<string name="nfc_tag_read_undef">I don\'t understand the Tag!</string> <string name="nfc_tag_read_undef">Ich verstehe den Tag nicht!</string>
<string name="nfc_tag_read_what">I don\'t know what you want!</string> <string name="nfc_tag_read_what">Ich weiß nicht, was du willst!</string>
<string name="nfc_tag_read_success">Reading Tag successful</string> <string name="nfc_tag_read_success">Tag erfolgreich gelesen</string>
<string name="nfc_tag_tap">NFC Available!</string> <string name="nfc_tag_tap">NFC verfügbar!</string>
<string name="status_wallet_connect_wrongversion">Node version incompatible - please upgrade!</string>
</resources> </resources>

View File

@@ -209,7 +209,6 @@
<string name="send_available">Υπόλοιπο: %1$s XMR</string> <string name="send_available">Υπόλοιπο: %1$s XMR</string>
<string name="send_address_title">Διεύθυνση</string> <string name="send_address_title">Διεύθυνση</string>
<string name="send_amount_title">Ποσό</string> <string name="send_amount_title">Ποσό</string>
<string name="send_settings_title">Ρυθμίσεις</string>
<string name="send_confirm_title">Επιβεβαίωση</string> <string name="send_confirm_title">Επιβεβαίωση</string>
<string name="send_success_title">Έγινε</string> <string name="send_success_title">Έγινε</string>
@@ -340,7 +339,7 @@
<string name="nfc_write_failed">Writing Tag failed!</string> <string name="nfc_write_failed">Writing Tag failed!</string>
<string name="nfc_write_successful">Writing Tag successful</string> <string name="nfc_write_successful">Writing Tag successful</string>
<string name="nfc_tag_unsupported">Tag does not support NDEF!</string> <string name="nfc_tag_unsupported">Tag does not support NDEF!</string>
<string name="nfc_tag_size">Tag provides %d bytes, but we need %d!</string> <string name="nfc_tag_size">Tag provides %1$d bytes, but we need %2$d!</string>
<string name="nfc_tag_read_undef">I don\'t understand the Tag!</string> <string name="nfc_tag_read_undef">I don\'t understand the Tag!</string>
<string name="nfc_tag_read_what">I don\'t know what you want!</string> <string name="nfc_tag_read_what">I don\'t know what you want!</string>
<string name="nfc_tag_read_success">Reading Tag successful</string> <string name="nfc_tag_read_success">Reading Tag successful</string>
@@ -353,4 +352,6 @@
<string name="send_address_resolve_openalias">Resolving OpenAlias&#8230;</string> <string name="send_address_resolve_openalias">Resolving OpenAlias&#8230;</string>
<string name="send_address_no_dnssec">OpenAlias without DNSSEC - address may be spoofed</string> <string name="send_address_no_dnssec">OpenAlias without DNSSEC - address may be spoofed</string>
<string name="send_address_hint">Receiver\'s XMR/BTC Address or OpenAlias</string> <string name="send_address_hint">Receiver\'s XMR/BTC Address or OpenAlias</string>
<string name="status_wallet_connect_wrongversion">Node version incompatible - please upgrade!</string>
</resources> </resources>

View File

@@ -174,7 +174,6 @@
<string name="send_available">Fondos disponibles: %1$s XMR</string> <string name="send_available">Fondos disponibles: %1$s XMR</string>
<string name="send_address_title">Dirección</string> <string name="send_address_title">Dirección</string>
<string name="send_amount_title">Monto</string> <string name="send_amount_title">Monto</string>
<string name="send_settings_title">Ajustes</string>
<string name="send_confirm_title">Aprobar</string> <string name="send_confirm_title">Aprobar</string>
<string name="send_success_title">Hecho</string> <string name="send_success_title">Hecho</string>
@@ -327,7 +326,7 @@
<string name="nfc_write_failed">Writing Tag failed!</string> <string name="nfc_write_failed">Writing Tag failed!</string>
<string name="nfc_write_successful">Writing Tag successful</string> <string name="nfc_write_successful">Writing Tag successful</string>
<string name="nfc_tag_unsupported">Tag does not support NDEF!</string> <string name="nfc_tag_unsupported">Tag does not support NDEF!</string>
<string name="nfc_tag_size">Tag provides %d bytes, but we need %d!</string> <string name="nfc_tag_size">Tag provides %1$d bytes, but we need %2$d!</string>
<string name="nfc_tag_read_undef">I don\'t understand the Tag!</string> <string name="nfc_tag_read_undef">I don\'t understand the Tag!</string>
<string name="nfc_tag_read_what">I don\'t know what you want!</string> <string name="nfc_tag_read_what">I don\'t know what you want!</string>
<string name="nfc_tag_read_success">Reading Tag successful</string> <string name="nfc_tag_read_success">Reading Tag successful</string>
@@ -340,4 +339,6 @@
<string name="send_address_resolve_openalias">Resolving OpenAlias&#8230;</string> <string name="send_address_resolve_openalias">Resolving OpenAlias&#8230;</string>
<string name="send_address_no_dnssec">OpenAlias without DNSSEC - address may be spoofed</string> <string name="send_address_no_dnssec">OpenAlias without DNSSEC - address may be spoofed</string>
<string name="send_address_hint">Receiver\'s XMR/BTC Address or OpenAlias</string> <string name="send_address_hint">Receiver\'s XMR/BTC Address or OpenAlias</string>
<string name="status_wallet_connect_wrongversion">Node version incompatible - please upgrade!</string>
</resources> </resources>

View File

@@ -237,7 +237,6 @@
<string name="send_available">Solde : %1$s XMR</string> <string name="send_available">Solde : %1$s XMR</string>
<string name="send_address_title">Adresse</string> <string name="send_address_title">Adresse</string>
<string name="send_amount_title">Montant</string> <string name="send_amount_title">Montant</string>
<string name="send_settings_title">Paramètres</string>
<string name="send_confirm_title">Confirmation</string> <string name="send_confirm_title">Confirmation</string>
<string name="send_success_title">Terminé</string> <string name="send_success_title">Terminé</string>
@@ -336,24 +335,26 @@
<string name="toast_ledger_attached">%1$s connecté</string> <string name="toast_ledger_attached">%1$s connecté</string>
<string name="toast_ledger_detached">%1$s déconnecté</string> <string name="toast_ledger_detached">%1$s déconnecté</string>
<string name="progress_nfc_write">Writing Tag</string> <string name="progress_nfc_write">Écriture du Tag</string>
<string name="nfc_write_failed">Writing Tag failed!</string> <string name="nfc_write_failed">Échec de l\'écriture du Tag !</string>
<string name="nfc_write_successful">Writing Tag successful</string> <string name="nfc_write_successful">Tag écrit avec succès</string>
<string name="nfc_tag_unsupported">Tag does not support NDEF!</string> <string name="nfc_tag_unsupported">le Tag ne supporte pas NDEF !</string>
<string name="nfc_tag_size">Tag provides %d bytes, but we need %d!</string> <string name="nfc_tag_size">Le Tag donne %1$d octets, mais il en faut %2$d !</string>
<string name="nfc_tag_read_undef">I don\'t understand the Tag!</string> <string name="nfc_tag_read_undef">Je ne comprend pas le Tag !</string>
<string name="nfc_tag_read_what">I don\'t know what you want!</string> <string name="nfc_tag_read_what">Je ne sais pas ce que vous voulez !</string>
<string name="nfc_tag_read_success">Reading Tag successful</string> <string name="nfc_tag_read_success">Tag lut avec succès</string>
<string name="nfc_tag_tap">NFC Available!</string> <string name="nfc_tag_tap">NFC Disponible !</string>
<string name="menu_language">Language</string> <string name="menu_language">Langue</string>
<string name="language_system_default">Use System Language</string> <string name="language_system_default">Utiliser la Langue du Système</string>
<string name="receive_desc_hint">Description (optional)</string> <string name="receive_desc_hint">Description (optionnelle)</string>
<string name="send_address_not_openalias">OpenAlias address not available</string> <string name="send_address_not_openalias">Adresse OpenAlias indisponible</string>
<string name="send_address_openalias">OpenAlias secure &#x2714;</string> <string name="send_address_openalias">Sécurisé OpenAlias &#x2714;</string>
<string name="send_address_resolve_openalias">Resolving OpenAlias&#8230;</string> <string name="send_address_resolve_openalias">Résolution OpenAlias&#8230;</string>
<string name="send_address_no_dnssec">OpenAlias without DNSSEC - address may be spoofed</string> <string name="send_address_no_dnssec">OpenAlias sans DNSSEC - l\'adresse pourrait être usurpée !</string>
<string name="send_address_hint">Receiver\'s XMR/BTC Address or OpenAlias</string> <string name="send_address_hint">Adresse ou OpenAlias XMR/BTC du Destinataire</string>
<string name="status_wallet_connect_wrongversion">Node version incompatible - please upgrade!</string>
</resources> </resources>

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