mirror of https://github.com/m2049r/xmrwallet.git
changes for monero v0.12 (#214)
* new version id & name * witness checksums * build docs updated for v0.12 * remove binaries * setenv HOME for ringdb to 'monero' in shared storage * min ringsize 7 * remove boost_locale and zmq from build - don't need them for wallet_api * splits for all archs * throw IndexOutOfBounds in case the TX is empty * donate, you ungrateful bastards! (removed donations to make google happy)
This commit is contained in:
parent
b1f530e64a
commit
a9092497b2
|
@ -60,9 +60,13 @@ set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
|
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# Monero set(libs_to_merge wallet cryptonote_core cryptonote_basic mnemonics common cncrypto ringct)
|
# Monero
|
||||||
#############
|
#############
|
||||||
|
|
||||||
|
add_library(wallet_api STATIC IMPORTED)
|
||||||
|
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet_api.a)
|
||||||
|
|
||||||
add_library(wallet STATIC IMPORTED)
|
add_library(wallet STATIC IMPORTED)
|
||||||
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
|
||||||
|
@ -91,11 +95,9 @@ add_library(ringct STATIC IMPORTED)
|
||||||
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
|
||||||
|
|
||||||
#####
|
add_library(ringct_basic STATIC IMPORTED)
|
||||||
|
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
|
||||||
add_library(p2p STATIC IMPORTED)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct_basic.a)
|
||||||
set_target_properties(p2p PROPERTIES IMPORTED_LOCATION
|
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libp2p.a)
|
|
||||||
|
|
||||||
add_library(blockchain_db STATIC IMPORTED)
|
add_library(blockchain_db STATIC IMPORTED)
|
||||||
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
||||||
|
@ -113,7 +115,6 @@ add_library(unbound STATIC IMPORTED)
|
||||||
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
|
||||||
|
|
||||||
####
|
|
||||||
add_library(epee STATIC IMPORTED)
|
add_library(epee STATIC IMPORTED)
|
||||||
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
|
||||||
|
@ -122,9 +123,21 @@ add_library(blocks STATIC IMPORTED)
|
||||||
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
|
||||||
|
|
||||||
add_library(miniupnpc STATIC IMPORTED)
|
add_library(checkpoints STATIC IMPORTED)
|
||||||
set_target_properties(miniupnpc PROPERTIES IMPORTED_LOCATION
|
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libminiupnpc.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcheckpoints.a)
|
||||||
|
|
||||||
|
add_library(device STATIC IMPORTED)
|
||||||
|
set_target_properties(device PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice.a)
|
||||||
|
|
||||||
|
add_library(multisig STATIC IMPORTED)
|
||||||
|
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmultisig.a)
|
||||||
|
|
||||||
|
add_library(version STATIC IMPORTED)
|
||||||
|
set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libversion.a)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# System
|
# System
|
||||||
|
@ -137,23 +150,26 @@ include_directories( ${EXTERNAL_LIBS_DIR}/monero/include )
|
||||||
message(STATUS EXTERNAL_LIBS_DIR : ${EXTERNAL_LIBS_DIR})
|
message(STATUS EXTERNAL_LIBS_DIR : ${EXTERNAL_LIBS_DIR})
|
||||||
|
|
||||||
target_link_libraries( monerujo
|
target_link_libraries( monerujo
|
||||||
|
|
||||||
|
wallet_api
|
||||||
wallet
|
wallet
|
||||||
cryptonote_core
|
cryptonote_core
|
||||||
cryptonote_basic
|
cryptonote_basic
|
||||||
mnemonics
|
mnemonics
|
||||||
ringct
|
ringct
|
||||||
|
ringct_basic
|
||||||
common
|
common
|
||||||
cncrypto
|
cncrypto
|
||||||
|
|
||||||
blockchain_db
|
blockchain_db
|
||||||
lmdb
|
lmdb
|
||||||
easylogging
|
easylogging
|
||||||
unbound
|
unbound
|
||||||
p2p
|
|
||||||
|
|
||||||
epee
|
epee
|
||||||
blocks
|
blocks
|
||||||
miniupnpc
|
checkpoints
|
||||||
|
device
|
||||||
|
multisig
|
||||||
|
version
|
||||||
|
|
||||||
boost_chrono
|
boost_chrono
|
||||||
boost_date_time
|
boost_date_time
|
||||||
|
|
|
@ -8,8 +8,8 @@ android {
|
||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 74
|
versionCode 82
|
||||||
versionName "1.3.14 'Satoshis Dream'"
|
versionName "1.4.2 'Monero Spedner'"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
|
@ -42,7 +42,7 @@ android {
|
||||||
enable true
|
enable true
|
||||||
reset()
|
reset()
|
||||||
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||||
universalApk false
|
universalApk true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,5 +104,7 @@ dependencyVerification {
|
||||||
'com.google.zxing:core:bba7724e02a997cec38213af77133ee8e24b0d5cf5fa7ecbc16a4fa93f11ee0d',
|
'com.google.zxing:core:bba7724e02a997cec38213af77133ee8e24b0d5cf5fa7ecbc16a4fa93f11ee0d',
|
||||||
'com.squareup.okio:okio:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850',
|
'com.squareup.okio:okio:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850',
|
||||||
'com.squareup.okhttp3:okhttp:7265adbd6f028aade307f58569d814835cd02bc9beffb70c25f72c9de50d61c4',
|
'com.squareup.okhttp3:okhttp:7265adbd6f028aade307f58569d814835cd02bc9beffb70c25f72c9de50d61c4',
|
||||||
|
'com.jakewharton.timber:timber:35c22867f2673132e97e17857d36bb2fc25f5790f0425406833ed0254d62fc66',
|
||||||
|
'com.nulab-inc:zxcvbn:18d7862a6abd2705defec478d77dedadf8f3bb7cf811df22995494f05485785f',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,17 +253,18 @@ JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
jstring language,
|
jstring language,
|
||||||
jboolean isTestNet) {
|
jint networkType) {
|
||||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
const char *_language = env->GetStringUTFChars(language, NULL);
|
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||||
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWallet(
|
Bitmonero::WalletManagerFactory::getWalletManager()->createWallet(
|
||||||
std::string(_path),
|
std::string(_path),
|
||||||
std::string(_password),
|
std::string(_password),
|
||||||
std::string(_language),
|
std::string(_language),
|
||||||
isTestNet);
|
_networkType);
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
env->ReleaseStringUTFChars(password, _password);
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
|
@ -274,15 +275,16 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletJ(JNIEnv *env, jobject
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
jboolean isTestNet) {
|
jint networkType) {
|
||||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->openWallet(
|
Bitmonero::WalletManagerFactory::getWalletManager()->openWallet(
|
||||||
std::string(_path),
|
std::string(_path),
|
||||||
std::string(_password),
|
std::string(_password),
|
||||||
isTestNet);
|
_networkType);
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
env->ReleaseStringUTFChars(password, _password);
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
|
@ -293,19 +295,20 @@ JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
jstring mnemonic,
|
jstring mnemonic,
|
||||||
jboolean isTestNet,
|
jint networkType,
|
||||||
jlong restoreHeight) {
|
jlong restoreHeight) {
|
||||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
const char *_mnemonic = env->GetStringUTFChars(mnemonic, NULL);
|
const char *_mnemonic = env->GetStringUTFChars(mnemonic, NULL);
|
||||||
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
||||||
std::string(_path),
|
std::string(_path),
|
||||||
std::string(_password),
|
std::string(_password),
|
||||||
std::string(_mnemonic),
|
std::string(_mnemonic),
|
||||||
isTestNet,
|
_networkType,
|
||||||
restoreHeight);
|
(uint64_t) restoreHeight);
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
env->ReleaseStringUTFChars(password, _password);
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
|
@ -314,10 +317,10 @@ Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobje
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletWithKeysJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
jstring language,
|
jstring language,
|
||||||
jboolean isTestNet,
|
jint networkType,
|
||||||
jlong restoreHeight,
|
jlong restoreHeight,
|
||||||
jstring addressString,
|
jstring addressString,
|
||||||
jstring viewKeyString,
|
jstring viewKeyString,
|
||||||
|
@ -325,17 +328,18 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletWithKeysJ(JNIEnv *env,
|
||||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
const char *_language = env->GetStringUTFChars(language, NULL);
|
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||||
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
const char *_addressString = env->GetStringUTFChars(addressString, NULL);
|
const char *_addressString = env->GetStringUTFChars(addressString, NULL);
|
||||||
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, NULL);
|
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, NULL);
|
||||||
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, NULL);
|
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletWithKeys(
|
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
|
||||||
std::string(_path),
|
std::string(_path),
|
||||||
std::string(_password),
|
std::string(_password),
|
||||||
std::string(_language),
|
std::string(_language),
|
||||||
isTestNet,
|
_networkType,
|
||||||
restoreHeight,
|
(uint64_t) restoreHeight,
|
||||||
std::string(_addressString),
|
std::string(_addressString),
|
||||||
std::string(_viewKeyString),
|
std::string(_viewKeyString),
|
||||||
std::string(_spendKeyString));
|
std::string(_spendKeyString));
|
||||||
|
@ -356,7 +360,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_walletExists(JNIEnv *env, jobject
|
||||||
bool exists =
|
bool exists =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->walletExists(std::string(_path));
|
Bitmonero::WalletManagerFactory::getWalletManager()->walletExists(std::string(_path));
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
return exists;
|
return static_cast<jboolean>(exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
|
@ -371,7 +375,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_verifyWalletPassword(JNIEnv *env,
|
||||||
std::string(_keys_file_name), std::string(_password), watch_only);
|
std::string(_keys_file_name), std::string(_password), watch_only);
|
||||||
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 passwordOk;
|
return static_cast<jboolean>(passwordOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -440,7 +444,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_getBlockTarget(JNIEnv *env, jobjec
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_isMining(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_WalletManager_isMining(JNIEnv *env, jobject instance) {
|
||||||
return Bitmonero::WalletManagerFactory::getWalletManager()->isMining();
|
return static_cast<jboolean>(Bitmonero::WalletManagerFactory::getWalletManager()->isMining());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
|
@ -454,12 +458,12 @@ Java_com_m2049r_xmrwallet_model_WalletManager_startMining(JNIEnv *env, jobject i
|
||||||
background_mining,
|
background_mining,
|
||||||
ignore_battery);
|
ignore_battery);
|
||||||
env->ReleaseStringUTFChars(address, _address);
|
env->ReleaseStringUTFChars(address, _address);
|
||||||
return success;
|
return static_cast<jboolean>(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_stopMining(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_WalletManager_stopMining(JNIEnv *env, jobject instance) {
|
||||||
return Bitmonero::WalletManagerFactory::getWalletManager()->stopMining();
|
return static_cast<jboolean>(Bitmonero::WalletManagerFactory::getWalletManager()->stopMining());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
|
@ -493,7 +497,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_closeJ(JNIEnv *env, jobject instan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOGD("wallet closed");
|
LOGD("wallet closed");
|
||||||
return closeSuccess;
|
return static_cast<jboolean>(closeSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -543,7 +547,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_setPassword(JNIEnv *env, jobject instance
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
bool success = wallet->setPassword(std::string(_password));
|
bool success = wallet->setPassword(std::string(_password));
|
||||||
env->ReleaseStringUTFChars(password, _password);
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
return success;
|
return static_cast<jboolean>(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
|
@ -558,10 +562,10 @@ Java_com_m2049r_xmrwallet_model_Wallet_getPath(JNIEnv *env, jobject instance) {
|
||||||
return env->NewStringUTF(wallet->path().c_str());
|
return env->NewStringUTF(wallet->path().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_isTestNet(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_Wallet_nettype(JNIEnv *env, jobject instance) {
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
return wallet->testnet();
|
return wallet->nettype();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO virtual void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const = 0;
|
//TODO virtual void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const = 0;
|
||||||
|
@ -599,7 +603,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_store(JNIEnv *env, jobject instance,
|
||||||
LOGE("store() %s", wallet->errorString().c_str());
|
LOGE("store() %s", wallet->errorString().c_str());
|
||||||
}
|
}
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
return success;
|
return static_cast<jboolean>(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
|
@ -619,12 +623,13 @@ Java_com_m2049r_xmrwallet_model_Wallet_initJ(JNIEnv *env, jobject instance,
|
||||||
const char *_daemon_username = env->GetStringUTFChars(daemon_username, NULL);
|
const char *_daemon_username = env->GetStringUTFChars(daemon_username, NULL);
|
||||||
const char *_daemon_password = env->GetStringUTFChars(daemon_password, NULL);
|
const char *_daemon_password = env->GetStringUTFChars(daemon_password, NULL);
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
bool status = wallet->init(_daemon_address, upper_transaction_size_limit, _daemon_username,
|
bool status = wallet->init(_daemon_address, (uint64_t) upper_transaction_size_limit,
|
||||||
|
_daemon_username,
|
||||||
_daemon_password);
|
_daemon_password);
|
||||||
env->ReleaseStringUTFChars(daemon_address, _daemon_address);
|
env->ReleaseStringUTFChars(daemon_address, _daemon_address);
|
||||||
env->ReleaseStringUTFChars(daemon_username, _daemon_username);
|
env->ReleaseStringUTFChars(daemon_username, _daemon_username);
|
||||||
env->ReleaseStringUTFChars(daemon_password, _daemon_password);
|
env->ReleaseStringUTFChars(daemon_password, _daemon_password);
|
||||||
return status;
|
return static_cast<jboolean>(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual bool createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const = 0;
|
// virtual bool createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const = 0;
|
||||||
|
@ -655,7 +660,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getUnlockedBalance(JNIEnv *env, jobject i
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_isWatchOnly(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_Wallet_isWatchOnly(JNIEnv *env, jobject instance) {
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
return wallet->watchOnly();
|
return static_cast<jboolean>(wallet->watchOnly());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
|
@ -687,7 +692,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getDaemonBlockChainTargetHeight(JNIEnv *e
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_isSynchronized(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_Wallet_isSynchronized(JNIEnv *env, jobject instance) {
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
return wallet->synchronized();
|
return static_cast<jboolean>(wallet->synchronized());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
|
@ -722,16 +727,17 @@ Java_com_m2049r_xmrwallet_model_Wallet_isPaymentIdValid(JNIEnv *env, jobject cla
|
||||||
const char *_payment_id = env->GetStringUTFChars(payment_id, NULL);
|
const char *_payment_id = env->GetStringUTFChars(payment_id, NULL);
|
||||||
bool isValid = Bitmonero::Wallet::paymentIdValid(_payment_id);
|
bool isValid = Bitmonero::Wallet::paymentIdValid(_payment_id);
|
||||||
env->ReleaseStringUTFChars(payment_id, _payment_id);
|
env->ReleaseStringUTFChars(payment_id, _payment_id);
|
||||||
return isValid;
|
return static_cast<jboolean>(isValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_isAddressValid(JNIEnv *env, jobject clazz,
|
Java_com_m2049r_xmrwallet_model_Wallet_isAddressValid(JNIEnv *env, jobject clazz,
|
||||||
jstring address, jboolean isTestNet) {
|
jstring address, jint networkType) {
|
||||||
const char *_address = env->GetStringUTFChars(address, NULL);
|
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||||
bool isValid = Bitmonero::Wallet::addressValid(_address, isTestNet);
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
|
bool isValid = Bitmonero::Wallet::addressValid(_address, _networkType);
|
||||||
env->ReleaseStringUTFChars(address, _address);
|
env->ReleaseStringUTFChars(address, _address);
|
||||||
return isValid;
|
return static_cast<jboolean>(isValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO static static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error);
|
//TODO static static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error);
|
||||||
|
@ -739,9 +745,10 @@ Java_com_m2049r_xmrwallet_model_Wallet_isAddressValid(JNIEnv *env, jobject clazz
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_getPaymentIdFromAddress(JNIEnv *env, jobject clazz,
|
Java_com_m2049r_xmrwallet_model_Wallet_getPaymentIdFromAddress(JNIEnv *env, jobject clazz,
|
||||||
jstring address,
|
jstring address,
|
||||||
jboolean isTestNet) {
|
jint networkType) {
|
||||||
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
const char *_address = env->GetStringUTFChars(address, NULL);
|
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||||
std::string payment_id = Bitmonero::Wallet::paymentIdFromAddress(_address, isTestNet);
|
std::string payment_id = Bitmonero::Wallet::paymentIdFromAddress(_address, _networkType);
|
||||||
env->ReleaseStringUTFChars(address, _address);
|
env->ReleaseStringUTFChars(address, _address);
|
||||||
return env->NewStringUTF(payment_id.c_str());
|
return env->NewStringUTF(payment_id.c_str());
|
||||||
}
|
}
|
||||||
|
@ -766,7 +773,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_pauseRefresh(JNIEnv *env, jobject instanc
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_refresh(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_Wallet_refresh(JNIEnv *env, jobject instance) {
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
return wallet->refresh();
|
return static_cast<jboolean>(wallet->refresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
@ -880,7 +887,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_setUserNote(JNIEnv *env, jobject instance
|
||||||
env->ReleaseStringUTFChars(txid, _txid);
|
env->ReleaseStringUTFChars(txid, _txid);
|
||||||
env->ReleaseStringUTFChars(note, _note);
|
env->ReleaseStringUTFChars(note, _note);
|
||||||
|
|
||||||
return success;
|
return static_cast<jboolean>(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
|
@ -1029,7 +1036,7 @@ Java_com_m2049r_xmrwallet_model_PendingTransaction_commit(JNIEnv *env, jobject i
|
||||||
bool success = tx->commit(_filename, overwrite);
|
bool success = tx->commit(_filename, overwrite);
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(filename, _filename);
|
env->ReleaseStringUTFChars(filename, _filename);
|
||||||
return success;
|
return static_cast<jboolean>(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1051,10 +1058,13 @@ Java_com_m2049r_xmrwallet_model_PendingTransaction_getFee(JNIEnv *env, jobject i
|
||||||
|
|
||||||
// TODO this returns a vector of strings - deal with this later - for now return first one
|
// TODO this returns a vector of strings - deal with this later - for now return first one
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_getFirstTxId(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_PendingTransaction_getFirstTxIdJ(JNIEnv *env, jobject instance) {
|
||||||
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
||||||
std::vector<std::string> txids = tx->txid();
|
std::vector<std::string> txids = tx->txid();
|
||||||
return env->NewStringUTF(txids.front().c_str());
|
if (!txids.empty())
|
||||||
|
return env->NewStringUTF(txids.front().c_str());
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -386,7 +386,7 @@ public class GenerateFragment extends Fragment {
|
||||||
|
|
||||||
private boolean checkAddress() {
|
private boolean checkAddress() {
|
||||||
String address = etWalletAddress.getEditText().getText().toString();
|
String address = etWalletAddress.getEditText().getText().toString();
|
||||||
boolean ok = Wallet.isAddressValid(address, WalletManager.getInstance().isTestNet());
|
boolean ok = Wallet.isAddressValid(address);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
etWalletAddress.setError(getString(R.string.generate_check_address));
|
etWalletAddress.setError(getString(R.string.generate_check_address));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -34,6 +34,7 @@ import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
@ -81,7 +82,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||||
|
|
||||||
bAccept = (Button) view.findViewById(R.id.bAccept);
|
bAccept = (Button) view.findViewById(R.id.bAccept);
|
||||||
|
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
boolean testnet = WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet;
|
||||||
tvWalletMnemonic.setTextIsSelectable(testnet);
|
tvWalletMnemonic.setTextIsSelectable(testnet);
|
||||||
tvWalletSpendKey.setTextIsSelectable(testnet);
|
tvWalletSpendKey.setTextIsSelectable(testnet);
|
||||||
|
|
||||||
|
@ -185,6 +186,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||||
name = wallet.getName();
|
name = wallet.getName();
|
||||||
status = wallet.getStatus();
|
status = wallet.getStatus();
|
||||||
if (status != Wallet.Status.Status_Ok) {
|
if (status != Wallet.Status.Status_Ok) {
|
||||||
|
Timber.e(wallet.getErrorString());
|
||||||
if (closeWallet) wallet.close();
|
if (closeWallet) wallet.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,10 +45,12 @@ import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.data.WalletNode;
|
||||||
import com.m2049r.xmrwallet.dialog.AboutFragment;
|
import com.m2049r.xmrwallet.dialog.AboutFragment;
|
||||||
import com.m2049r.xmrwallet.dialog.DonationFragment;
|
import com.m2049r.xmrwallet.dialog.CreditsFragment;
|
||||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||||
import com.m2049r.xmrwallet.dialog.PrivacyFragment;
|
import com.m2049r.xmrwallet.dialog.PrivacyFragment;
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.service.WalletService;
|
import com.m2049r.xmrwallet.service.WalletService;
|
||||||
|
@ -60,7 +62,6 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
|
@ -120,8 +121,8 @@ public class LoginActivity extends SecureActivity
|
||||||
case Toolbar.BUTTON_CLOSE:
|
case Toolbar.BUTTON_CLOSE:
|
||||||
finish();
|
finish();
|
||||||
break;
|
break;
|
||||||
case Toolbar.BUTTON_DONATE:
|
case Toolbar.BUTTON_CREDITS:
|
||||||
DonationFragment.display(getSupportFragmentManager());
|
CreditsFragment.display(getSupportFragmentManager());
|
||||||
break;
|
break;
|
||||||
case Toolbar.BUTTON_NONE:
|
case Toolbar.BUTTON_NONE:
|
||||||
default:
|
default:
|
||||||
|
@ -147,14 +148,14 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onWalletSelected(String walletName, String daemon, boolean testnet) {
|
public boolean onWalletSelected(String walletName, String daemon) {
|
||||||
if (daemon.length() == 0) {
|
if (daemon.length() == 0) {
|
||||||
Toast.makeText(this, getString(R.string.prompt_daemon_missing), Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, getString(R.string.prompt_daemon_missing), Toast.LENGTH_SHORT).show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (checkServiceRunning()) return false;
|
if (checkServiceRunning()) return false;
|
||||||
try {
|
try {
|
||||||
WalletNode aWalletNode = new WalletNode(walletName, daemon, testnet);
|
WalletNode aWalletNode = new WalletNode(walletName, daemon, WalletManager.getInstance().getNetworkType());
|
||||||
new AsyncOpenWallet().execute(aWalletNode);
|
new AsyncOpenWallet().execute(aWalletNode);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
Timber.e(ex.getLocalizedMessage());
|
Timber.e(ex.getLocalizedMessage());
|
||||||
|
@ -165,9 +166,8 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWalletDetails(final String walletName, boolean testnet) {
|
public void onWalletDetails(final String walletName) {
|
||||||
setNet(testnet);
|
Timber.d("details for wallet .%s.", walletName);
|
||||||
Timber.d("details for wallet ." + walletName + ".");
|
|
||||||
if (checkServiceRunning()) return;
|
if (checkServiceRunning()) return;
|
||||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -203,9 +203,8 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWalletReceive(String walletName, boolean testnet) {
|
public void onWalletReceive(String walletName) {
|
||||||
setNet(testnet);
|
Timber.d("receive for wallet .%s.", walletName);
|
||||||
Timber.d("receive for wallet ." + walletName + ".");
|
|
||||||
if (checkServiceRunning()) return;
|
if (checkServiceRunning()) return;
|
||||||
final File walletFile = Helper.getWalletFile(this, walletName);
|
final File walletFile = Helper.getWalletFile(this, walletName);
|
||||||
if (WalletManager.getInstance().walletExists(walletFile)) {
|
if (WalletManager.getInstance().walletExists(walletFile)) {
|
||||||
|
@ -439,8 +438,7 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAddWallet(boolean testnet, String type) {
|
public void onAddWallet(String type) {
|
||||||
setNet(testnet);
|
|
||||||
if (checkServiceRunning()) return;
|
if (checkServiceRunning()) return;
|
||||||
startGenerateFragment(type);
|
startGenerateFragment(type);
|
||||||
}
|
}
|
||||||
|
@ -537,7 +535,7 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkWalletPassword(String walletName, String password) {
|
private boolean checkWalletPassword(String walletName, String password) {
|
||||||
String walletPath = new File(Helper.getStorageRoot(getApplicationContext()),
|
String walletPath = new File(Helper.getWalletRoot(getApplicationContext()),
|
||||||
walletName + ".keys").getAbsolutePath();
|
walletName + ".keys").getAbsolutePath();
|
||||||
// only test view key
|
// only test view key
|
||||||
return WalletManager.getInstance().verifyWalletPassword(walletPath, password, true);
|
return WalletManager.getInstance().verifyWalletPassword(walletPath, password, true);
|
||||||
|
@ -566,20 +564,30 @@ public class LoginActivity extends SecureActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getStorageRoot() {
|
public File getStorageRoot() {
|
||||||
return Helper.getStorageRoot(getApplicationContext());
|
return Helper.getWalletRoot(getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showNet(boolean testnet) {
|
public void showNet() {
|
||||||
if (testnet) {
|
switch (WalletManager.getInstance().getNetworkType()) {
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
case NetworkType_Mainnet:
|
||||||
} else {
|
toolbar.setSubtitle(getString(R.string.connect_mainnet));
|
||||||
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
||||||
|
break;
|
||||||
|
case NetworkType_Testnet:
|
||||||
|
toolbar.setSubtitle(getString(R.string.connect_testnet));
|
||||||
|
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
||||||
|
break;
|
||||||
|
case NetworkType_Stagenet:
|
||||||
|
toolbar.setSubtitle(getString(R.string.connect_stagenet));
|
||||||
|
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("NetworkType unknown: " + WalletManager.getInstance().getNetworkType());
|
||||||
}
|
}
|
||||||
toolbar.setSubtitle(getString(testnet ? R.string.connect_testnet : R.string.connect_mainnet));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -636,7 +644,7 @@ public class LoginActivity extends SecureActivity
|
||||||
private class MyProgressDialog extends ProgressDialog {
|
private class MyProgressDialog extends ProgressDialog {
|
||||||
Activity activity;
|
Activity activity;
|
||||||
|
|
||||||
public MyProgressDialog(Activity activity, int msgId) {
|
MyProgressDialog(Activity activity, int msgId) {
|
||||||
super(activity);
|
super(activity);
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
setCancelable(false);
|
setCancelable(false);
|
||||||
|
@ -735,6 +743,7 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
void startLoginFragment() {
|
void startLoginFragment() {
|
||||||
|
Helper.setMoneroHome(this);
|
||||||
Fragment fragment = new LoginFragment();
|
Fragment fragment = new LoginFragment();
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.add(R.id.fragment_container, fragment).commit();
|
.add(R.id.fragment_container, fragment).commit();
|
||||||
|
@ -784,8 +793,8 @@ public class LoginActivity extends SecureActivity
|
||||||
|
|
||||||
File newWalletFile;
|
File newWalletFile;
|
||||||
|
|
||||||
public AsyncCreateWallet(final String name, final String password,
|
AsyncCreateWallet(final String name, final String password,
|
||||||
final WalletCreator walletCreator) {
|
final WalletCreator walletCreator) {
|
||||||
super();
|
super();
|
||||||
this.walletName = name;
|
this.walletName = name;
|
||||||
this.walletPassword = password;
|
this.walletPassword = password;
|
||||||
|
@ -1081,6 +1090,7 @@ public class LoginActivity extends SecureActivity
|
||||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||||
item.setChecked(loginFragment.onTestnetMenuItem());
|
item.setChecked(loginFragment.onTestnetMenuItem());
|
||||||
} catch (ClassCastException ex) {
|
} catch (ClassCastException ex) {
|
||||||
|
// never mind then
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
@ -1088,59 +1098,8 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNet(boolean testnet) {
|
public void setNetworkType(NetworkType networkType) {
|
||||||
WalletManager.getInstance().setDaemon("", testnet, "", "");
|
WalletManager.getInstance().setNetworkType(networkType);
|
||||||
}
|
|
||||||
|
|
||||||
static class WalletNode {
|
|
||||||
String name = null;
|
|
||||||
String host = "";
|
|
||||||
int port = 28081;
|
|
||||||
String user = "";
|
|
||||||
String password = "";
|
|
||||||
boolean isTestnet;
|
|
||||||
|
|
||||||
WalletNode(String walletName, String daemon, boolean isTestnet) {
|
|
||||||
if ((daemon == null) || daemon.isEmpty()) return;
|
|
||||||
this.name = walletName;
|
|
||||||
String daemonAddress;
|
|
||||||
String a[] = daemon.split("@");
|
|
||||||
if (a.length == 1) { // no credentials
|
|
||||||
daemonAddress = a[0];
|
|
||||||
} else if (a.length == 2) { // credentials
|
|
||||||
String userPassword[] = a[0].split(":");
|
|
||||||
if (userPassword.length != 2)
|
|
||||||
throw new IllegalArgumentException("User:Password invalid");
|
|
||||||
user = userPassword[0];
|
|
||||||
if (!user.isEmpty()) password = userPassword[1];
|
|
||||||
daemonAddress = a[1];
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Too many @");
|
|
||||||
}
|
|
||||||
|
|
||||||
String da[] = daemonAddress.split(":");
|
|
||||||
if ((da.length > 2) || (da.length < 1))
|
|
||||||
throw new IllegalArgumentException("Too many ':' or too few");
|
|
||||||
host = da[0];
|
|
||||||
if (da.length == 2) {
|
|
||||||
try {
|
|
||||||
port = Integer.parseInt(da[1]);
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
throw new IllegalArgumentException("Port not numeric");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
port = (isTestnet ? 28081 : 18081);
|
|
||||||
}
|
|
||||||
this.isTestnet = isTestnet;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getAddress() {
|
|
||||||
return host + ":" + port;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isValid() {
|
|
||||||
return !host.isEmpty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AsyncOpenWallet extends AsyncTask<WalletNode, Void, Integer> {
|
private class AsyncOpenWallet extends AsyncTask<WalletNode, Void, Integer> {
|
||||||
|
@ -1167,22 +1126,22 @@ public class LoginActivity extends SecureActivity
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long timeDA = new Date().getTime();
|
long timeDA = new Date().getTime();
|
||||||
SocketAddress address = new InetSocketAddress(walletNode.host, walletNode.port);
|
SocketAddress address = walletNode.getSocketAddress();
|
||||||
long timeDB = new Date().getTime();
|
long timeDB = new Date().getTime();
|
||||||
Timber.d("Resolving " + walletNode.host + " took " + (timeDB - timeDA) + "ms.");
|
Timber.d("Resolving " + walletNode.getAddress() + " took " + (timeDB - timeDA) + "ms.");
|
||||||
Socket socket = new Socket();
|
Socket socket = new Socket();
|
||||||
long timeA = new Date().getTime();
|
long timeA = new Date().getTime();
|
||||||
socket.connect(address, LoginActivity.DAEMON_TIMEOUT);
|
socket.connect(address, LoginActivity.DAEMON_TIMEOUT);
|
||||||
socket.close();
|
socket.close();
|
||||||
long timeB = new Date().getTime();
|
long timeB = new Date().getTime();
|
||||||
long time = timeB - timeA;
|
long time = timeB - timeA;
|
||||||
Timber.d("Daemon " + walletNode.host + " is " + time + "ms away.");
|
Timber.d("Daemon " + walletNode.getAddress() + " is " + time + "ms away.");
|
||||||
return (time < LoginActivity.DAEMON_TIMEOUT ? OK : TIMEOUT);
|
return (time < LoginActivity.DAEMON_TIMEOUT ? OK : TIMEOUT);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Timber.d("Cannot reach daemon " + walletNode.host + "/" + walletNode.port + " because " + ex.getMessage());
|
Timber.d("Cannot reach daemon %s because %s", walletNode.getAddress(), ex.getMessage());
|
||||||
return IOEX;
|
return IOEX;
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
Timber.d("Cannot reach daemon " + walletNode.host + "/" + walletNode.port + " because " + ex.getMessage());
|
Timber.d("Cannot reach daemon %s because %s", walletNode.getAddress(), ex.getMessage());
|
||||||
return INVALID;
|
return INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1196,7 +1155,7 @@ public class LoginActivity extends SecureActivity
|
||||||
dismissProgressDialog();
|
dismissProgressDialog();
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case OK:
|
case OK:
|
||||||
Timber.d("selected wallet is ." + walletNode.name + ".");
|
Timber.d("selected wallet is .%s.", walletNode.getName());
|
||||||
// now it's getting real, onValidateFields if wallet exists
|
// now it's getting real, onValidateFields if wallet exists
|
||||||
promptAndStart(walletNode);
|
promptAndStart(walletNode);
|
||||||
break;
|
break;
|
||||||
|
@ -1214,11 +1173,10 @@ public class LoginActivity extends SecureActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
void promptAndStart(WalletNode walletNode) {
|
void promptAndStart(WalletNode walletNode) {
|
||||||
File walletFile = Helper.getWalletFile(this, walletNode.name);
|
File walletFile = Helper.getWalletFile(this, walletNode.getName());
|
||||||
if (WalletManager.getInstance().walletExists(walletFile)) {
|
if (WalletManager.getInstance().walletExists(walletFile)) {
|
||||||
WalletManager.getInstance().
|
WalletManager.getInstance().setDaemon(walletNode);
|
||||||
setDaemon(walletNode.getAddress(), walletNode.isTestnet, walletNode.user, walletNode.password);
|
promptPassword(walletNode.getName(), new PasswordAction() {
|
||||||
promptPassword(walletNode.name, new PasswordAction() {
|
|
||||||
@Override
|
@Override
|
||||||
public void action(String walletName, String password) {
|
public void action(String walletName, String password) {
|
||||||
startWallet(walletName, password);
|
startWallet(walletName, password);
|
||||||
|
|
|
@ -45,6 +45,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||||
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.NodeList;
|
import com.m2049r.xmrwallet.util.NodeList;
|
||||||
|
@ -81,11 +82,11 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
|
|
||||||
File getStorageRoot();
|
File getStorageRoot();
|
||||||
|
|
||||||
boolean onWalletSelected(String wallet, String daemon, boolean testnet);
|
boolean onWalletSelected(String wallet, String daemon);
|
||||||
|
|
||||||
void onWalletDetails(String wallet, boolean testnet);
|
void onWalletDetails(String wallet);
|
||||||
|
|
||||||
void onWalletReceive(String wallet, boolean testnet);
|
void onWalletReceive(String wallet);
|
||||||
|
|
||||||
void onWalletRename(String name);
|
void onWalletRename(String name);
|
||||||
|
|
||||||
|
@ -93,14 +94,16 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
|
|
||||||
void onWalletArchive(String walletName);
|
void onWalletArchive(String walletName);
|
||||||
|
|
||||||
void onAddWallet(boolean testnet, String type);
|
void onAddWallet(String type);
|
||||||
|
|
||||||
void showNet(boolean testnet);
|
void showNet();
|
||||||
|
|
||||||
void setToolbarButton(int type);
|
void setToolbarButton(int type);
|
||||||
|
|
||||||
void setTitle(String title);
|
void setTitle(String title);
|
||||||
|
|
||||||
|
void setNetworkType(NetworkType networkType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -126,8 +129,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Timber.d("onResume()");
|
Timber.d("onResume()");
|
||||||
activityCallback.setTitle(null);
|
activityCallback.setTitle(null);
|
||||||
activityCallback.setToolbarButton(Toolbar.BUTTON_DONATE);
|
activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS);
|
||||||
activityCallback.showNet(isTestnet());
|
activityCallback.showNet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -244,13 +247,13 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
// Callbacks from WalletInfoAdapter
|
// Callbacks from WalletInfoAdapter
|
||||||
@Override
|
@Override
|
||||||
public void onInteraction(final View view, final WalletManager.WalletInfo infoItem) {
|
public void onInteraction(final View view, final WalletManager.WalletInfo infoItem) {
|
||||||
String x = isTestnet() ? "9A-" : "4-";
|
String addressPrefix = addressPrefix();
|
||||||
if (x.indexOf(infoItem.address.charAt(0)) < 0) {
|
if (addressPrefix.indexOf(infoItem.address.charAt(0)) < 0) {
|
||||||
Toast.makeText(getActivity(), getString(R.string.prompt_wrong_net), Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), getString(R.string.prompt_wrong_net), Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activityCallback.onWalletSelected(infoItem.name, getDaemon(), isTestnet())) {
|
if (activityCallback.onWalletSelected(infoItem.name, getDaemon())) {
|
||||||
savePrefs();
|
savePrefs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,11 +282,24 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String addressPrefix() {
|
||||||
|
switch (WalletManager.getInstance().getNetworkType()) {
|
||||||
|
case NetworkType_Testnet:
|
||||||
|
return "9A-";
|
||||||
|
case NetworkType_Mainnet:
|
||||||
|
return "4-";
|
||||||
|
case NetworkType_Stagenet:
|
||||||
|
return "5-";
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void filterList() {
|
private void filterList() {
|
||||||
displayedList.clear();
|
displayedList.clear();
|
||||||
String x = isTestnet() ? "9A" : "4";
|
String addressPrefix = addressPrefix();
|
||||||
for (WalletManager.WalletInfo s : walletList) {
|
for (WalletManager.WalletInfo s : walletList) {
|
||||||
if (x.indexOf(s.address.charAt(0)) >= 0) displayedList.add(s);
|
if (addressPrefix.indexOf(s.address.charAt(0)) >= 0) displayedList.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,11 +329,11 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showInfo(@NonNull String name) {
|
private void showInfo(@NonNull String name) {
|
||||||
activityCallback.onWalletDetails(name, isTestnet());
|
activityCallback.onWalletDetails(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showReceive(@NonNull String name) {
|
private void showReceive(@NonNull String name) {
|
||||||
activityCallback.onWalletReceive(name, isTestnet());
|
activityCallback.onWalletReceive(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -329,29 +345,31 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
inflater.inflate(R.menu.list_menu, menu);
|
inflater.inflate(R.menu.list_menu, menu);
|
||||||
menu.findItem(R.id.action_testnet).setChecked(isTestnet());
|
menu.findItem(R.id.action_testnet).setChecked(testnetCheckMenu);
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean testnet = BuildConfig.DEBUG;
|
private boolean testnetCheckMenu = BuildConfig.DEBUG;
|
||||||
|
|
||||||
boolean isTestnet() {
|
//boolean isTestnet() {
|
||||||
return testnet;
|
// return testnet;
|
||||||
}
|
//}
|
||||||
|
|
||||||
public boolean onTestnetMenuItem() {
|
public boolean onTestnetMenuItem() {
|
||||||
boolean lastState = testnet;
|
boolean lastState = testnetCheckMenu;
|
||||||
setNet(!lastState, true); // set and save
|
setNet(!lastState, true); // set and save
|
||||||
return !lastState;
|
return !lastState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNet(boolean testnet, boolean save) {
|
public void setNet(boolean testnetChecked, boolean save) {
|
||||||
this.testnet = testnet;
|
this.testnetCheckMenu = testnetChecked;
|
||||||
activityCallback.showNet(testnet);
|
NetworkType net = testnetChecked ? NetworkType.NetworkType_Testnet : NetworkType.NetworkType_Mainnet;
|
||||||
|
activityCallback.setNetworkType(net);
|
||||||
|
activityCallback.showNet();
|
||||||
if (save) {
|
if (save) {
|
||||||
savePrefs(true); // use previous state as we just clicked it
|
savePrefs(true); // use previous state as we just clicked it
|
||||||
}
|
}
|
||||||
if (testnet) {
|
if (testnetChecked) {
|
||||||
setDaemon(daemonTestNet);
|
setDaemon(daemonTestNet);
|
||||||
} else {
|
} else {
|
||||||
setDaemon(daemonMainNet);
|
setDaemon(daemonMainNet);
|
||||||
|
@ -379,7 +397,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
|
|
||||||
daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET));
|
daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET));
|
||||||
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, PREF_DAEMONLIST_TESTNET));
|
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, PREF_DAEMONLIST_TESTNET));
|
||||||
setNet(isTestnet(), false);
|
setNet(testnetCheckMenu, false);
|
||||||
|
|
||||||
showXmrtoEnabled = sharedPref.getBoolean(PREF_SHOW_XMRTO_ENABLED, true);
|
showXmrtoEnabled = sharedPref.getBoolean(PREF_SHOW_XMRTO_ENABLED, true);
|
||||||
}
|
}
|
||||||
|
@ -398,7 +416,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
void savePrefs(boolean usePreviousTestnetState) {
|
void savePrefs(boolean usePreviousTestnetState) {
|
||||||
Timber.d("SAVE / %s", usePreviousTestnetState);
|
Timber.d("SAVE / %s", usePreviousTestnetState);
|
||||||
// save the daemon address for the net
|
// save the daemon address for the net
|
||||||
boolean testnet = isTestnet() ^ usePreviousTestnetState;
|
boolean testnet = testnetCheckMenu ^ usePreviousTestnetState;
|
||||||
String daemon = getDaemon();
|
String daemon = getDaemon();
|
||||||
if (testnet) {
|
if (testnet) {
|
||||||
daemonTestNet.setRecent(daemon);
|
daemonTestNet.setRecent(daemon);
|
||||||
|
@ -484,19 +502,19 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||||
case R.id.fabNew:
|
case R.id.fabNew:
|
||||||
fabScreen.setVisibility(View.INVISIBLE);
|
fabScreen.setVisibility(View.INVISIBLE);
|
||||||
isFabOpen = false;
|
isFabOpen = false;
|
||||||
activityCallback.onAddWallet(isTestnet(), GenerateFragment.TYPE_NEW);
|
activityCallback.onAddWallet(GenerateFragment.TYPE_NEW);
|
||||||
break;
|
break;
|
||||||
case R.id.fabView:
|
case R.id.fabView:
|
||||||
animateFAB();
|
animateFAB();
|
||||||
activityCallback.onAddWallet(isTestnet(), GenerateFragment.TYPE_VIEWONLY);
|
activityCallback.onAddWallet(GenerateFragment.TYPE_VIEWONLY);
|
||||||
break;
|
break;
|
||||||
case R.id.fabKey:
|
case R.id.fabKey:
|
||||||
animateFAB();
|
animateFAB();
|
||||||
activityCallback.onAddWallet(isTestnet(), GenerateFragment.TYPE_KEY);
|
activityCallback.onAddWallet(GenerateFragment.TYPE_KEY);
|
||||||
break;
|
break;
|
||||||
case R.id.fabSeed:
|
case R.id.fabSeed:
|
||||||
animateFAB();
|
animateFAB();
|
||||||
activityCallback.onAddWallet(isTestnet(), GenerateFragment.TYPE_SEED);
|
activityCallback.onAddWallet(GenerateFragment.TYPE_SEED);
|
||||||
break;
|
break;
|
||||||
case R.id.fabScreen:
|
case R.id.fabScreen:
|
||||||
animateFAB();
|
animateFAB();
|
||||||
|
|
|
@ -300,7 +300,7 @@ public class ReceiveFragment extends Fragment {
|
||||||
String paymentId = etPaymentId.getEditText().getText().toString();
|
String paymentId = etPaymentId.getEditText().getText().toString();
|
||||||
String xmrAmount = evAmount.getAmount();
|
String xmrAmount = evAmount.getAmount();
|
||||||
Timber.d("%s/%s/%s", xmrAmount, paymentId, address);
|
Timber.d("%s/%s/%s", xmrAmount, paymentId, address);
|
||||||
if ((xmrAmount == null) || !Wallet.isAddressValid(address, WalletManager.getInstance().isTestNet())) {
|
if ((xmrAmount == null) || !Wallet.isAddressValid(address)) {
|
||||||
clearQR();
|
clearQR();
|
||||||
Timber.d("CLEARQR");
|
Timber.d("CLEARQR");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -36,7 +36,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
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.dialog.DonationFragment;
|
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;
|
||||||
|
@ -159,8 +159,8 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||||
case R.id.action_info:
|
case R.id.action_info:
|
||||||
onWalletDetails();
|
onWalletDetails();
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_donate:
|
case R.id.action_credits:
|
||||||
DonationFragment.display(getSupportFragmentManager());
|
CreditsFragment.display(getSupportFragmentManager());
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_share:
|
case R.id.action_share:
|
||||||
onShareTxInfo();
|
onShareTxInfo();
|
||||||
|
@ -213,8 +213,8 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||||
case Toolbar.BUTTON_CLOSE:
|
case Toolbar.BUTTON_CLOSE:
|
||||||
finish();
|
finish();
|
||||||
break;
|
break;
|
||||||
case Toolbar.BUTTON_DONATE:
|
case Toolbar.BUTTON_CREDITS:
|
||||||
Toast.makeText(WalletActivity.this, getString(R.string.label_donate), Toast.LENGTH_SHORT).show();
|
Toast.makeText(WalletActivity.this, getString(R.string.label_credits), Toast.LENGTH_SHORT).show();
|
||||||
case Toolbar.BUTTON_NONE:
|
case Toolbar.BUTTON_NONE:
|
||||||
default:
|
default:
|
||||||
Timber.e("Button " + type + "pressed - how can this be?");
|
Timber.e("Button " + type + "pressed - how can this be?");
|
||||||
|
@ -222,13 +222,6 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
|
||||||
if (testnet) {
|
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
|
||||||
} else {
|
|
||||||
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
|
||||||
}
|
|
||||||
|
|
||||||
Fragment walletFragment = new WalletFragment();
|
Fragment walletFragment = new WalletFragment();
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.add(R.id.fragment_container, walletFragment, WalletFragment.class.getName()).commit();
|
.add(R.id.fragment_container, walletFragment, WalletFragment.class.getName()).commit();
|
||||||
|
@ -238,6 +231,23 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||||
Timber.d("onCreate() done.");
|
Timber.d("onCreate() done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showNet() {
|
||||||
|
switch (WalletManager.getInstance().getNetworkType()) {
|
||||||
|
case NetworkType_Mainnet:
|
||||||
|
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
||||||
|
break;
|
||||||
|
case NetworkType_Testnet:
|
||||||
|
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
||||||
|
break;
|
||||||
|
case NetworkType_Stagenet:
|
||||||
|
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Wallet getWallet() {
|
public Wallet getWallet() {
|
||||||
if (mBoundService == null) throw new IllegalStateException("WalletService not bound.");
|
if (mBoundService == null) throw new IllegalStateException("WalletService not bound.");
|
||||||
return mBoundService.getWallet();
|
return mBoundService.getWallet();
|
||||||
|
@ -798,7 +808,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifyWalletPassword(String password) {
|
public boolean verifyWalletPassword(String password) {
|
||||||
String walletPath = new File(Helper.getStorageRoot(this),
|
String walletPath = new File(Helper.getWalletRoot(this),
|
||||||
getWalletName() + ".keys").getAbsolutePath();
|
getWalletName() + ".keys").getAbsolutePath();
|
||||||
return WalletManager.getInstance().verifyWalletPassword(walletPath, password, true);
|
return WalletManager.getInstance().verifyWalletPassword(walletPath, password, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class XmrWalletApplication extends Application {
|
public class XmrWalletApplication extends Application {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
||||||
|
@ -178,7 +179,7 @@ public class BarcodeData {
|
||||||
return null; // we have an amount but its not a number!
|
return null; // we have an amount but its not a number!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet())) {
|
if (!BitcoinAddressValidator.validate(address)) {
|
||||||
Timber.d("address invalid");
|
Timber.d("address invalid");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +191,7 @@ public class BarcodeData {
|
||||||
|
|
||||||
if (address == null) return null;
|
if (address == null) return null;
|
||||||
|
|
||||||
if (!BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet())) {
|
if (!BitcoinAddressValidator.validate(address)) {
|
||||||
Timber.d("address invalid");
|
Timber.d("address invalid");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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 com.m2049r.xmrwallet.model.NetworkType;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
public class WalletNode {
|
||||||
|
private final String name;
|
||||||
|
private final String host;
|
||||||
|
private final int port;
|
||||||
|
private final String user;
|
||||||
|
private final String password;
|
||||||
|
private final NetworkType networkType;
|
||||||
|
|
||||||
|
public WalletNode(String walletName, String daemon, NetworkType networkType) {
|
||||||
|
if ((daemon == null) || daemon.isEmpty())
|
||||||
|
throw new IllegalArgumentException("daemon is empty");
|
||||||
|
this.name = walletName;
|
||||||
|
String daemonAddress;
|
||||||
|
String a[] = daemon.split("@");
|
||||||
|
if (a.length == 1) { // no credentials
|
||||||
|
daemonAddress = a[0];
|
||||||
|
user = "";
|
||||||
|
password = "";
|
||||||
|
} else if (a.length == 2) { // credentials
|
||||||
|
String userPassword[] = a[0].split(":");
|
||||||
|
if (userPassword.length != 2)
|
||||||
|
throw new IllegalArgumentException("User:Password invalid");
|
||||||
|
user = userPassword[0];
|
||||||
|
if (!user.isEmpty()) {
|
||||||
|
password = userPassword[1];
|
||||||
|
} else {
|
||||||
|
password = "";
|
||||||
|
}
|
||||||
|
daemonAddress = a[1];
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Too many @");
|
||||||
|
}
|
||||||
|
|
||||||
|
String da[] = daemonAddress.split(":");
|
||||||
|
if ((da.length > 2) || (da.length < 1))
|
||||||
|
throw new IllegalArgumentException("Too many ':' or too few");
|
||||||
|
host = da[0];
|
||||||
|
if (da.length == 2) {
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(da[1]);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new IllegalArgumentException("Port not numeric");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (networkType) {
|
||||||
|
case NetworkType_Mainnet:
|
||||||
|
port = 18081;
|
||||||
|
break;
|
||||||
|
case NetworkType_Testnet:
|
||||||
|
port = 28081;
|
||||||
|
break;
|
||||||
|
case NetworkType_Stagenet:
|
||||||
|
port = 38081;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
port = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.networkType = networkType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return host + ":" + port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketAddress getSocketAddress() {
|
||||||
|
return new InetSocketAddress(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return !host.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,16 +28,14 @@ import android.text.Html;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
|
||||||
|
|
||||||
public class DonationFragment extends DialogFragment {
|
public class CreditsFragment extends DialogFragment {
|
||||||
static final String TAG = "DonationFragment";
|
static final String TAG = "DonationFragment";
|
||||||
|
|
||||||
public static DonationFragment newInstance() {
|
public static CreditsFragment newInstance() {
|
||||||
return new DonationFragment();
|
return new CreditsFragment();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void display(FragmentManager fm) {
|
public static void display(FragmentManager fm) {
|
||||||
|
@ -47,24 +45,14 @@ public class DonationFragment extends DialogFragment {
|
||||||
ft.remove(prev);
|
ft.remove(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
DonationFragment.newInstance().show(ft, TAG);
|
CreditsFragment.newInstance().show(ft, TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_donation, null);
|
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_credits, null);
|
||||||
|
|
||||||
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.donation_credits)));
|
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.credits_text)));
|
||||||
|
|
||||||
(view.findViewById(R.id.bCopyAddress)).
|
|
||||||
setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_address),
|
|
||||||
((TextView) view.findViewById(R.id.tvWalletAddress)).getText().toString());
|
|
||||||
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setView(view);
|
builder.setView(view);
|
|
@ -212,7 +212,7 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||||
private boolean checkAddressNoError() {
|
private boolean checkAddressNoError() {
|
||||||
String address = etAddress.getEditText().getText().toString();
|
String address = etAddress.getEditText().getText().toString();
|
||||||
return Wallet.isAddressValid(address)
|
return Wallet.isAddressValid(address)
|
||||||
|| BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet());
|
|| BitcoinAddressValidator.validate(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkAddress() {
|
private boolean checkAddress() {
|
||||||
|
@ -228,13 +228,13 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||||
private boolean isIntegratedAddress() {
|
private boolean isIntegratedAddress() {
|
||||||
String address = etAddress.getEditText().getText().toString();
|
String address = etAddress.getEditText().getText().toString();
|
||||||
return (address.length() == INTEGRATED_ADDRESS_LENGTH)
|
return (address.length() == INTEGRATED_ADDRESS_LENGTH)
|
||||||
&& Wallet.isAddressValid(address, WalletManager.getInstance().isTestNet());
|
&& Wallet.isAddressValid(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBitcoinAddress() {
|
private boolean isBitcoinAddress() {
|
||||||
String address = etAddress.getEditText().getText().toString();
|
String address = etAddress.getEditText().getText().toString();
|
||||||
if ((address.length() >= 27) && (address.length() <= 34))
|
if ((address.length() >= 27) && (address.length() <= 34))
|
||||||
return BitcoinAddressValidator.validate(address, WalletManager.getInstance().isTestNet());
|
return BitcoinAddressValidator.validate(address);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,8 @@ public class SendSettingsWizardFragment extends SendWizardFragment {
|
||||||
TxData getTxData();
|
TxData getTxData();
|
||||||
}
|
}
|
||||||
|
|
||||||
final static int Mixins[] = {4, 7, 12, 25}; // must match the layout XML
|
// Mixin = Ringsize - 1
|
||||||
|
final static int Mixins[] = {6, 9, 12, 25}; // must match the layout XML / "@array/mixin"
|
||||||
final static PendingTransaction.Priority Priorities[] =
|
final static PendingTransaction.Priority Priorities[] =
|
||||||
{PendingTransaction.Priority.Priority_Default,
|
{PendingTransaction.Priority.Priority_Default,
|
||||||
PendingTransaction.Priority.Priority_Low,
|
PendingTransaction.Priority.Priority_Low,
|
||||||
|
|
|
@ -137,12 +137,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||||
ivTxType.setVisibility(View.GONE); // gives us more space for the amount
|
ivTxType.setVisibility(View.GONE); // gives us more space for the amount
|
||||||
}
|
}
|
||||||
|
|
||||||
long realAmount = infoItem.amount;
|
String displayAmount = Helper.getDisplayAmount(infoItem.amount, Helper.DISPLAY_DIGITS_INFO);
|
||||||
if (infoItem.isPending) {
|
|
||||||
realAmount = realAmount - infoItem.fee;
|
|
||||||
}
|
|
||||||
|
|
||||||
String displayAmount = Helper.getDisplayAmount(realAmount, Helper.DISPLAY_DIGITS_INFO);
|
|
||||||
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {
|
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {
|
||||||
tvAmount.setText(context.getString(R.string.tx_list_amount_negative, displayAmount));
|
tvAmount.setText(context.getString(R.string.tx_list_amount_negative, displayAmount));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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.model;
|
||||||
|
|
||||||
|
public enum NetworkType {
|
||||||
|
NetworkType_Mainnet(0),
|
||||||
|
NetworkType_Testnet(1),
|
||||||
|
NetworkType_Stagenet(2);
|
||||||
|
|
||||||
|
public static NetworkType fromInteger(int n) {
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
return NetworkType_Mainnet;
|
||||||
|
case 1:
|
||||||
|
return NetworkType_Testnet;
|
||||||
|
case 2:
|
||||||
|
return NetworkType_Stagenet;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
NetworkType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -84,7 +84,14 @@ public class PendingTransaction {
|
||||||
|
|
||||||
public native long getFee();
|
public native long getFee();
|
||||||
|
|
||||||
public native String getFirstTxId();
|
public String getFirstTxId() {
|
||||||
|
String id = getFirstTxIdJ();
|
||||||
|
if (id == null)
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public native String getFirstTxIdJ();
|
||||||
|
|
||||||
public native long getTxCount();
|
public native long getTxCount();
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,11 @@ public class Wallet {
|
||||||
|
|
||||||
public native String getPath();
|
public native String getPath();
|
||||||
|
|
||||||
public native boolean isTestNet();
|
public NetworkType getNetworkType() {
|
||||||
|
return NetworkType.fromInteger(nettype());
|
||||||
|
}
|
||||||
|
|
||||||
|
public native int nettype();
|
||||||
|
|
||||||
//TODO virtual void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const = 0;
|
//TODO virtual void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const = 0;
|
||||||
//TODO virtual bool useForkRules(uint8_t version, int64_t early_blocks) const = 0;
|
//TODO virtual bool useForkRules(uint8_t version, int64_t early_blocks) const = 0;
|
||||||
|
@ -155,10 +159,10 @@ public class Wallet {
|
||||||
public static native boolean isPaymentIdValid(String payment_id);
|
public static native boolean isPaymentIdValid(String payment_id);
|
||||||
|
|
||||||
public static boolean isAddressValid(String address) {
|
public static boolean isAddressValid(String address) {
|
||||||
return isAddressValid(address, WalletManager.getInstance().isTestNet());
|
return isAddressValid(address, WalletManager.getInstance().getNetworkType().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static native boolean isAddressValid(String address, boolean isTestNet);
|
public static native boolean isAddressValid(String address, int networkType);
|
||||||
|
|
||||||
//TODO static static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error);
|
//TODO static static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package com.m2049r.xmrwallet.model;
|
package com.m2049r.xmrwallet.model;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.data.WalletNode;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
@ -69,22 +71,22 @@ public class WalletManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Wallet createWallet(File aFile, String password, String language) {
|
public Wallet createWallet(File aFile, String password, String language) {
|
||||||
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, isTestNet());
|
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, getNetworkType().getValue());
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long createWalletJ(String path, String password, String language, boolean isTestNet);
|
private native long createWalletJ(String path, String password, String language, int networkType);
|
||||||
|
|
||||||
public Wallet openWallet(String path, String password) {
|
public Wallet openWallet(String path, String password) {
|
||||||
long walletHandle = openWalletJ(path, password, isTestNet());
|
long walletHandle = openWalletJ(path, password, getNetworkType().getValue());
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long openWalletJ(String path, String password, boolean isTestNet);
|
private native long openWalletJ(String path, String password, int networkType);
|
||||||
|
|
||||||
public Wallet recoveryWallet(File aFile, String password, String mnemonic) {
|
public Wallet recoveryWallet(File aFile, String password, String mnemonic) {
|
||||||
return recoveryWallet(aFile, password, mnemonic, 0);
|
return recoveryWallet(aFile, password, mnemonic, 0);
|
||||||
|
@ -92,28 +94,28 @@ public class WalletManager {
|
||||||
|
|
||||||
public Wallet recoveryWallet(File aFile, String password, String mnemonic, long restoreHeight) {
|
public Wallet recoveryWallet(File aFile, String password, String mnemonic, long restoreHeight) {
|
||||||
long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), password, mnemonic,
|
long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), password, mnemonic,
|
||||||
isTestNet(), restoreHeight);
|
getNetworkType().getValue(), restoreHeight);
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long recoveryWalletJ(String path, String password, String mnemonic,
|
private native long recoveryWalletJ(String path, String password, String mnemonic,
|
||||||
boolean isTestNet, long restoreHeight);
|
int networkType, long restoreHeight);
|
||||||
|
|
||||||
public Wallet createWalletWithKeys(File aFile, String password, String language, long restoreHeight,
|
public Wallet createWalletWithKeys(File aFile, String password, String language, long restoreHeight,
|
||||||
String addressString, String viewKeyString, String spendKeyString) {
|
String addressString, String viewKeyString, String spendKeyString) {
|
||||||
long walletHandle = createWalletWithKeysJ(aFile.getAbsolutePath(), password,
|
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), password,
|
||||||
language, isTestNet(), restoreHeight,
|
language, getNetworkType().getValue(), restoreHeight,
|
||||||
addressString, viewKeyString, spendKeyString);
|
addressString, viewKeyString, spendKeyString);
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long createWalletWithKeysJ(String path, String password,
|
private native long createWalletFromKeysJ(String path, String password,
|
||||||
String language,
|
String language,
|
||||||
boolean isTestNet,
|
int networkType,
|
||||||
long restoreHeight,
|
long restoreHeight,
|
||||||
String addressString,
|
String addressString,
|
||||||
String viewKeyString,
|
String viewKeyString,
|
||||||
|
@ -204,24 +206,23 @@ public class WalletManager {
|
||||||
//TODO virtual bool checkPayment(const std::string &address, const std::string &txid, const std::string &txkey, const std::string &daemon_address, uint64_t &received, uint64_t &height, std::string &error) const = 0;
|
//TODO virtual bool checkPayment(const std::string &address, const std::string &txid, const std::string &txkey, const std::string &daemon_address, uint64_t &received, uint64_t &height, std::string &error) const = 0;
|
||||||
|
|
||||||
private String daemonAddress = null;
|
private String daemonAddress = null;
|
||||||
private boolean testnet = true;
|
private NetworkType networkType = null;
|
||||||
|
|
||||||
public boolean isTestNet() {
|
public NetworkType getNetworkType() {
|
||||||
if (daemonAddress == null) {
|
return networkType;
|
||||||
return true;
|
|
||||||
// assume testnet not explicitly initialised
|
|
||||||
//throw new IllegalStateException("use setDaemon() to initialise daemon and net first!");
|
|
||||||
}
|
|
||||||
return testnet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDaemon(String address, boolean testnet, String username, String password) {
|
//public void setDaemon(String address, NetworkType networkType, String username, String password) {
|
||||||
//Timber.d("SETDAEMON " + username + "/" + password + "/" + address);
|
public void setDaemon(WalletNode walletNode) {
|
||||||
this.daemonAddress = address;
|
this.daemonAddress = walletNode.getAddress();
|
||||||
this.testnet = testnet;
|
this.networkType = networkType;
|
||||||
this.daemonUsername = username;
|
this.daemonUsername = walletNode.getUsername();
|
||||||
this.daemonPassword = password;
|
this.daemonPassword = walletNode.getPassword();
|
||||||
setDaemonAddressJ(address);
|
setDaemonAddressJ(daemonAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNetworkType(NetworkType networkType) {
|
||||||
|
this.networkType = networkType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDaemonAddress() {
|
public String getDaemonAddress() {
|
||||||
|
|
|
@ -524,7 +524,7 @@ public class WalletService extends Service {
|
||||||
showProgress(20);
|
showProgress(20);
|
||||||
Wallet wallet = null;
|
Wallet wallet = null;
|
||||||
WalletManager walletMgr = WalletManager.getInstance();
|
WalletManager walletMgr = WalletManager.getInstance();
|
||||||
Timber.d("WalletManager testnet=%s", walletMgr.isTestNet());
|
Timber.d("WalletManager network=%s", walletMgr.getNetworkType().name());
|
||||||
showProgress(30);
|
showProgress(30);
|
||||||
if (walletMgr.walletExists(path)) {
|
if (walletMgr.walletExists(path)) {
|
||||||
Timber.d("open wallet %s", path);
|
Timber.d("open wallet %s", path);
|
||||||
|
|
|
@ -18,6 +18,9 @@ package com.m2049r.xmrwallet.util;
|
||||||
|
|
||||||
// based on https://rosettacode.org/wiki/Bitcoin/address_validation#Java
|
// based on https://rosettacode.org/wiki/Bitcoin/address_validation#Java
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -27,6 +30,11 @@ public class BitcoinAddressValidator {
|
||||||
|
|
||||||
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
public static boolean validate(String addrress) {
|
||||||
|
return validate(addrress,
|
||||||
|
WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean validate(String addrress, boolean testnet) {
|
public static boolean validate(String addrress, boolean testnet) {
|
||||||
if (addrress.length() < 26 || addrress.length() > 35)
|
if (addrress.length() < 26 || addrress.length() > 35)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -31,12 +31,15 @@ import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.VectorDrawable;
|
import android.graphics.drawable.VectorDrawable;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.system.ErrnoException;
|
||||||
|
import android.system.Os;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
|
||||||
|
@ -55,16 +58,21 @@ import timber.log.Timber;
|
||||||
|
|
||||||
public class Helper {
|
public class Helper {
|
||||||
static private final String WALLET_DIR = "monerujo";
|
static private final String WALLET_DIR = "monerujo";
|
||||||
|
static private final String HOME_DIR = "monero";
|
||||||
|
|
||||||
static public int DISPLAY_DIGITS_INFO = 5;
|
static public int DISPLAY_DIGITS_INFO = 5;
|
||||||
|
|
||||||
static public File getStorageRoot(Context context) {
|
static public File getWalletRoot(Context context) {
|
||||||
|
return getStorage(context, WALLET_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public File getStorage(Context context, String folderName) {
|
||||||
if (!isExternalStorageWritable()) {
|
if (!isExternalStorageWritable()) {
|
||||||
String msg = context.getString(R.string.message_strorage_not_writable);
|
String msg = context.getString(R.string.message_strorage_not_writable);
|
||||||
Timber.e(msg);
|
Timber.e(msg);
|
||||||
throw new IllegalStateException(msg);
|
throw new IllegalStateException(msg);
|
||||||
}
|
}
|
||||||
File dir = new File(Environment.getExternalStorageDirectory(), WALLET_DIR);
|
File dir = new File(Environment.getExternalStorageDirectory(), folderName);
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
Timber.i("Creating %s", dir.getAbsolutePath());
|
Timber.i("Creating %s", dir.getAbsolutePath());
|
||||||
dir.mkdirs(); // try to make it
|
dir.mkdirs(); // try to make it
|
||||||
|
@ -114,9 +122,9 @@ public class Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
static public File getWalletFile(Context context, String aWalletName) {
|
static public File getWalletFile(Context context, String aWalletName) {
|
||||||
File walletDir = getStorageRoot(context);
|
File walletDir = getWalletRoot(context);
|
||||||
File f = new File(walletDir, aWalletName);
|
File f = new File(walletDir, aWalletName);
|
||||||
Timber.d("wallet= %s size= %d", f.getAbsolutePath(), f.length());
|
Timber.d("wallet=%s size= %d", f.getAbsolutePath(), f.length());
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,10 +271,20 @@ public class Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
static public HttpUrl getXmrToBaseUrl() {
|
static public HttpUrl getXmrToBaseUrl() {
|
||||||
if ((WalletManager.getInstance() == null) || WalletManager.getInstance().isTestNet()) {
|
if ((WalletManager.getInstance() == null)
|
||||||
|
|| (WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet)) {
|
||||||
return HttpUrl.parse("https://test.xmr.to/api/v2/xmr2btc/");
|
return HttpUrl.parse("https://test.xmr.to/api/v2/xmr2btc/");
|
||||||
} else {
|
} else {
|
||||||
return HttpUrl.parse("https://xmr.to/api/v2/xmr2btc/");
|
return HttpUrl.parse("https://xmr.to/api/v2/xmr2btc/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public void setMoneroHome(Context context) {
|
||||||
|
try {
|
||||||
|
String home = getStorage(context, HOME_DIR).getAbsolutePath();
|
||||||
|
Os.setenv("HOME", home, true);
|
||||||
|
} catch (ErrnoException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class Toolbar extends android.support.v7.widget.Toolbar {
|
||||||
ImageView toolbarImage;
|
ImageView toolbarImage;
|
||||||
TextView toolbarTitle;
|
TextView toolbarTitle;
|
||||||
TextView toolbarSubtitle;
|
TextView toolbarSubtitle;
|
||||||
Button bDonate;
|
Button bCredits;
|
||||||
|
|
||||||
public Toolbar(Context context) {
|
public Toolbar(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -87,8 +87,8 @@ public class Toolbar extends android.support.v7.widget.Toolbar {
|
||||||
|
|
||||||
toolbarTitle = (TextView) findViewById(R.id.toolbarTitle);
|
toolbarTitle = (TextView) findViewById(R.id.toolbarTitle);
|
||||||
toolbarSubtitle = (TextView) findViewById(R.id.toolbarSubtitle);
|
toolbarSubtitle = (TextView) findViewById(R.id.toolbarSubtitle);
|
||||||
bDonate = (Button) findViewById(R.id.bDonate);
|
bCredits = (Button) findViewById(R.id.bCredits);
|
||||||
bDonate.setOnClickListener(new View.OnClickListener() {
|
bCredits.setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (onButtonListener != null) {
|
if (onButtonListener != null) {
|
||||||
onButtonListener.onButton(buttonType);
|
onButtonListener.onButton(buttonType);
|
||||||
|
@ -116,43 +116,43 @@ public class Toolbar extends android.support.v7.widget.Toolbar {
|
||||||
public final static int BUTTON_NONE = 0;
|
public final static int BUTTON_NONE = 0;
|
||||||
public final static int BUTTON_BACK = 1;
|
public final static int BUTTON_BACK = 1;
|
||||||
public final static int BUTTON_CLOSE = 2;
|
public final static int BUTTON_CLOSE = 2;
|
||||||
public final static int BUTTON_DONATE = 3;
|
public final static int BUTTON_CREDITS = 3;
|
||||||
public final static int BUTTON_CANCEL = 4;
|
public final static int BUTTON_CANCEL = 4;
|
||||||
|
|
||||||
int buttonType = BUTTON_DONATE;
|
int buttonType = BUTTON_CREDITS;
|
||||||
|
|
||||||
public void setButton(int type) {
|
public void setButton(int type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BUTTON_BACK:
|
case BUTTON_BACK:
|
||||||
Timber.d("BUTTON_BACK");
|
Timber.d("BUTTON_BACK");
|
||||||
bDonate.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_arrow_back_white_24dp, 0, 0, 0);
|
bCredits.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_arrow_back_white_24dp, 0, 0, 0);
|
||||||
bDonate.setText(null);
|
bCredits.setText(null);
|
||||||
bDonate.setVisibility(View.VISIBLE);
|
bCredits.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
case BUTTON_CLOSE:
|
case BUTTON_CLOSE:
|
||||||
Timber.d("BUTTON_CLOSE");
|
Timber.d("BUTTON_CLOSE");
|
||||||
bDonate.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_close_white_24dp, 0, 0, 0);
|
bCredits.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_close_white_24dp, 0, 0, 0);
|
||||||
bDonate.setText(R.string.label_close);
|
bCredits.setText(R.string.label_close);
|
||||||
bDonate.setVisibility(View.VISIBLE);
|
bCredits.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
case BUTTON_DONATE:
|
case BUTTON_CREDITS:
|
||||||
Timber.d("BUTTON_DONATE");
|
Timber.d("BUTTON_CREDITS");
|
||||||
bDonate.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_favorite_white_24dp, 0, 0, 0);
|
bCredits.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_favorite_white_24dp, 0, 0, 0);
|
||||||
bDonate.setText(R.string.label_donate);
|
bCredits.setText(R.string.label_credits);
|
||||||
bDonate.setVisibility(View.VISIBLE);
|
bCredits.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
case BUTTON_CANCEL:
|
case BUTTON_CANCEL:
|
||||||
Timber.d("BUTTON_CANCEL");
|
Timber.d("BUTTON_CANCEL");
|
||||||
bDonate.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_close_white_24dp, 0, 0, 0);
|
bCredits.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_close_white_24dp, 0, 0, 0);
|
||||||
bDonate.setText(R.string.label_cancel);
|
bCredits.setText(R.string.label_cancel);
|
||||||
bDonate.setVisibility(View.VISIBLE);
|
bCredits.setVisibility(View.VISIBLE);
|
||||||
break;
|
break;
|
||||||
case BUTTON_NONE:
|
case BUTTON_NONE:
|
||||||
default:
|
default:
|
||||||
Timber.d("BUTTON_NONE");
|
Timber.d("BUTTON_NONE");
|
||||||
bDonate.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
bCredits.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||||
bDonate.setText(null);
|
bCredits.setText(null);
|
||||||
bDonate.setVisibility(View.INVISIBLE);
|
bCredits.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
buttonType = type;
|
buttonType = type;
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingStart="16dp">
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:src="@drawable/gunther_coder" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvCredits"
|
||||||
|
style="@style/MoneroText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/header_top"
|
||||||
|
android:autoLink="web"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/credits_text" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
|
@ -1,79 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingStart="16dp">
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="100dp"
|
|
||||||
android:src="@drawable/gunther_donate" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/MoneroText"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/donation_text"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/header_top"
|
|
||||||
android:background="@drawable/backgound_spinner"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="@dimen/header_top">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/MoneroLabel.Heading.Donation"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:text="@string/donation_address_label" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/bCopyAddress"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:background="?android:selectableItemBackground"
|
|
||||||
android:src="@drawable/ic_content_copy_black_24dp" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvWalletAddress"
|
|
||||||
style="@style/MoneroText"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/data_top"
|
|
||||||
android:text="@string/donation_address"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textColor="@color/moneroBlack"
|
|
||||||
android:textSize="17sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvCredits"
|
|
||||||
style="@style/MoneroText"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/header_top"
|
|
||||||
android:autoLink="web"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/donation_credits" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
|
@ -3,12 +3,12 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/bDonate"
|
android:id="@+id/bCredits"
|
||||||
style="@style/ToolBarStyle.ActionButton"
|
style="@style/ToolBarStyle.ActionButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:drawableStart="@drawable/ic_favorite_white_24dp"
|
android:drawableStart="@drawable/ic_favorite_white_24dp"
|
||||||
android:text="@string/label_donate" />
|
android:text="@string/label_credits" />
|
||||||
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_donate"
|
android:id="@+id/action_credits"
|
||||||
android:icon="@drawable/ic_favorite_white_24dp"
|
android:icon="@drawable/ic_favorite_white_24dp"
|
||||||
android:orderInCategory="10"
|
android:orderInCategory="10"
|
||||||
android:title="@string/label_donate"
|
android:title="@string/label_credits"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
|
|
|
@ -4,13 +4,7 @@
|
||||||
<string name="about_close">Cerrar</string>
|
<string name="about_close">Cerrar</string>
|
||||||
<string name="about_version">Versión %1$s (%2$d)</string>
|
<string name="about_version">Versión %1$s (%2$d)</string>
|
||||||
|
|
||||||
<string name="donation_text">
|
<string name="credits_text"><![CDATA[
|
||||||
\"¡Donad, bastardos ingratos!\"
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="donation_address_label">Donaciones</string>
|
|
||||||
|
|
||||||
<string name="donation_credits"><![CDATA[
|
|
||||||
<b>Créditos</b>
|
<b>Créditos</b>
|
||||||
<br/>
|
<br/>
|
||||||
m2049r, baltsar777, anhdres, keejef,
|
m2049r, baltsar777, anhdres, keejef,
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<string name="password_very_strong">¡Bien ahí, hacker nivel 4!</string>
|
<string name="password_very_strong">¡Bien ahí, hacker nivel 4!</string>
|
||||||
|
|
||||||
<string name="label_login_wallets">Monederos</string>
|
<string name="label_login_wallets">Monederos</string>
|
||||||
<string name="label_donate">Donar</string>
|
<string name="label_credits">Créditos</string>
|
||||||
<string name="label_ok">Aceptar</string>
|
<string name="label_ok">Aceptar</string>
|
||||||
<string name="label_cancel">Cancelar</string>
|
<string name="label_cancel">Cancelar</string>
|
||||||
<string name="label_close">Cerrar</string>
|
<string name="label_close">Cerrar</string>
|
||||||
|
@ -59,6 +59,7 @@
|
||||||
<string name="label_daemon">Nodo</string>
|
<string name="label_daemon">Nodo</string>
|
||||||
<string name="prompt_daemon">([<usuario>:<contraseña>@]<daemon>[:<puerto>])</string>
|
<string name="prompt_daemon">([<usuario>:<contraseña>@]<daemon>[:<puerto>])</string>
|
||||||
<string name="prompt_mainnet">Selección de Red</string>
|
<string name="prompt_mainnet">Selección de Red</string>
|
||||||
|
<string name="connect_stagenet">StageNet</string>
|
||||||
<string name="connect_testnet">TestNet</string>
|
<string name="connect_testnet">TestNet</string>
|
||||||
<string name="connect_mainnet">MainNet</string>
|
<string name="connect_mainnet">MainNet</string>
|
||||||
<string name="status_walletlist_loading">Cargando lista de monederos</string>
|
<string name="status_walletlist_loading">Cargando lista de monederos</string>
|
||||||
|
|
|
@ -5,14 +5,7 @@
|
||||||
<string name="about_whoami">I am monerujo</string>
|
<string name="about_whoami">I am monerujo</string>
|
||||||
<string name="about_version">Version %1$s (%2$d)</string>
|
<string name="about_version">Version %1$s (%2$d)</string>
|
||||||
|
|
||||||
<string name="donation_text">
|
<string name="credits_text"><![CDATA[
|
||||||
\"Donate you ungrateful bastards!\"
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<string name="donation_address_label">Donations Address</string>
|
|
||||||
<string name="donation_address" translatable="false">4AdkPJoxn7JCvAby9szgnt93MSEwdnxdhaASxbTBm6x5dCwmsDep2UYN4FhStDn5i11nsJbpU7oj59ahg8gXb1Mg3viqCuk</string>
|
|
||||||
|
|
||||||
<string name="donation_credits"><![CDATA[
|
|
||||||
<b>Credits</b>
|
<b>Credits</b>
|
||||||
<br/>
|
<br/>
|
||||||
m2049r, baltsar777, anhdres, keejef,
|
m2049r, baltsar777, anhdres, keejef,
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<string name="password_very_strong">Yeah baby, h4x0r style!</string>
|
<string name="password_very_strong">Yeah baby, h4x0r style!</string>
|
||||||
|
|
||||||
<string name="label_login_wallets">Wallets</string>
|
<string name="label_login_wallets">Wallets</string>
|
||||||
<string name="label_donate">Donate</string>
|
<string name="label_credits">Credits</string>
|
||||||
<string name="label_ok">OK</string>
|
<string name="label_ok">OK</string>
|
||||||
<string name="label_cancel">Cancel</string>
|
<string name="label_cancel">Cancel</string>
|
||||||
<string name="label_close">Close</string>
|
<string name="label_close">Close</string>
|
||||||
|
@ -124,6 +124,7 @@
|
||||||
<string name="label_daemon">Node</string>
|
<string name="label_daemon">Node</string>
|
||||||
<string name="prompt_daemon">([<user>:<pass>@]<daemon>[:<port>])</string>
|
<string name="prompt_daemon">([<user>:<pass>@]<daemon>[:<port>])</string>
|
||||||
<string name="prompt_mainnet">Net Selection</string>
|
<string name="prompt_mainnet">Net Selection</string>
|
||||||
|
<string name="connect_stagenet">StageNet</string>
|
||||||
<string name="connect_testnet">TestNet</string>
|
<string name="connect_testnet">TestNet</string>
|
||||||
<string name="connect_mainnet">MainNet</string>
|
<string name="connect_mainnet">MainNet</string>
|
||||||
<string name="status_walletlist_loading">Loading Wallet List</string>
|
<string name="status_walletlist_loading">Loading Wallet List</string>
|
||||||
|
@ -348,8 +349,8 @@
|
||||||
<string name="archive_alert_no">No thanks!</string>
|
<string name="archive_alert_no">No thanks!</string>
|
||||||
|
|
||||||
<string-array name="mixin" translatable="false">
|
<string-array name="mixin" translatable="false">
|
||||||
<item>Ringsize 5</item>
|
<item>Ringsize 7</item>
|
||||||
<item>Ringsize 8</item>
|
<item>Ringsize 10</item>
|
||||||
<item>Ringsize 13</item>
|
<item>Ringsize 13</item>
|
||||||
<item>Ringsize 26</item>
|
<item>Ringsize 26</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
|
@ -4,27 +4,35 @@ Based on https://forum.getmonero.org/5/support/87643/building-monero-v0-10-3-1-f
|
||||||
|
|
||||||
Do not follow this blindly.
|
Do not follow this blindly.
|
||||||
|
|
||||||
|
These instructions are tailored to building ```wallep_api```.
|
||||||
|
|
||||||
These instructions build all supported architectures: ```'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'```.
|
These instructions build all supported architectures: ```'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'```.
|
||||||
|
|
||||||
Yes, lots of copy&paste here. TODO: Script this.
|
Yes, lots of copy&paste here. TODO: Script this.
|
||||||
|
|
||||||
## Prepare Ubuntu environment
|
## Prepare Ubuntu environment
|
||||||
|
|
||||||
```
|
```Shell
|
||||||
sudo apt-get install build-essential cmake tofrodos libtool-bin
|
sudo apt-get install build-essential cmake tofrodos libtool-bin
|
||||||
sudo mkdir /opt/android
|
sudo mkdir /opt/android
|
||||||
sudo chown $LOGNAME /opt/android
|
sudo chown $LOGNAME /opt/android
|
||||||
```
|
```
|
||||||
|
|
||||||
## Install Android NDK
|
## Install Android NDK
|
||||||
```
|
```Shell
|
||||||
cd /opt/android
|
cd /opt/android
|
||||||
wget https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip
|
wget https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip
|
||||||
unzip android-ndk-r15c-linux-x86_64.zip
|
unzip android-ndk-r16b-linux-x86_64.zip
|
||||||
android-ndk-r15c/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch arm --install-dir /opt/android/tool32
|
ln -s android-ndk-r16b ndk
|
||||||
android-ndk-r15c/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch arm64 --install-dir /opt/android/tool64
|
ndk/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch arm --install-dir /opt/android/tool/arm
|
||||||
android-ndk-r15c/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch x86 --install-dir /opt/android/toolx86
|
ndk/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch arm64 --install-dir /opt/android/tool/arm64
|
||||||
android-ndk-r15c/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch x86_64 --install-dir /opt/android/toolx86_64
|
ndk/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch x86 --install-dir /opt/android/tool/x86
|
||||||
|
ndk/build/tools/make_standalone_toolchain.py --api 21 --stl=libc++ --arch x86_64 --install-dir /opt/android/tool/x86_64
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prepare output
|
||||||
|
```Shell
|
||||||
|
mkdir -p /opt/android/build
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build OpenSSL
|
## Build OpenSSL
|
||||||
|
@ -32,131 +40,81 @@ Best is to compile openssl from sources. Copying from your phone or elsewhere (d
|
||||||
|
|
||||||
If you don't want to build for all architectures, edit ```build-all-arch.sh``` before running it (Line 12).
|
If you don't want to build for all architectures, edit ```build-all-arch.sh``` before running it (Line 12).
|
||||||
|
|
||||||
```
|
```Shell
|
||||||
cd /opt/android
|
cd /opt/android
|
||||||
git clone https://github.com/m2049r/android-openssl.git
|
git clone https://github.com/m2049r/android-openssl.git
|
||||||
wget https://github.com/openssl/openssl/archive/OpenSSL_1_0_2l.tar.gz
|
wget https://github.com/openssl/openssl/archive/OpenSSL_1_0_2l.tar.gz
|
||||||
cd android-openssl
|
cd android-openssl
|
||||||
tar xfz ../OpenSSL_1_0_2l.tar.gz
|
tar xfz ../OpenSSL_1_0_2l.tar.gz
|
||||||
export ANDROID_NDK_ROOT=/opt/android/android-ndk-r15c
|
ANDROID_NDK_ROOT=/opt/android/ndk ./build-all-arch.sh
|
||||||
./build-all-arch.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Make symlinks
|
### Install & make symlinks
|
||||||
|
```Shell
|
||||||
|
mkdir -p /opt/android/build/openssl/{arm,arm64,x86,x86_64}
|
||||||
|
cp -a /opt/android/android-openssl/prebuilt/armeabi /opt/android/build/openssl/arm/lib
|
||||||
|
cp -a /opt/android/android-openssl/prebuilt/arm64-v8a /opt/android/build/openssl/arm64/lib
|
||||||
|
cp -a /opt/android/android-openssl/prebuilt/x86 /opt/android/build/openssl/x86/lib
|
||||||
|
cp -a /opt/android/android-openssl/prebuilt/x86_64 /opt/android/build/openssl/x86_64/lib
|
||||||
|
cp -aL /opt/android/android-openssl/openssl-OpenSSL_1_0_2l/include/openssl/ /opt/android/build/openssl/include
|
||||||
|
ln -s /opt/android/build/openssl/include /opt/android/build/openssl/arm/include
|
||||||
|
ln -s /opt/android/build/openssl/include /opt/android/build/openssl/arm64/include
|
||||||
|
ln -s /opt/android/build/openssl/include /opt/android/build/openssl/x86/include
|
||||||
|
ln -s /opt/android/build/openssl/include /opt/android/build/openssl/x86_64/include
|
||||||
```
|
```
|
||||||
cd /opt/android/tool32/sysroot/usr/include
|
```Shell
|
||||||
ln -s ../../../../android-openssl/openssl-OpenSSL_1_0_2l/include/openssl/
|
ln -sf /opt/android/build/openssl/include /opt/android/tool/arm/sysroot/usr/include/openssl
|
||||||
cd /opt/android/tool32/sysroot/usr/lib
|
ln -sf /opt/android/build/openssl/lib/armeabi-v7a/*.so /opt/android/tool/arm/sysroot/usr/lib
|
||||||
ln -s ../../../../android-openssl/prebuilt/armeabi/libssl.so
|
|
||||||
ln -s ../../../../android-openssl/prebuilt/armeabi/libcrypto.so
|
|
||||||
|
|
||||||
cd /opt/android/tool64/sysroot/usr/include
|
ln -sf /opt/android/build/openssl/include /opt/android/tool/arm64/sysroot/usr/include/openssl
|
||||||
ln -s ../../../../android-openssl/openssl-OpenSSL_1_0_2l/include/openssl/
|
ln -sf /opt/android/build/openssl/lib/arm64-v8a/*.so /opt/android/tool/arm64/sysroot/usr/lib
|
||||||
cd /opt/android/tool64/sysroot/usr/lib
|
|
||||||
ln -s ../../../../android-openssl/prebuilt/arm64-v8a/libssl.so
|
|
||||||
ln -s ../../../../android-openssl/prebuilt/arm64-v8a/libcrypto.so
|
|
||||||
|
|
||||||
cd /opt/android/toolx86/sysroot/usr/include
|
ln -sf /opt/android/build/openssl/include /opt/android/tool/x86/sysroot/usr/include/openssl
|
||||||
ln -s ../../../../android-openssl/openssl-OpenSSL_1_0_2l/include/openssl/
|
ln -sf /opt/android/build/openssl/lib/x86/*.so /opt/android/tool/x86/sysroot/usr/lib
|
||||||
cd /opt/android/toolx86/sysroot/usr/lib
|
|
||||||
ln -s ../../../../android-openssl/prebuilt/x86/libssl.so
|
|
||||||
ln -s ../../../../android-openssl/prebuilt/x86/libcrypto.so
|
|
||||||
|
|
||||||
cd /opt/android/toolx86_64/sysroot/usr/include
|
ln -sf /opt/android/build/openssl/include /opt/android/tool/x86_64/sysroot/usr/include/openssl
|
||||||
ln -s ../../../../android-openssl/openssl-OpenSSL_1_0_2l/include/openssl/
|
ln -sf /opt/android/build/openssl/lib/x86_64/*.so /opt/android/tool/x86_64/sysroot/usr/lib64
|
||||||
cd /opt/android/toolx86_64/sysroot/usr/lib
|
|
||||||
ln -s ../../../../android-openssl/prebuilt/x86_64/libssl.so
|
|
||||||
ln -s ../../../../android-openssl/prebuilt/x86_64/libcrypto.so
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build Boost
|
## Build Boost
|
||||||
```
|
```Shell
|
||||||
cd /opt/android
|
cd /opt/android
|
||||||
wget https://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz/download -O boost_1_58_0.tar.gz
|
wget https://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz/download -O boost_1_58_0.tar.gz
|
||||||
tar xfz boost_1_58_0.tar.gz
|
tar xfz boost_1_58_0.tar.gz
|
||||||
cd boost_1_58_0
|
cd boost_1_58_0
|
||||||
./bootstrap.sh
|
./bootstrap.sh
|
||||||
```
|
```
|
||||||
The NDK r15c above gives errors about fsetpos and fgetpos not found(!?!), so we "just" comment them out in the include file:
|
Comment out ```using ::fgetpos;``` & ```using ::fsetpos;``` in ```cstdio```.
|
||||||
* `vi /opt/android/tool32/include/c++/4.9.x/cstdio` (`//using ::fgetpos`, `//using ::fsetpos`)
|
|
||||||
* `vi /opt/android/tool64/include/c++/4.9.x/cstdio` (`//using ::fgetpos`, `//using ::fsetpos`)
|
|
||||||
* `vi /opt/android/toolx86/include/c++/4.9.x/cstdio` (`//using ::fgetpos`, `//using ::fsetpos`)
|
|
||||||
* `vi /opt/android/toolx86_64/include/c++/4.9.x/cstdio` (`//using ::fgetpos`, `//using ::fsetpos`)
|
|
||||||
|
|
||||||
Then:
|
Then build & install to ```/opt/android/build/boost``` with
|
||||||
```
|
```Shell
|
||||||
PATH=/opt/android/tool32/arm-linux-androideabi/bin:/opt/android/tool32/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android32 --stagedir=android32 toolset=clang threading=multi threadapi=pthread target-os=android stage
|
PATH=/opt/android/tool/arm/arm-linux-androideabi/bin:/opt/android/tool/arm/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android-arm --prefix=/opt/android/build/boost/arm --includedir=/opt/android/build/boost/include toolset=clang threading=multi threadapi=pthread target-os=android install
|
||||||
PATH=/opt/android/tool64/aarch64-linux-android/bin:/opt/android/tool64/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android64 --stagedir=android64 toolset=clang threading=multi threadapi=pthread target-os=android stage
|
ln -sf ../include /opt/android/build/boost/arm
|
||||||
PATH=/opt/android/toolx86/i686-linux-android/bin:/opt/android/toolx86/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=androidx86 --stagedir=androidx86 toolset=clang threading=multi threadapi=pthread target-os=android stage
|
PATH=/opt/android/tool/arm64/aarch64-linux-android/bin:/opt/android/tool/arm64/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android-arm64 --prefix=/opt/android/build/boost/arm64 --includedir=/opt/android/build/boost/include toolset=clang threading=multi threadapi=pthread target-os=android install
|
||||||
PATH=/opt/android/toolx86_64/x86_64-linux-android/bin:/opt/android/toolx86_64/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=androidx86_64 --stagedir=androidx86_64 toolset=clang threading=multi threadapi=pthread target-os=android stage
|
ln -sf ../include /opt/android/build/boost/arm64
|
||||||
|
PATH=/opt/android/tool/x86/i686-linux-android/bin:/opt/android/tool/x86/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android-x86 --prefix=/opt/android/build/boost/x86 --includedir=/opt/android/build/boost/include toolset=clang threading=multi threadapi=pthread target-os=android install
|
||||||
|
ln -sf ../include /opt/android/build/boost/x86
|
||||||
|
PATH=/opt/android/tool/x86_64/x86_64-linux-android/bin:/opt/android/tool/x86_64/bin:$PATH ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android-x86_64 --prefix=/opt/android/build/boost/x86_64 --includedir=/opt/android/build/boost/include toolset=clang threading=multi threadapi=pthread target-os=android install
|
||||||
|
ln -sf ../include /opt/android/build/boost/x86_64
|
||||||
```
|
```
|
||||||
|
|
||||||
## And finally: Build Monero
|
## And finally: Build Monero
|
||||||
```
|
```Shell
|
||||||
cd /opt/android
|
cd /opt/android
|
||||||
git clone https://github.com/m2049r/monero.git
|
git clone https://github.com/m2049r/monero.git
|
||||||
|
|
||||||
cd /opt/android/monero
|
cd /opt/android/monero/build
|
||||||
mkdir -p build/release.android32
|
./build-all-arch.sh
|
||||||
cd build/release.android32
|
|
||||||
PATH=/opt/android/tool32/arm-linux-androideabi/bin:/opt/android/tool32/bin:$PATH CC=clang CXX=clang++ cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D BUILD_TAG="android" -D BOOST_ROOT=/opt/android/boost_1_58_0 -D BOOST_LIBRARYDIR=/opt/android/boost_1_58_0/android32/lib -D OPENSSL_ROOT_DIR=/opt/android/android-openssl/openssl-OpenSSL_1_0_2l -D OPENSSL_CRYPTO_LIBRARY=/opt/android/android-openssl/prebuilt/armeabi/libcrypto.so -D OPENSSL_SSL_LIBRARY=/opt/android/android-openssl/prebuilt/armeabi/libssl.so -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=true ../..
|
|
||||||
make
|
|
||||||
find . -name '*.a' -exec cp '{}' lib \;
|
|
||||||
|
|
||||||
cd /opt/android/monero
|
|
||||||
mkdir -p build/release.android64
|
|
||||||
cd build/release.android64
|
|
||||||
PATH=/opt/android/tool64/aarch64-linux-android/bin:/opt/android/tool64/bin:$PATH CC=clang CXX=clang++ cmake -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D BUILD_TAG="android" -D BOOST_ROOT=/opt/android/boost_1_58_0 -D BOOST_LIBRARYDIR=/opt/android/boost_1_58_0/android64/lib -D OPENSSL_ROOT_DIR=/opt/android/android-openssl/openssl-OpenSSL_1_0_2l -D OPENSSL_CRYPTO_LIBRARY=/opt/android/android-openssl/prebuilt/arm64-v8a/libcrypto.so -D OPENSSL_SSL_LIBRARY=/opt/android/android-openssl/prebuilt/arm64-v8a/libssl.so -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=true ../..
|
|
||||||
make
|
|
||||||
find . -name '*.a' -exec cp '{}' lib \;
|
|
||||||
|
|
||||||
cd /opt/android/monero
|
|
||||||
mkdir -p build/release.androidx86
|
|
||||||
cd build/release.androidx86
|
|
||||||
PATH=/opt/android/toolx86/i686-linux-android/bin:/opt/android/toolx86/bin:$PATH CC=clang CXX=clang++ cmake -D BUILD_TESTS=OFF -D ARCH="i686" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D BUILD_TAG="android" -D BOOST_ROOT=/opt/android/boost_1_58_0 -D BOOST_LIBRARYDIR=/opt/android/boost_1_58_0/androidx86/lib -D OPENSSL_ROOT_DIR=/opt/android/android-openssl/openssl-OpenSSL_1_0_2l -D OPENSSL_CRYPTO_LIBRARY=/opt/android/android-openssl/prebuilt/x86/libcrypto.so -D OPENSSL_SSL_LIBRARY=/opt/android/android-openssl/prebuilt/x86/libssl.so -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=true ../..
|
|
||||||
make
|
|
||||||
find . -name '*.a' -exec cp '{}' lib \;
|
|
||||||
|
|
||||||
cd /opt/android/monero
|
|
||||||
mkdir -p build/release.androidx86_64
|
|
||||||
cd build/release.androidx86_64
|
|
||||||
PATH=/opt/android/toolx86_64/x86_64-linux-android/bin:/opt/android/toolx86_64/bin:$PATH CC=clang CXX=clang++ cmake -D BUILD_TESTS=OFF -D ARCH="x86-64" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D BUILD_TAG="android" -D BOOST_ROOT=/opt/android/boost_1_58_0 -D BOOST_LIBRARYDIR=/opt/android/boost_1_58_0/androidx86_64/lib -D OPENSSL_ROOT_DIR=/opt/android/android-openssl/openssl-OpenSSL_1_0_2l -D OPENSSL_CRYPTO_LIBRARY=/opt/android/android-openssl/prebuilt/x86_64/libcrypto.so -D OPENSSL_SSL_LIBRARY=/opt/android/android-openssl/prebuilt/x86_64/libssl.so -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=true ../..
|
|
||||||
make
|
|
||||||
find . -name '*.a' -exec cp '{}' lib \;
|
|
||||||
```
|
```
|
||||||
Ignore the warning from ```find``` - all monero static libraries are now in `lib`.
|
|
||||||
|
|
||||||
# Bringing it all together
|
# Bringing it all together
|
||||||
- Copy all .a libraries into the appropriate `external-libs` folders.
|
- Copy all .a libraries into the appropriate `external-libs` folders.
|
||||||
- Copy `/opt/android/monero/src/wallet/wallet2_api.h` into `external-libs/monero/include`
|
- Copy `/opt/android/monero/src/wallet/api/wallet2_api.h` into `external-libs/monero/include`
|
||||||
|
|
||||||
If using default locations, this would mean:
|
If using default locations, this would mean:
|
||||||
```
|
```Shell
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/boost/lib/armeabi-v7a
|
cd <path-to-xmrwallet>/external-libs
|
||||||
cp -a /opt/android/boost_1_58_0/android32/lib/*.a ~/StudioProjects/xmrwallet/external-libs/boost/lib/armeabi-v7a
|
# remove old stuff
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/openssl/lib/armeabi-v7a
|
find . -name "*.a" -or -name "*.h" -type f -delete
|
||||||
cp -a /opt/android/android-openssl/prebuilt/armeabi/*.a ~/StudioProjects/xmrwallet/external-libs/openssl/lib/armeabi-v7a
|
./collect.sh
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/monero/lib/armeabi-v7a
|
|
||||||
cp -a /opt/android/monero/build/release.android32/lib/*.a ~/StudioProjects/xmrwallet/external-libs/monero/lib/armeabi-v7a
|
|
||||||
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/boost/lib/arm64-v8a
|
|
||||||
cp -a /opt/android/boost_1_58_0/android64/lib/*.a ~/StudioProjects/xmrwallet/external-libs/boost/lib/arm64-v8a
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/openssl/lib/arm64-v8a
|
|
||||||
cp -a /opt/android/android-openssl/prebuilt/arm64-v8a/*.a ~/StudioProjects/xmrwallet/external-libs/openssl/lib/arm64-v8a
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/monero/lib/arm64-v8a
|
|
||||||
cp -a /opt/android/monero/build/release.android64/lib/*.a ~/StudioProjects/xmrwallet/external-libs/monero/lib/arm64-v8a
|
|
||||||
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/boost/lib/x86
|
|
||||||
cp -a /opt/android/boost_1_58_0/androidx86/lib/*.a ~/StudioProjects/xmrwallet/external-libs/boost/lib/x86
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/openssl/lib/x86
|
|
||||||
cp -a /opt/android/android-openssl/prebuilt/x86/*.a ~/StudioProjects/xmrwallet/external-libs/openssl/lib/x86
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/monero/lib/x86
|
|
||||||
cp -a /opt/android/monero/build/release.androidx86/lib/*.a ~/StudioProjects/xmrwallet/external-libs/monero/lib/x86
|
|
||||||
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/boost/lib/x86_64
|
|
||||||
cp -a /opt/android/boost_1_58_0/androidx86_64/lib/*.a ~/StudioProjects/xmrwallet/external-libs/boost/lib/x86_64
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/openssl/lib/x86_64
|
|
||||||
cp -a /opt/android/android-openssl/prebuilt/x86_64/*.a ~/StudioProjects/xmrwallet/external-libs/openssl/lib/x86_64
|
|
||||||
mkdir -p ~/StudioProjects/xmrwallet/external-libs/monero/lib/x86_64
|
|
||||||
cp -a /opt/android/monero/build/release.androidx86_64/lib/*.a ~/StudioProjects/xmrwallet/external-libs/monero/lib/x86_64
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# -D BOOST_ROOT=/opt/android/boost_1_58_0
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
orig_path=$PATH
|
||||||
|
|
||||||
|
packages=(boost openssl monero)
|
||||||
|
archs=(arm arm64 x86 x86_64)
|
||||||
|
|
||||||
|
for arch in ${archs[@]}; do
|
||||||
|
case ${arch} in
|
||||||
|
"arm")
|
||||||
|
xarch="armeabi-v7a"
|
||||||
|
;;
|
||||||
|
"arm64")
|
||||||
|
xarch="arm64-v8a"
|
||||||
|
;;
|
||||||
|
"x86")
|
||||||
|
xarch="x86"
|
||||||
|
;;
|
||||||
|
"x86_64")
|
||||||
|
xarch="x86_64"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 16
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for package in ${packages[@]}; do
|
||||||
|
OUTPUT_DIR=`pwd`/$package/lib/$xarch
|
||||||
|
mkdir -p $OUTPUT_DIR
|
||||||
|
rm -f $OUTPUT_DIR/*.a
|
||||||
|
cp -a /opt/android/build/$package/$arch/lib/*.a $OUTPUT_DIR
|
||||||
|
|
||||||
|
if [ $package = "monero" -a -d "/opt/android/build/$package/include" ]; then
|
||||||
|
rm -rf $OUTPUT_DIR/../../include
|
||||||
|
cp -a /opt/android/build/$package/include $OUTPUT_DIR/../..
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -33,14 +33,23 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <set>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// Public interface for libwallet library
|
// Public interface for libwallet library
|
||||||
namespace Monero {
|
namespace Monero {
|
||||||
|
|
||||||
|
enum NetworkType : uint8_t {
|
||||||
|
MAINNET = 0,
|
||||||
|
TESTNET,
|
||||||
|
STAGENET
|
||||||
|
};
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
bool isAddressLocal(const std::string &hostaddr);
|
bool isAddressLocal(const std::string &hostaddr);
|
||||||
|
void onStartup();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -68,6 +77,7 @@ struct PendingTransaction
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Priority {
|
enum Priority {
|
||||||
|
Priority_Default = 0,
|
||||||
Priority_Low = 1,
|
Priority_Low = 1,
|
||||||
Priority_Medium = 2,
|
Priority_Medium = 2,
|
||||||
Priority_High = 3,
|
Priority_High = 3,
|
||||||
|
@ -88,6 +98,8 @@ struct PendingTransaction
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
virtual uint64_t txCount() const = 0;
|
virtual uint64_t txCount() const = 0;
|
||||||
|
virtual std::vector<uint32_t> subaddrAccount() const = 0;
|
||||||
|
virtual std::vector<std::set<uint32_t>> subaddrIndices() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,13 +113,6 @@ struct UnsignedTransaction
|
||||||
Status_Critical
|
Status_Critical
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Priority {
|
|
||||||
Priority_Low = 1,
|
|
||||||
Priority_Medium = 2,
|
|
||||||
Priority_High = 3,
|
|
||||||
Priority_Last
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~UnsignedTransaction() = 0;
|
virtual ~UnsignedTransaction() = 0;
|
||||||
virtual int status() const = 0;
|
virtual int status() const = 0;
|
||||||
virtual std::string errorString() const = 0;
|
virtual std::string errorString() const = 0;
|
||||||
|
@ -155,6 +160,9 @@ struct TransactionInfo
|
||||||
virtual uint64_t amount() const = 0;
|
virtual uint64_t amount() const = 0;
|
||||||
virtual uint64_t fee() const = 0;
|
virtual uint64_t fee() const = 0;
|
||||||
virtual uint64_t blockHeight() const = 0;
|
virtual uint64_t blockHeight() const = 0;
|
||||||
|
virtual std::set<uint32_t> subaddrIndex() const = 0;
|
||||||
|
virtual uint32_t subaddrAccount() const = 0;
|
||||||
|
virtual std::string label() const = 0;
|
||||||
virtual uint64_t confirmations() const = 0;
|
virtual uint64_t confirmations() const = 0;
|
||||||
virtual uint64_t unlockTime() const = 0;
|
virtual uint64_t unlockTime() const = 0;
|
||||||
//! transaction_id
|
//! transaction_id
|
||||||
|
@ -223,6 +231,66 @@ struct AddressBook
|
||||||
virtual int lookupPaymentID(const std::string &payment_id) const = 0;
|
virtual int lookupPaymentID(const std::string &payment_id) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SubaddressRow {
|
||||||
|
public:
|
||||||
|
SubaddressRow(std::size_t _rowId, const std::string &_address, const std::string &_label):
|
||||||
|
m_rowId(_rowId),
|
||||||
|
m_address(_address),
|
||||||
|
m_label(_label) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_rowId;
|
||||||
|
std::string m_address;
|
||||||
|
std::string m_label;
|
||||||
|
public:
|
||||||
|
std::string extra;
|
||||||
|
std::string getAddress() const {return m_address;}
|
||||||
|
std::string getLabel() const {return m_label;}
|
||||||
|
std::size_t getRowId() const {return m_rowId;}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Subaddress
|
||||||
|
{
|
||||||
|
virtual ~Subaddress() = 0;
|
||||||
|
virtual std::vector<SubaddressRow*> getAll() const = 0;
|
||||||
|
virtual void addRow(uint32_t accountIndex, const std::string &label) = 0;
|
||||||
|
virtual void setLabel(uint32_t accountIndex, uint32_t addressIndex, const std::string &label) = 0;
|
||||||
|
virtual void refresh(uint32_t accountIndex) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SubaddressAccountRow {
|
||||||
|
public:
|
||||||
|
SubaddressAccountRow(std::size_t _rowId, const std::string &_address, const std::string &_label, const std::string &_balance, const std::string &_unlockedBalance):
|
||||||
|
m_rowId(_rowId),
|
||||||
|
m_address(_address),
|
||||||
|
m_label(_label),
|
||||||
|
m_balance(_balance),
|
||||||
|
m_unlockedBalance(_unlockedBalance) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t m_rowId;
|
||||||
|
std::string m_address;
|
||||||
|
std::string m_label;
|
||||||
|
std::string m_balance;
|
||||||
|
std::string m_unlockedBalance;
|
||||||
|
public:
|
||||||
|
std::string extra;
|
||||||
|
std::string getAddress() const {return m_address;}
|
||||||
|
std::string getLabel() const {return m_label;}
|
||||||
|
std::string getBalance() const {return m_balance;}
|
||||||
|
std::string getUnlockedBalance() const {return m_unlockedBalance;}
|
||||||
|
std::size_t getRowId() const {return m_rowId;}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SubaddressAccount
|
||||||
|
{
|
||||||
|
virtual ~SubaddressAccount() = 0;
|
||||||
|
virtual std::vector<SubaddressAccountRow*> getAll() const = 0;
|
||||||
|
virtual void addRow(const std::string &label) = 0;
|
||||||
|
virtual void setLabel(uint32_t accountIndex, const std::string &label) = 0;
|
||||||
|
virtual void refresh() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct WalletListener
|
struct WalletListener
|
||||||
{
|
{
|
||||||
virtual ~WalletListener() = 0;
|
virtual ~WalletListener() = 0;
|
||||||
|
@ -294,9 +362,13 @@ struct Wallet
|
||||||
//! in case error status, returns error string
|
//! in case error status, returns error string
|
||||||
virtual std::string errorString() const = 0;
|
virtual std::string errorString() const = 0;
|
||||||
virtual bool setPassword(const std::string &password) = 0;
|
virtual bool setPassword(const std::string &password) = 0;
|
||||||
virtual std::string address() const = 0;
|
virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0;
|
||||||
|
std::string mainAddress() const { return address(0, 0); }
|
||||||
virtual std::string path() const = 0;
|
virtual std::string path() const = 0;
|
||||||
virtual bool testnet() const = 0;
|
virtual NetworkType nettype() const = 0;
|
||||||
|
bool mainnet() const { return nettype() == MAINNET; }
|
||||||
|
bool testnet() const { return nettype() == TESTNET; }
|
||||||
|
bool stagenet() const { return nettype() == STAGENET; }
|
||||||
//! returns current hard fork info
|
//! returns current hard fork info
|
||||||
virtual void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const = 0;
|
virtual void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const = 0;
|
||||||
//! check if hard fork rules should be used
|
//! check if hard fork rules should be used
|
||||||
|
@ -360,9 +432,12 @@ struct Wallet
|
||||||
*
|
*
|
||||||
* \param daemon_address - daemon address in "hostname:port" format
|
* \param daemon_address - daemon address in "hostname:port" format
|
||||||
* \param upper_transaction_size_limit
|
* \param upper_transaction_size_limit
|
||||||
|
* \param daemon_username
|
||||||
|
* \param daemon_password
|
||||||
|
* \param lightWallet - start wallet in light mode, connect to a openmonero compatible server.
|
||||||
* \return - true on success
|
* \return - true on success
|
||||||
*/
|
*/
|
||||||
virtual bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit, const std::string &daemon_username = "", const std::string &daemon_password = "") = 0;
|
virtual bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit = 0, const std::string &daemon_username = "", const std::string &daemon_password = "", bool use_ssl = false, bool lightWallet = false) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief createWatchOnly - Creates a watch only wallet
|
* \brief createWatchOnly - Creates a watch only wallet
|
||||||
|
@ -406,8 +481,20 @@ struct Wallet
|
||||||
virtual ConnectionStatus connected() const = 0;
|
virtual ConnectionStatus connected() const = 0;
|
||||||
virtual void setTrustedDaemon(bool arg) = 0;
|
virtual void setTrustedDaemon(bool arg) = 0;
|
||||||
virtual bool trustedDaemon() const = 0;
|
virtual bool trustedDaemon() const = 0;
|
||||||
virtual uint64_t balance() const = 0;
|
virtual uint64_t balance(uint32_t accountIndex = 0) const = 0;
|
||||||
virtual uint64_t unlockedBalance() const = 0;
|
uint64_t balanceAll() const {
|
||||||
|
uint64_t result = 0;
|
||||||
|
for (uint32_t i = 0; i < numSubaddressAccounts(); ++i)
|
||||||
|
result += balance(i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
virtual uint64_t unlockedBalance(uint32_t accountIndex = 0) const = 0;
|
||||||
|
uint64_t unlockedBalanceAll() const {
|
||||||
|
uint64_t result = 0;
|
||||||
|
for (uint32_t i = 0; i < numSubaddressAccounts(); ++i)
|
||||||
|
result += unlockedBalance(i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief watchOnly - checks if wallet is watch only
|
* @brief watchOnly - checks if wallet is watch only
|
||||||
|
@ -452,13 +539,28 @@ struct Wallet
|
||||||
static uint64_t amountFromDouble(double amount);
|
static uint64_t amountFromDouble(double amount);
|
||||||
static std::string genPaymentId();
|
static std::string genPaymentId();
|
||||||
static bool paymentIdValid(const std::string &paiment_id);
|
static bool paymentIdValid(const std::string &paiment_id);
|
||||||
static bool addressValid(const std::string &str, bool testnet);
|
static bool addressValid(const std::string &str, NetworkType nettype);
|
||||||
static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error);
|
static bool addressValid(const std::string &str, bool testnet) // deprecated
|
||||||
static std::string paymentIdFromAddress(const std::string &str, bool testnet);
|
{
|
||||||
|
return addressValid(str, testnet ? TESTNET : MAINNET);
|
||||||
|
}
|
||||||
|
static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, NetworkType nettype, std::string &error);
|
||||||
|
static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error) // deprecated
|
||||||
|
{
|
||||||
|
return keyValid(secret_key_string, address_string, isViewKey, testnet ? TESTNET : MAINNET, error);
|
||||||
|
}
|
||||||
|
static std::string paymentIdFromAddress(const std::string &str, NetworkType nettype);
|
||||||
|
static std::string paymentIdFromAddress(const std::string &str, bool testnet) // deprecated
|
||||||
|
{
|
||||||
|
return paymentIdFromAddress(str, testnet ? TESTNET : MAINNET);
|
||||||
|
}
|
||||||
static uint64_t maximumAllowedAmount();
|
static uint64_t maximumAllowedAmount();
|
||||||
// Easylogger wrapper
|
// Easylogger wrapper
|
||||||
static void init(const char *argv0, const char *default_log_base_name);
|
static void init(const char *argv0, const char *default_log_base_name);
|
||||||
static void debug(const std::string &str);
|
static void debug(const std::string &category, const std::string &str);
|
||||||
|
static void info(const std::string &category, const std::string &str);
|
||||||
|
static void warning(const std::string &category, const std::string &str);
|
||||||
|
static void error(const std::string &category, const std::string &str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds)
|
* @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds)
|
||||||
|
@ -492,6 +594,39 @@ struct Wallet
|
||||||
*/
|
*/
|
||||||
virtual int autoRefreshInterval() const = 0;
|
virtual int autoRefreshInterval() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief addSubaddressAccount - appends a new subaddress account at the end of the last major index of existing subaddress accounts
|
||||||
|
* @param label - the label for the new account (which is the as the label of the primary address (accountIndex,0))
|
||||||
|
*/
|
||||||
|
virtual void addSubaddressAccount(const std::string& label) = 0;
|
||||||
|
/**
|
||||||
|
* @brief numSubaddressAccounts - returns the number of existing subaddress accounts
|
||||||
|
*/
|
||||||
|
virtual size_t numSubaddressAccounts() const = 0;
|
||||||
|
/**
|
||||||
|
* @brief numSubaddresses - returns the number of existing subaddresses associated with the specified subaddress account
|
||||||
|
* @param accountIndex - the major index specifying the subaddress account
|
||||||
|
*/
|
||||||
|
virtual size_t numSubaddresses(uint32_t accountIndex) const = 0;
|
||||||
|
/**
|
||||||
|
* @brief addSubaddress - appends a new subaddress at the end of the last minor index of the specified subaddress account
|
||||||
|
* @param accountIndex - the major index specifying the subaddress account
|
||||||
|
* @param label - the label for the new subaddress
|
||||||
|
*/
|
||||||
|
virtual void addSubaddress(uint32_t accountIndex, const std::string& label) = 0;
|
||||||
|
/**
|
||||||
|
* @brief getSubaddressLabel - gets the label of the specified subaddress
|
||||||
|
* @param accountIndex - the major index specifying the subaddress account
|
||||||
|
* @param addressIndex - the minor index specifying the subaddress
|
||||||
|
*/
|
||||||
|
virtual std::string getSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex) const = 0;
|
||||||
|
/**
|
||||||
|
* @brief setSubaddressLabel - sets the label of the specified subaddress
|
||||||
|
* @param accountIndex - the major index specifying the subaddress account
|
||||||
|
* @param addressIndex - the minor index specifying the subaddress
|
||||||
|
* @param label - the new label for the specified subaddress
|
||||||
|
*/
|
||||||
|
virtual void setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex, const std::string &label) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored
|
* \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored
|
||||||
|
@ -499,6 +634,8 @@ struct Wallet
|
||||||
* \param payment_id optional payment_id, can be empty string
|
* \param payment_id optional payment_id, can be empty string
|
||||||
* \param amount amount
|
* \param amount amount
|
||||||
* \param mixin_count mixin count. if 0 passed, wallet will use default value
|
* \param mixin_count mixin count. if 0 passed, wallet will use default value
|
||||||
|
* \param subaddr_account subaddress account from which the input funds are taken
|
||||||
|
* \param subaddr_indices set of subaddress indices to use for transfer or sweeping. if set empty, all are chosen when sweeping, and one or more are automatically chosen when transferring. after execution, returns the set of actually used indices
|
||||||
* \param priority
|
* \param priority
|
||||||
* \return PendingTransaction object. caller is responsible to check PendingTransaction::status()
|
* \return PendingTransaction object. caller is responsible to check PendingTransaction::status()
|
||||||
* after object returned
|
* after object returned
|
||||||
|
@ -506,7 +643,9 @@ struct Wallet
|
||||||
|
|
||||||
virtual PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
|
virtual PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
|
||||||
optional<uint64_t> amount, uint32_t mixin_count,
|
optional<uint64_t> amount, uint32_t mixin_count,
|
||||||
PendingTransaction::Priority = PendingTransaction::Priority_Low) = 0;
|
PendingTransaction::Priority = PendingTransaction::Priority_Low,
|
||||||
|
uint32_t subaddr_account = 0,
|
||||||
|
std::set<uint32_t> subaddr_indices = {}) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief createSweepUnmixableTransaction creates transaction with unmixable outputs.
|
* \brief createSweepUnmixableTransaction creates transaction with unmixable outputs.
|
||||||
|
@ -551,8 +690,10 @@ struct Wallet
|
||||||
virtual bool importKeyImages(const std::string &filename) = 0;
|
virtual bool importKeyImages(const std::string &filename) = 0;
|
||||||
|
|
||||||
|
|
||||||
virtual TransactionHistory * history() const = 0;
|
virtual TransactionHistory * history() = 0;
|
||||||
virtual AddressBook * addressBook() const = 0;
|
virtual AddressBook * addressBook() = 0;
|
||||||
|
virtual Subaddress * subaddress() = 0;
|
||||||
|
virtual SubaddressAccount * subaddressAccount() = 0;
|
||||||
virtual void setListener(WalletListener *) = 0;
|
virtual void setListener(WalletListener *) = 0;
|
||||||
/*!
|
/*!
|
||||||
* \brief defaultMixin - returns number of mixins used in transactions
|
* \brief defaultMixin - returns number of mixins used in transactions
|
||||||
|
@ -569,7 +710,7 @@ struct Wallet
|
||||||
* \brief setUserNote - attach an arbitrary string note to a txid
|
* \brief setUserNote - attach an arbitrary string note to a txid
|
||||||
* \param txid - the transaction id to attach the note to
|
* \param txid - the transaction id to attach the note to
|
||||||
* \param note - the note
|
* \param note - the note
|
||||||
* \return true if succesful, false otherwise
|
* \return true if successful, false otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool setUserNote(const std::string &txid, const std::string ¬e) = 0;
|
virtual bool setUserNote(const std::string &txid, const std::string ¬e) = 0;
|
||||||
/*!
|
/*!
|
||||||
|
@ -579,6 +720,17 @@ struct Wallet
|
||||||
*/
|
*/
|
||||||
virtual std::string getUserNote(const std::string &txid) const = 0;
|
virtual std::string getUserNote(const std::string &txid) const = 0;
|
||||||
virtual std::string getTxKey(const std::string &txid) const = 0;
|
virtual std::string getTxKey(const std::string &txid) const = 0;
|
||||||
|
virtual bool checkTxKey(const std::string &txid, std::string tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0;
|
||||||
|
virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message) const = 0;
|
||||||
|
virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0;
|
||||||
|
virtual std::string getSpendProof(const std::string &txid, const std::string &message) const = 0;
|
||||||
|
virtual bool checkSpendProof(const std::string &txid, const std::string &message, const std::string &signature, bool &good) const = 0;
|
||||||
|
/*!
|
||||||
|
* \brief getReserveProof - Generates a proof that proves the reserve of unspent funds
|
||||||
|
* Parameters `account_index` and `amount` are ignored when `all` is true
|
||||||
|
*/
|
||||||
|
virtual std::string getReserveProof(bool all, uint32_t account_index, uint64_t amount, const std::string &message) const = 0;
|
||||||
|
virtual bool checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \brief signMessage - sign a message with the spend private key
|
* \brief signMessage - sign a message with the spend private key
|
||||||
|
@ -604,6 +756,36 @@ struct Wallet
|
||||||
* \return true on success
|
* \return true on success
|
||||||
*/
|
*/
|
||||||
virtual bool rescanSpent() = 0;
|
virtual bool rescanSpent() = 0;
|
||||||
|
|
||||||
|
//! blackballs a set of outputs
|
||||||
|
virtual bool blackballOutputs(const std::vector<std::string> &pubkeys, bool add) = 0;
|
||||||
|
|
||||||
|
//! unblackballs an output
|
||||||
|
virtual bool unblackballOutput(const std::string &pubkey) = 0;
|
||||||
|
|
||||||
|
//! gets the ring used for a key image, if any
|
||||||
|
virtual bool getRing(const std::string &key_image, std::vector<uint64_t> &ring) const = 0;
|
||||||
|
|
||||||
|
//! gets the rings used for a txid, if any
|
||||||
|
virtual bool getRings(const std::string &txid, std::vector<std::pair<std::string, std::vector<uint64_t>>> &rings) const = 0;
|
||||||
|
|
||||||
|
//! sets the ring used for a key image
|
||||||
|
virtual bool setRing(const std::string &key_image, const std::vector<uint64_t> &ring, bool relative) = 0;
|
||||||
|
|
||||||
|
//! sets whether pre-fork outs are to be segregated
|
||||||
|
virtual void segregatePreForkOutputs(bool segregate) = 0;
|
||||||
|
|
||||||
|
//! sets the height where segregation should occur
|
||||||
|
virtual void segregationHeight(uint64_t height) = 0;
|
||||||
|
|
||||||
|
//! secondary key reuse mitigation
|
||||||
|
virtual void keyReuseMitigation2(bool mitigation) = 0;
|
||||||
|
|
||||||
|
//! Light wallet authenticate and login
|
||||||
|
virtual bool lightWalletLogin(bool &isNewWallet) const = 0;
|
||||||
|
|
||||||
|
//! Initiates a light wallet import wallet request
|
||||||
|
virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -616,84 +798,125 @@ struct WalletManager
|
||||||
* \brief Creates new wallet
|
* \brief Creates new wallet
|
||||||
* \param path Name of wallet file
|
* \param path Name of wallet file
|
||||||
* \param password Password of wallet file
|
* \param password Password of wallet file
|
||||||
* \param language Language to be used to generate electrum seed memo
|
* \param language Language to be used to generate electrum seed mnemonic
|
||||||
|
* \param nettype Network type
|
||||||
* \return Wallet instance (Wallet::status() needs to be called to check if created successfully)
|
* \return Wallet instance (Wallet::status() needs to be called to check if created successfully)
|
||||||
*/
|
*/
|
||||||
virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, bool testnet = false) = 0;
|
virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, NetworkType nettype) = 0;
|
||||||
|
Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, bool testnet = false) // deprecated
|
||||||
|
{
|
||||||
|
return createWallet(path, password, language, testnet ? TESTNET : MAINNET);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Opens existing wallet
|
* \brief Opens existing wallet
|
||||||
* \param path Name of wallet file
|
* \param path Name of wallet file
|
||||||
* \param password Password of wallet file
|
* \param password Password of wallet file
|
||||||
|
* \param nettype Network type
|
||||||
* \return Wallet instance (Wallet::status() needs to be called to check if opened successfully)
|
* \return Wallet instance (Wallet::status() needs to be called to check if opened successfully)
|
||||||
*/
|
*/
|
||||||
virtual Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) = 0;
|
virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype) = 0;
|
||||||
|
Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) // deprecated
|
||||||
|
{
|
||||||
|
return openWallet(path, password, testnet ? TESTNET : MAINNET);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief recovers existing wallet using memo (electrum seed)
|
* \brief recovers existing wallet using mnemonic (electrum seed)
|
||||||
* \param path Name of wallet file to be created
|
* \param path Name of wallet file to be created
|
||||||
* \param password Password of wallet file
|
* \param password Password of wallet file
|
||||||
* \param memo memo (25 words electrum seed)
|
* \param mnemonic mnemonic (25 words electrum seed)
|
||||||
* \param testnet testnet
|
* \param nettype Network type
|
||||||
* \param restoreHeight restore from start height
|
* \param restoreHeight restore from start height
|
||||||
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
||||||
*/
|
*/
|
||||||
virtual Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &memo, bool testnet = false, uint64_t restoreHeight = 0) = 0;
|
virtual Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic,
|
||||||
|
NetworkType nettype = MAINNET, uint64_t restoreHeight = 0) = 0;
|
||||||
|
Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic,
|
||||||
|
bool testnet = false, uint64_t restoreHeight = 0) // deprecated
|
||||||
|
{
|
||||||
|
return recoveryWallet(path, password, mnemonic, testnet ? TESTNET : MAINNET, restoreHeight);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \deprecated this method creates a wallet WITHOUT a psssphrase, use the alternate recoverWallet() method
|
* \deprecated this method creates a wallet WITHOUT a passphrase, use the alternate recoverWallet() method
|
||||||
* \brief recovers existing wallet using memo (electrum seed)
|
* \brief recovers existing wallet using mnemonic (electrum seed)
|
||||||
* \param path Name of wallet file to be created
|
* \param path Name of wallet file to be created
|
||||||
* \param memo memo (25 words electrum seed)
|
* \param mnemonic mnemonic (25 words electrum seed)
|
||||||
* \param testnet testnet
|
* \param nettype Network type
|
||||||
* \param restoreHeight restore from start height
|
* \param restoreHeight restore from start height
|
||||||
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
||||||
*/
|
*/
|
||||||
virtual Wallet * recoveryWallet(const std::string &path, const std::string &memo, bool testnet = false, uint64_t restoreHeight = 0) = 0;
|
virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight = 0) = 0;
|
||||||
|
Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, bool testnet = false, uint64_t restoreHeight = 0) // deprecated
|
||||||
|
{
|
||||||
|
return recoveryWallet(path, mnemonic, testnet ? TESTNET : MAINNET, restoreHeight);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted
|
* \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted
|
||||||
* \param path Name of wallet file to be created
|
* \param path Name of wallet file to be created
|
||||||
* \param password Password of wallet file
|
* \param password Password of wallet file
|
||||||
* \param language language
|
* \param language language
|
||||||
* \param testnet testnet
|
* \param nettype Network type
|
||||||
* \param restoreHeight restore from start height
|
* \param restoreHeight restore from start height
|
||||||
* \param addressString public address
|
* \param addressString public address
|
||||||
* \param viewKeyString view key
|
* \param viewKeyString view key
|
||||||
* \param spendKeyString spend key (optional)
|
* \param spendKeyString spend key (optional)
|
||||||
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
||||||
*/
|
*/
|
||||||
virtual Wallet * createWalletWithKeys(const std::string &path,
|
virtual Wallet * createWalletFromKeys(const std::string &path,
|
||||||
const std::string &password,
|
const std::string &password,
|
||||||
const std::string &language,
|
const std::string &language,
|
||||||
bool testnet,
|
NetworkType nettype,
|
||||||
uint64_t restoreHeight,
|
uint64_t restoreHeight,
|
||||||
const std::string &addressString,
|
const std::string &addressString,
|
||||||
const std::string &viewKeyString,
|
const std::string &viewKeyString,
|
||||||
const std::string &spendKeyString = "") = 0;
|
const std::string &spendKeyString = "") = 0;
|
||||||
|
Wallet * createWalletFromKeys(const std::string &path,
|
||||||
|
const std::string &password,
|
||||||
|
const std::string &language,
|
||||||
|
bool testnet,
|
||||||
|
uint64_t restoreHeight,
|
||||||
|
const std::string &addressString,
|
||||||
|
const std::string &viewKeyString,
|
||||||
|
const std::string &spendKeyString = "") // deprecated
|
||||||
|
{
|
||||||
|
return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \deprecated this method creates a wallet WITHOUT a psssphrase, use createWalletWithKeys() instead
|
* \deprecated this method creates a wallet WITHOUT a passphrase, use createWalletFromKeys(..., password, ...) instead
|
||||||
* \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted
|
* \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted
|
||||||
* \param path Name of wallet file to be created
|
* \param path Name of wallet file to be created
|
||||||
* \param language language
|
* \param language language
|
||||||
* \param testnet testnet
|
* \param nettype Network type
|
||||||
* \param restoreHeight restore from start height
|
* \param restoreHeight restore from start height
|
||||||
* \param addressString public address
|
* \param addressString public address
|
||||||
* \param viewKeyString view key
|
* \param viewKeyString view key
|
||||||
* \param spendKeyString spend key (optional)
|
* \param spendKeyString spend key (optional)
|
||||||
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
|
||||||
*/
|
*/
|
||||||
virtual Wallet * createWalletFromKeys(const std::string &path,
|
virtual Wallet * createWalletFromKeys(const std::string &path,
|
||||||
const std::string &language,
|
const std::string &language,
|
||||||
bool testnet,
|
NetworkType nettype,
|
||||||
uint64_t restoreHeight,
|
uint64_t restoreHeight,
|
||||||
const std::string &addressString,
|
const std::string &addressString,
|
||||||
const std::string &viewKeyString,
|
const std::string &viewKeyString,
|
||||||
const std::string &spendKeyString = "") = 0;
|
const std::string &spendKeyString = "") = 0;
|
||||||
|
Wallet * createWalletFromKeys(const std::string &path,
|
||||||
|
const std::string &language,
|
||||||
|
bool testnet,
|
||||||
|
uint64_t restoreHeight,
|
||||||
|
const std::string &addressString,
|
||||||
|
const std::string &viewKeyString,
|
||||||
|
const std::string &spendKeyString = "") // deprecated
|
||||||
|
{
|
||||||
|
return createWalletFromKeys(path, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Closes wallet. In case operation succeded, wallet object deleted. in case operation failed, wallet object not deleted
|
* \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted
|
||||||
* \param wallet previously opened / created wallet instance
|
* \param wallet previously opened / created wallet instance
|
||||||
* \return None
|
* \return None
|
||||||
*/
|
*/
|
||||||
|
@ -714,10 +937,10 @@ struct WalletManager
|
||||||
* @brief verifyWalletPassword - check if the given filename is the wallet
|
* @brief verifyWalletPassword - check if the given filename is the wallet
|
||||||
* @param keys_file_name - location of keys file
|
* @param keys_file_name - location of keys file
|
||||||
* @param password - password to verify
|
* @param password - password to verify
|
||||||
* @param watch_only - verify only view keys?
|
* @param no_spend_key - verify only view keys?
|
||||||
* @return - true if password is correct
|
* @return - true if password is correct
|
||||||
*/
|
*/
|
||||||
virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool watch_only) const = 0;
|
virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key) const = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief findWallets - searches for the wallet files by given path name recursively
|
* \brief findWallets - searches for the wallet files by given path name recursively
|
||||||
|
@ -726,19 +949,6 @@ struct WalletManager
|
||||||
*/
|
*/
|
||||||
virtual std::vector<std::string> findWallets(const std::string &path) = 0;
|
virtual std::vector<std::string> findWallets(const std::string &path) = 0;
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief checkPayment - checks a payment was made using a txkey
|
|
||||||
* \param address - the address the payment was sent to
|
|
||||||
* \param txid - the transaction id for that payment
|
|
||||||
* \param txkey - the transaction's secret key
|
|
||||||
* \param daemon_address - the address (host and port) to the daemon to request transaction data
|
|
||||||
* \param received - if succesful, will hold the amount of monero received
|
|
||||||
* \param height - if succesful, will hold the height of the transaction (0 if only in the pool)
|
|
||||||
* \param error - if unsuccesful, will hold an error string with more information about the error
|
|
||||||
* \return - true is succesful, false otherwise
|
|
||||||
*/
|
|
||||||
virtual bool checkPayment(const std::string &address, const std::string &txid, const std::string &txkey, const std::string &daemon_address, uint64_t &received, uint64_t &height, std::string &error) const = 0;
|
|
||||||
|
|
||||||
//! returns verbose error string regarding last error;
|
//! returns verbose error string regarding last error;
|
||||||
virtual std::string errorString() const = 0;
|
virtual std::string errorString() const = 0;
|
||||||
|
|
||||||
|
@ -776,7 +986,7 @@ struct WalletManager
|
||||||
virtual std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const = 0;
|
virtual std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const = 0;
|
||||||
|
|
||||||
//! checks for an update and returns version, hash and url
|
//! checks for an update and returns version, hash and url
|
||||||
static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir);
|
static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, std::string subdir);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue