mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-03 08:23:04 +02:00
Compare commits
263 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c956f38899 | ||
![]() |
db68f517d3 | ||
![]() |
d4b293af80 | ||
![]() |
f7bbfc2fac | ||
![]() |
e08964749e | ||
![]() |
a05fa9d177 | ||
![]() |
7fe2fbe37d | ||
![]() |
40e30fed08 | ||
![]() |
320c7865ff | ||
![]() |
5e8cf8010e | ||
![]() |
e671fa19e0 | ||
![]() |
20d5b9a100 | ||
![]() |
5d489a634b | ||
![]() |
59b6f484fd | ||
![]() |
ecaa49d67d | ||
![]() |
d2dc53599e | ||
![]() |
4d8b26f97f | ||
![]() |
581c76e7be | ||
![]() |
6f66862870 | ||
![]() |
dd92f7bb36 | ||
![]() |
46808d306b | ||
![]() |
20503d2cbd | ||
![]() |
604691ca7e | ||
![]() |
1b626ba2b0 | ||
![]() |
0ed7bdfcee | ||
![]() |
524c3dd79f | ||
![]() |
197dffeae1 | ||
![]() |
cdb29bbc2e | ||
![]() |
7b96baeca7 | ||
![]() |
0712efec78 | ||
![]() |
341df6c6a3 | ||
![]() |
ab8fb82c1b | ||
![]() |
22d9173cea | ||
![]() |
05720e63ab | ||
![]() |
cdc2b23257 | ||
![]() |
9f0e89719c | ||
![]() |
190726e61c | ||
![]() |
729fafdb48 | ||
![]() |
b7ae23ac64 | ||
![]() |
27885f2c86 | ||
![]() |
ce9046c7b5 | ||
![]() |
506e6ce017 | ||
![]() |
f07b439731 | ||
![]() |
ac70ba8424 | ||
![]() |
84ec1ef418 | ||
![]() |
b576a9de3d | ||
![]() |
148faa00e4 | ||
![]() |
e82b471c14 | ||
![]() |
9ed92e5117 | ||
![]() |
303b3aa354 | ||
![]() |
d801a50962 | ||
![]() |
9cd8a75dc6 | ||
![]() |
002dfd5d58 | ||
![]() |
54e54b2a8a | ||
![]() |
aa768596a4 | ||
![]() |
c4958f6c54 | ||
![]() |
2c2a5314d4 | ||
![]() |
669516c60b | ||
![]() |
a56a29a6c4 | ||
![]() |
4e31f47482 | ||
![]() |
c1f14f9653 | ||
![]() |
2746c52d7b | ||
![]() |
5df323bacb | ||
![]() |
776cc26377 | ||
![]() |
bdfb6a90b6 | ||
![]() |
6db44dfab1 | ||
![]() |
c68ac7db6d | ||
![]() |
e09862e940 | ||
![]() |
c7bd7469a1 | ||
![]() |
b39857fd2e | ||
![]() |
8170f823ab | ||
![]() |
38c0ead45c | ||
![]() |
1d027c1694 | ||
![]() |
45dc21fbf7 | ||
![]() |
d4f4de234a | ||
![]() |
394d5471e3 | ||
![]() |
beb098adb3 | ||
![]() |
fda370d35b | ||
![]() |
99681e1bbb | ||
![]() |
21f44380b1 | ||
![]() |
f4c1af1bb8 | ||
![]() |
c002b81ebd | ||
![]() |
d2f07ba3b6 | ||
![]() |
24fc27b09e | ||
![]() |
cf4ff856d5 | ||
![]() |
b01de1ad6e | ||
![]() |
5fb1bcb552 | ||
![]() |
b937ba38b6 | ||
![]() |
849718fdc7 | ||
![]() |
a6372f701d | ||
![]() |
12f135bb14 | ||
![]() |
16870fcbb9 | ||
![]() |
2fbd152fb3 | ||
![]() |
a7b178e024 | ||
![]() |
c5a035437b | ||
![]() |
75c550fd19 | ||
![]() |
1b680344b1 | ||
![]() |
3329636d32 | ||
![]() |
77e9bf7c43 | ||
![]() |
40f5c9365e | ||
![]() |
850ba7efef | ||
![]() |
548369ca0b | ||
![]() |
afc0d5b7bc | ||
![]() |
02e92db59a | ||
![]() |
2b34454214 | ||
![]() |
12706119d3 | ||
![]() |
f7a762f32b | ||
![]() |
86d5d2a2cb | ||
![]() |
e56369b91a | ||
![]() |
b04aa24269 | ||
![]() |
dda86bd5de | ||
![]() |
a19ad7fd52 | ||
![]() |
0443fd808c | ||
![]() |
faf57c96fc | ||
![]() |
57ddddfce2 | ||
![]() |
ab6069058b | ||
![]() |
d94d6e6925 | ||
![]() |
4a819cc159 | ||
![]() |
f40c3d6c6d | ||
![]() |
82b25df7ad | ||
![]() |
08f815e830 | ||
![]() |
4e59be2dff | ||
![]() |
45c5883e11 | ||
![]() |
067a23e6a5 | ||
![]() |
d21fd41c44 | ||
![]() |
6632547d1e | ||
![]() |
f1b786ec3e | ||
![]() |
a93e96d34c | ||
![]() |
1829d30b61 | ||
![]() |
e5b15b7816 | ||
![]() |
7206857a5b | ||
![]() |
85d84d09ee | ||
![]() |
c6a1b503bc | ||
![]() |
8bda7aa0cf | ||
![]() |
97fb0a5483 | ||
![]() |
fc950c6772 | ||
![]() |
46add5e927 | ||
![]() |
fa0692ceab | ||
![]() |
ff4f4a1c2c | ||
![]() |
79abb89725 | ||
![]() |
ef8301fd6f | ||
![]() |
3a15c842ff | ||
![]() |
1697da55b5 | ||
![]() |
454f3e412a | ||
![]() |
d803a1e220 | ||
![]() |
f2fe781cb5 | ||
![]() |
dcf60ae193 | ||
![]() |
ffdf54c2e1 | ||
![]() |
c060a2ab88 | ||
![]() |
05fc654f3a | ||
![]() |
c32d157150 | ||
![]() |
74e9278baa | ||
![]() |
e41e344d63 | ||
![]() |
e66875437d | ||
![]() |
c1d2db3d7d | ||
![]() |
0c9a2f5e01 | ||
![]() |
64616e3921 | ||
![]() |
82b4d66987 | ||
![]() |
10f2bc6561 | ||
![]() |
2ed9a78d9e | ||
![]() |
ca19f32f8f | ||
![]() |
4431d74051 | ||
![]() |
f00da6ecda | ||
![]() |
1cecd0b718 | ||
![]() |
a0d6117bbb | ||
![]() |
0b0648a172 | ||
![]() |
775dcf01ae | ||
![]() |
aed4051d44 | ||
![]() |
a586c0781a | ||
![]() |
616d93cb18 | ||
![]() |
73d9cb6d58 | ||
![]() |
9846e8b5cf | ||
![]() |
aa66a12dac | ||
![]() |
65ce9b0889 | ||
![]() |
291e311b8a | ||
![]() |
41290f51fd | ||
![]() |
a11c898e2c | ||
![]() |
9c921183ab | ||
![]() |
b978396a38 | ||
![]() |
c6aa04e986 | ||
![]() |
6c17b8bd87 | ||
![]() |
835a35c6a8 | ||
![]() |
cac32f660c | ||
![]() |
8e70004bf2 | ||
![]() |
c3a466c392 | ||
![]() |
e076c19e3e | ||
![]() |
35b717756d | ||
![]() |
c14486306e | ||
![]() |
c2ef25c377 | ||
![]() |
b7164ef200 | ||
![]() |
f94a366d51 | ||
![]() |
286a04b5ef | ||
![]() |
1209295a8c | ||
![]() |
037b019d4d | ||
![]() |
7a1d788f2a | ||
![]() |
87d9a8cd95 | ||
![]() |
f637d7f617 | ||
![]() |
a4b9a7c6fb | ||
![]() |
9f01155cb7 | ||
![]() |
08e8a48138 | ||
![]() |
551c3b9fb6 | ||
![]() |
2258cb7096 | ||
![]() |
6d61841cf3 | ||
![]() |
c65508d288 | ||
![]() |
2c3f582672 | ||
![]() |
f46ba75771 | ||
![]() |
0ce5f2b6ca | ||
![]() |
110057c294 | ||
![]() |
7553d3c5f4 | ||
![]() |
317976b34a | ||
![]() |
6ad423567f | ||
![]() |
d497158856 | ||
![]() |
f4cada5fa1 | ||
![]() |
352f0ad09c | ||
![]() |
ff1a9c1570 | ||
![]() |
fa811a39a2 | ||
![]() |
cf5018be33 | ||
![]() |
8ec027f9d4 | ||
![]() |
f28428e677 | ||
![]() |
294084bec5 | ||
![]() |
4349907627 | ||
![]() |
f7cef24a83 | ||
![]() |
2774f99b15 | ||
![]() |
bc630fc445 | ||
![]() |
895cf16d33 | ||
![]() |
7f1796b12e | ||
![]() |
abe5c8afab | ||
![]() |
47f79b5269 | ||
![]() |
c9c07eaa15 | ||
![]() |
a490e3af0c | ||
![]() |
64d5b3bdea | ||
![]() |
bf91eaf22f | ||
![]() |
2c3e73b540 | ||
![]() |
830d9dadb9 | ||
![]() |
331d88ebba | ||
![]() |
7cc2f6fafb | ||
![]() |
9a3ee0eda8 | ||
![]() |
6e898939a3 | ||
![]() |
40ae39d647 | ||
![]() |
ca81e652e5 | ||
![]() |
796048be4e | ||
![]() |
441bf995c8 | ||
![]() |
e8860ab8eb | ||
![]() |
525b38ff53 | ||
![]() |
ba79bf87aa | ||
![]() |
3fe6571e7d | ||
![]() |
364e6a8137 | ||
![]() |
cb69ce99d6 | ||
![]() |
1f976872fc | ||
![]() |
27f266b6f7 | ||
![]() |
168928d54a | ||
![]() |
b3f61072aa | ||
![]() |
ccb64aded0 | ||
![]() |
e98fa089f2 | ||
![]() |
884878b7a7 | ||
![]() |
4e23f0ef3a | ||
![]() |
6ea4e3d998 | ||
![]() |
971c90f35b | ||
![]() |
f0523c403c | ||
![]() |
966ed23b87 | ||
![]() |
95f2ca74a6 | ||
![]() |
81d94478f2 | ||
![]() |
16ff779ebc |
@@ -3,13 +3,11 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/code
|
||||
docker:
|
||||
- image: circleci/android:api-28-ndk
|
||||
- image: cimg/android:2022.03-ndk
|
||||
environment:
|
||||
JVM_OPTS: -Xmx3200m
|
||||
steps:
|
||||
- checkout
|
||||
- run: yes | sdkmanager --licenses || exit 0
|
||||
- run: yes | sdkmanager --update || exit 0
|
||||
- restore_cache:
|
||||
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
|
||||
- run:
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,3 +14,5 @@
|
||||
/app/prodMainnet
|
||||
/app/alphaStagenet
|
||||
/app/prodStagenet
|
||||
/app/.cxx
|
||||
/monerujo.id
|
||||
|
@@ -13,7 +13,7 @@ set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../external-libs)
|
||||
|
||||
add_library(sodium STATIC IMPORTED)
|
||||
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/libsodium/lib/${ANDROID_ABI}/libsodium.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libsodium.a)
|
||||
|
||||
############
|
||||
# OpenSSL
|
||||
@@ -21,11 +21,11 @@ set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
add_library(crypto STATIC IMPORTED)
|
||||
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libcrypto.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libcrypto.a)
|
||||
|
||||
add_library(ssl STATIC IMPORTED)
|
||||
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libssl.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libssl.a)
|
||||
|
||||
############
|
||||
# Boost
|
||||
@@ -33,39 +33,39 @@ set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
add_library(boost_chrono STATIC IMPORTED)
|
||||
set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_chrono.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_chrono.a)
|
||||
|
||||
add_library(boost_date_time STATIC IMPORTED)
|
||||
set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_date_time.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_date_time.a)
|
||||
|
||||
add_library(boost_filesystem STATIC IMPORTED)
|
||||
set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_filesystem.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_filesystem.a)
|
||||
|
||||
add_library(boost_program_options STATIC IMPORTED)
|
||||
set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_program_options.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_program_options.a)
|
||||
|
||||
add_library(boost_regex STATIC IMPORTED)
|
||||
set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_regex.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_regex.a)
|
||||
|
||||
add_library(boost_serialization STATIC IMPORTED)
|
||||
set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_serialization.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_serialization.a)
|
||||
|
||||
add_library(boost_system STATIC IMPORTED)
|
||||
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_system.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_system.a)
|
||||
|
||||
add_library(boost_thread STATIC IMPORTED)
|
||||
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_thread.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_thread.a)
|
||||
|
||||
add_library(boost_wserialization STATIC IMPORTED)
|
||||
set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_wserialization.a)
|
||||
|
||||
#############
|
||||
# Monero
|
||||
@@ -73,79 +73,107 @@ set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
add_library(wallet_api STATIC IMPORTED)
|
||||
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet_api.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet_api.a)
|
||||
|
||||
add_library(wallet STATIC IMPORTED)
|
||||
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet.a)
|
||||
|
||||
add_library(cryptonote_core STATIC IMPORTED)
|
||||
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_core.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_core.a)
|
||||
|
||||
add_library(cryptonote_basic STATIC IMPORTED)
|
||||
set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_basic.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_basic.a)
|
||||
|
||||
add_library(mnemonics STATIC IMPORTED)
|
||||
set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmnemonics.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libmnemonics.a)
|
||||
|
||||
add_library(common STATIC IMPORTED)
|
||||
set_target_properties(common PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcommon.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcommon.a)
|
||||
|
||||
add_library(cncrypto STATIC IMPORTED)
|
||||
set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcncrypto.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcncrypto.a)
|
||||
|
||||
add_library(ringct STATIC IMPORTED)
|
||||
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libringct.a)
|
||||
|
||||
add_library(ringct_basic STATIC IMPORTED)
|
||||
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct_basic.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libringct_basic.a)
|
||||
|
||||
add_library(blockchain_db STATIC IMPORTED)
|
||||
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblockchain_db.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libblockchain_db.a)
|
||||
|
||||
add_library(lmdb STATIC IMPORTED)
|
||||
set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/liblmdb.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/liblmdb.a)
|
||||
|
||||
add_library(easylogging STATIC IMPORTED)
|
||||
set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libeasylogging.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libeasylogging.a)
|
||||
|
||||
add_library(unbound STATIC IMPORTED)
|
||||
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libunbound.a)
|
||||
|
||||
add_library(epee STATIC IMPORTED)
|
||||
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libepee.a)
|
||||
|
||||
add_library(blocks STATIC IMPORTED)
|
||||
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libblocks.a)
|
||||
|
||||
add_library(checkpoints STATIC IMPORTED)
|
||||
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcheckpoints.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcheckpoints.a)
|
||||
|
||||
add_library(device STATIC IMPORTED)
|
||||
set_target_properties(device PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libdevice.a)
|
||||
|
||||
add_library(device_trezor STATIC IMPORTED)
|
||||
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libdevice_trezor.a)
|
||||
|
||||
add_library(multisig STATIC IMPORTED)
|
||||
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmultisig.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libmultisig.a)
|
||||
|
||||
add_library(version STATIC IMPORTED)
|
||||
set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libversion.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libversion.a)
|
||||
|
||||
add_library(net STATIC IMPORTED)
|
||||
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libnet.a)
|
||||
|
||||
add_library(hardforks STATIC IMPORTED)
|
||||
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libhardforks.a)
|
||||
|
||||
add_library(randomx STATIC IMPORTED)
|
||||
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/librandomx.a)
|
||||
|
||||
add_library(rpc_base STATIC IMPORTED)
|
||||
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/librpc_base.a)
|
||||
|
||||
add_library(wallet-crypto STATIC IMPORTED)
|
||||
set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet-crypto.a)
|
||||
|
||||
add_library(cryptonote_format_utils_basic STATIC IMPORTED)
|
||||
set_target_properties(cryptonote_format_utils_basic PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_format_utils_basic.a)
|
||||
|
||||
#############
|
||||
# System
|
||||
@@ -153,19 +181,27 @@ set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
find_library( log-lib log )
|
||||
|
||||
include_directories( ${EXTERNAL_LIBS_DIR}/monero/include )
|
||||
include_directories( ${EXTERNAL_LIBS_DIR}/include )
|
||||
|
||||
message(STATUS EXTERNAL_LIBS_DIR : ${EXTERNAL_LIBS_DIR})
|
||||
|
||||
if(${ANDROID_ABI} STREQUAL "x86_64")
|
||||
set(EXTRA_LIBS "wallet-crypto")
|
||||
else()
|
||||
set(EXTRA_LIBS "")
|
||||
endif()
|
||||
|
||||
target_link_libraries( monerujo
|
||||
|
||||
wallet_api
|
||||
wallet
|
||||
cryptonote_core
|
||||
cryptonote_basic
|
||||
cryptonote_format_utils_basic
|
||||
mnemonics
|
||||
ringct
|
||||
ringct_basic
|
||||
net
|
||||
common
|
||||
cncrypto
|
||||
blockchain_db
|
||||
@@ -176,8 +212,13 @@ target_link_libraries( monerujo
|
||||
blocks
|
||||
checkpoints
|
||||
device
|
||||
device_trezor
|
||||
multisig
|
||||
version
|
||||
randomx
|
||||
hardforks
|
||||
rpc_base
|
||||
${EXTRA_LIBS}
|
||||
|
||||
boost_chrono
|
||||
boost_date_time
|
||||
|
@@ -1,16 +1,16 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion '28.0.3'
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion '30.0.3'
|
||||
ndkVersion '17.2.4988734'
|
||||
defaultConfig {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 28
|
||||
versionCode 173
|
||||
versionName "1.11.3 'Chernushka'"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
targetSdkVersion 31
|
||||
versionCode 1403
|
||||
versionName "2.4.3 'Baldaŭ'"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags "-std=c++11"
|
||||
@@ -18,6 +18,11 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
bundle {
|
||||
language {
|
||||
enableSplit = false
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions 'type', 'net'
|
||||
productFlavors {
|
||||
@@ -29,6 +34,11 @@ android {
|
||||
applicationIdSuffix '.stage'
|
||||
versionNameSuffix ' (stage)'
|
||||
}
|
||||
devnet {
|
||||
dimension 'net'
|
||||
applicationIdSuffix '.test'
|
||||
versionNameSuffix ' (test)'
|
||||
}
|
||||
alpha {
|
||||
dimension 'type'
|
||||
applicationIdSuffix '.alpha'
|
||||
@@ -47,6 +57,9 @@ android {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
variant.buildConfigField "String", "ID_A", "\"" + getId("ID_A") + "\""
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
@@ -71,7 +84,8 @@ android {
|
||||
def availableLocales = ["en"]
|
||||
new File("app/src/main/res/").eachFileMatch(~/^values-.*/) { file ->
|
||||
def languageTag = file.name.substring(7).replace("-r", "-")
|
||||
availableLocales.add(languageTag)
|
||||
if (languageTag != "night")
|
||||
availableLocales.add(languageTag)
|
||||
}
|
||||
|
||||
// APKs for the same app that all have the same version information.
|
||||
@@ -82,8 +96,7 @@ android {
|
||||
variant.outputs.all {
|
||||
output ->
|
||||
def abiName = output.getFilter(com.android.build.OutputFile.ABI)
|
||||
output.versionCodeOverride = abiCodes.get(abiName, 0) + 10 * variant.versionCode
|
||||
//def flavor = output.getFilter(flavor)
|
||||
output.versionCodeOverride = abiCodes.get(abiName, 0) + 10 * versionCode
|
||||
|
||||
if (abiName == null) abiName = "universal"
|
||||
def v = "${variant.versionName}".replaceFirst(" '.*' ?", "")
|
||||
@@ -93,36 +106,54 @@ android {
|
||||
outputFileName = "$rootProject.ext.apkName-" + v + "_" + abiName + ".apk"
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
namespace 'com.m2049r.xmrwallet'
|
||||
}
|
||||
|
||||
static def getId(name) {
|
||||
Properties props = new Properties()
|
||||
props.load(new FileInputStream(new File('monerujo.id')))
|
||||
return props[name]
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "com.android.support:appcompat-v7:$rootProject.ext.supportVersion"
|
||||
implementation "com.android.support:design:$rootProject.ext.supportVersion"
|
||||
implementation "com.android.support:support-v4:$rootProject.ext.supportVersion"
|
||||
implementation "com.android.support:recyclerview-v7:$rootProject.ext.supportVersion"
|
||||
implementation "com.android.support:cardview-v7:$rootProject.ext.supportVersion"
|
||||
implementation "com.android.support:swiperefreshlayout:$rootProject.ext.supportVersion"
|
||||
implementation 'androidx.core:core:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
|
||||
implementation 'com.google.android.material:material:1.6.0'
|
||||
|
||||
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||
implementation "com.squareup.okhttp3:okhttp:4.9.3"
|
||||
implementation "io.github.rburgst:okhttp-digest:2.6"
|
||||
implementation "com.jakewharton.timber:timber:5.0.1"
|
||||
|
||||
implementation "com.squareup.okhttp3:okhttp:$rootProject.ext.okHttpVersion"
|
||||
implementation "com.burgstaller:okhttp-digest:1.18"
|
||||
implementation "com.jakewharton.timber:timber:$rootProject.ext.timberVersion"
|
||||
implementation 'info.guardianproject.netcipher:netcipher:2.1.0'
|
||||
//implementation 'info.guardianproject.netcipher:netcipher-okhttp3:2.1.0'
|
||||
implementation fileTree(dir: 'libs/classes', include: ['*.jar'])
|
||||
implementation 'com.nulab-inc:zxcvbn:1.5.2'
|
||||
|
||||
implementation 'com.nulab-inc:zxcvbn:1.2.3'
|
||||
|
||||
implementation 'dnsjava:dnsjava:2.1.8'
|
||||
implementation 'org.jitsi:dnssecjava:1.1.3'
|
||||
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
||||
implementation 'dnsjava:dnsjava:2.1.9'
|
||||
implementation 'org.jitsi:dnssecjava:1.2.0'
|
||||
implementation 'org.slf4j:slf4j-nop:1.7.36'
|
||||
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
||||
|
||||
// https://mvnrepository.com/artifact/com.github.aelstad/keccakj
|
||||
implementation 'com.github.aelstad:keccakj:1.1.0'
|
||||
|
||||
|
||||
testImplementation "junit:junit:$rootProject.ext.junitVersion"
|
||||
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
||||
testImplementation "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
||||
testImplementation 'org.json:json:20180813'
|
||||
testImplementation 'net.jodah:concurrentunit:0.4.4'
|
||||
//noinspection GradleDependency
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation "org.mockito:mockito-all:1.10.19"
|
||||
testImplementation "com.squareup.okhttp3:mockwebserver:4.9.3"
|
||||
testImplementation 'org.json:json:20211205'
|
||||
testImplementation 'net.jodah:concurrentunit:0.4.6'
|
||||
|
||||
compileOnly 'org.projectlombok:lombok:1.18.22'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
||||
}
|
||||
|
@@ -1,57 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.m2049r.xmrwallet">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="org.torproject.android.intent.action.START" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="org.torproject.android.intent.action.STATUS" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="org.torproject.android.REQUEST_HS_PORT" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="org.torproject.android.REQUEST_V3_ONION_SERVICE" />
|
||||
</intent>
|
||||
|
||||
<package android:name="org.torproject.android" />
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:name=".XmrWalletApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:preserveLegacyExternalStorage="true"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/MyMaterialTheme"
|
||||
android:theme="@style/MyMaterialThemeClassic"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|uiMode"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".WalletActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:configChanges="orientation|keyboardHidden|uiMode"
|
||||
android:label="@string/wallet_activity_name"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="behind" />
|
||||
|
||||
<activity
|
||||
android:name=".LoginActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="locked">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<data android:scheme="monero" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<data android:scheme="bitcoin" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -62,6 +85,11 @@
|
||||
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||
android:resource="@xml/usb_device_filter" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".onboarding.OnBoardingActivity"
|
||||
android:configChanges="orientation|keyboardHidden|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<service
|
||||
android:name=".service.WalletService"
|
||||
@@ -70,7 +98,7 @@
|
||||
android:label="Monero Wallet Service" />
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
@@ -79,4 +107,5 @@
|
||||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@@ -1,88 +0,0 @@
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#if defined(HAVE_MONERUJO)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LedgerFind - find Ledger Device and return it's name
|
||||
* @param buffer - buffer for name of found device
|
||||
* @param len - length of buffer
|
||||
* @return 0 - success
|
||||
* -1 - no device connected / found
|
||||
* -2 - JVM not found
|
||||
*/
|
||||
int LedgerFind(char *buffer, size_t len);
|
||||
|
||||
/**
|
||||
* @brief LedgerExchange - exchange data with Ledger Device
|
||||
* @param command - buffer for data to send
|
||||
* @param cmd_len - length of send to send
|
||||
* @param response - buffer for received data
|
||||
* @param max_resp_len - size of receive buffer
|
||||
*
|
||||
* @return length of received data in response or -1 if error
|
||||
*/
|
||||
int LedgerExchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "device_io.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace hw {
|
||||
namespace io {
|
||||
class device_io_monerujo: device_io {
|
||||
public:
|
||||
device_io_monerujo() {};
|
||||
~device_io_monerujo() {};
|
||||
|
||||
void init() {};
|
||||
void release() {};
|
||||
|
||||
void connect(void *params) {};
|
||||
void disconnect() {};
|
||||
bool connected() const {return true;}; // monerujo is always connected before it gets here
|
||||
|
||||
// returns number of bytes read or -1 on error
|
||||
int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len) {
|
||||
return LedgerExchange(command, cmd_len, response, max_resp_len);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif //#if defined(HAVE_MONERUJO)
|
File diff suppressed because it is too large
Load Diff
@@ -54,6 +54,8 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern const char* const MONERO_VERSION; // the actual monero core version
|
||||
|
||||
// from monero-core crypto/hash-ops.h - avoid #including monero code here
|
||||
enum {
|
||||
HASH_SIZE = 32,
|
||||
|
@@ -46,8 +46,12 @@ public class BTChipTransportAndroidHID implements BTChipTransport {
|
||||
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
|
||||
for (UsbDevice device : deviceList.values()) {
|
||||
Timber.d("%04X:%04X %s, %s", device.getVendorId(), device.getProductId(), device.getManufacturerName(), device.getProductName());
|
||||
if ((device.getVendorId() == VID) && (device.getProductId() == PID_HID)) {
|
||||
return device;
|
||||
if (device.getVendorId() == VID) {
|
||||
final int deviceProductId = device.getProductId();
|
||||
for (int pid : PID_HIDS) {
|
||||
if (deviceProductId == pid)
|
||||
return device;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -74,7 +78,7 @@ public class BTChipTransportAndroidHID implements BTChipTransport {
|
||||
}
|
||||
|
||||
private static final int VID = 0x2C97;
|
||||
private static final int PID_HID = 0x0001;
|
||||
private static final int[] PID_HIDS = {0x0001, 0x0004, 0x0005};
|
||||
|
||||
private UsbDeviceConnection connection;
|
||||
private UsbInterface dongleInterface;
|
||||
|
@@ -77,7 +77,7 @@ public class Dispatcher implements PeerRetriever.OnGetPeers {
|
||||
final NodeInfo nodeInfo = retrievedPeer.getNodeInfo();
|
||||
Timber.d("Retrieved %s", nodeInfo);
|
||||
if ((nodeInfo.isValid() || nodeInfo.isFavourite())) {
|
||||
nodeInfo.setName();
|
||||
nodeInfo.setDefaultName();
|
||||
rpcNodes.add(nodeInfo);
|
||||
Timber.d("RPC: %s", nodeInfo);
|
||||
// the following is not totally correct but it works (otherwise we need to
|
||||
@@ -185,7 +185,6 @@ public class Dispatcher implements PeerRetriever.OnGetPeers {
|
||||
|
||||
public void seedPeers(Collection<NodeInfo> seedNodes) {
|
||||
for (NodeInfo node : seedNodes) {
|
||||
node.clear();
|
||||
if (node.isFavourite()) {
|
||||
rpcNodes.add(node);
|
||||
if (listener != null) listener.onGet(node);
|
||||
|
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* 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.levin.scanner;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 m2049r et al.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
@@ -11,15 +27,17 @@ import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.tech.Ndef;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||
import com.m2049r.xmrwallet.dialog.ProgressDialog;
|
||||
import com.m2049r.xmrwallet.fragment.send.SendFragment;
|
||||
@@ -30,7 +48,8 @@ import java.io.IOException;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class BaseActivity extends SecureActivity implements GenerateReviewFragment.ProgressListener {
|
||||
public class BaseActivity extends SecureActivity
|
||||
implements GenerateReviewFragment.ProgressListener, SubaddressFragment.ProgressListener {
|
||||
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
@@ -162,7 +181,7 @@ public class BaseActivity extends SecureActivity implements GenerateReviewFragme
|
||||
return;
|
||||
nfcPendingIntent = PendingIntent.getActivity(this, 0,
|
||||
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
|
||||
0);
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||
}
|
||||
|
||||
private void processNfcIntent(Intent intent) {
|
||||
@@ -197,7 +216,7 @@ public class BaseActivity extends SecureActivity implements GenerateReviewFragme
|
||||
if (uri == null) {
|
||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
BarcodeData bc = BarcodeData.fromQrCode(uri.toString());
|
||||
BarcodeData bc = BarcodeData.fromString(uri.toString());
|
||||
if (bc == null)
|
||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
39
app/src/main/java/com/m2049r/xmrwallet/MainActivity.java
Normal file
39
app/src/main/java/com/m2049r/xmrwallet/MainActivity.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 EarlOfEgo, 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;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.m2049r.xmrwallet.onboarding.OnBoardingActivity;
|
||||
import com.m2049r.xmrwallet.onboarding.OnBoardingManager;
|
||||
|
||||
public class MainActivity extends BaseActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (OnBoardingManager.shouldShowOnBoarding(getApplicationContext())) {
|
||||
startActivity(new Intent(this, OnBoardingActivity.class));
|
||||
} else {
|
||||
startActivity(new Intent(this, LoginActivity.class));
|
||||
}
|
||||
finish();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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;
|
||||
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
|
||||
public interface OnBlockUpdateListener {
|
||||
void onBlockUpdate(final Wallet wallet);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@ package com.m2049r.xmrwallet;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.Fragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -73,14 +73,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
// * On older devices continuously stopping and resuming camera preview can result in freezing the app.
|
||||
// * I don't know why this is the case but I don't have the time to figure out.
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(new
|
||||
|
||||
Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mScannerView.resumeCameraPreview(ScannerFragment.this);
|
||||
}
|
||||
}, 2000);
|
||||
handler.postDelayed(() -> mScannerView.resumeCameraPreview(ScannerFragment.this), 2000);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -17,12 +17,18 @@
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.LocaleHelper;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams;
|
||||
|
||||
public abstract class SecureActivity extends AppCompatActivity {
|
||||
@@ -30,14 +36,38 @@ public abstract class SecureActivity extends AppCompatActivity {
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||
if (!(BuildConfig.DEBUG && BuildConfig.FLAVOR_type.equals("alpha"))) {
|
||||
if (Helper.preventScreenshot()) {
|
||||
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context context) {
|
||||
super.attachBaseContext(LocaleHelper.setLocale(context, LocaleHelper.getLocale(context)));
|
||||
protected void attachBaseContext(Context newBase) {
|
||||
super.attachBaseContext(newBase);
|
||||
applyOverrideConfiguration(new Configuration());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyOverrideConfiguration(Configuration newConfig) {
|
||||
super.applyOverrideConfiguration(updateConfigurationIfSupported(newConfig));
|
||||
}
|
||||
|
||||
private Configuration updateConfigurationIfSupported(Configuration config) {
|
||||
// Configuration.getLocales is added after 24 and Configuration.locale is deprecated in 24
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (!config.getLocales().isEmpty()) {
|
||||
return config;
|
||||
}
|
||||
} else {
|
||||
if (config.locale != null) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
Locale locale = LocaleHelper.getPreferredLocale(this);
|
||||
if (locale != null) {
|
||||
config.setLocale(locale);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
125
app/src/main/java/com/m2049r/xmrwallet/SettingsFragment.java
Normal file
125
app/src/main/java/com/m2049r/xmrwallet/SettingsFragment.java
Normal file
@@ -0,0 +1,125 @@
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.StyleRes;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.m2049r.xmrwallet.dialog.AboutFragment;
|
||||
import com.m2049r.xmrwallet.dialog.CreditsFragment;
|
||||
import com.m2049r.xmrwallet.dialog.PrivacyFragment;
|
||||
import com.m2049r.xmrwallet.util.DayNightMode;
|
||||
import com.m2049r.xmrwallet.util.LocaleHelper;
|
||||
import com.m2049r.xmrwallet.util.NightmodeHelper;
|
||||
import com.m2049r.xmrwallet.util.ThemeHelper;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragmentCompat
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
setPreferencesFromResource(R.xml.root_preferences, rootKey);
|
||||
|
||||
findPreference(getString(R.string.about_info)).setOnPreferenceClickListener(preference -> {
|
||||
AboutFragment.display(getParentFragmentManager());
|
||||
return true;
|
||||
});
|
||||
findPreference(getString(R.string.privacy_info)).setOnPreferenceClickListener(preference -> {
|
||||
PrivacyFragment.display(getParentFragmentManager());
|
||||
return true;
|
||||
});
|
||||
findPreference(getString(R.string.credits_info)).setOnPreferenceClickListener(preference -> {
|
||||
CreditsFragment.display(getParentFragmentManager());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (key.equals(getString(R.string.preferred_locale))) {
|
||||
activity.recreate();
|
||||
} else if (key.equals(getString(R.string.preferred_nightmode))) {
|
||||
NightmodeHelper.setNightMode(DayNightMode.valueOf(sharedPreferences.getString(key, "AUTO")));
|
||||
} else if (key.equals(getString(R.string.preferred_theme))) {
|
||||
ThemeHelper.setTheme((Activity) activity, sharedPreferences.getString(key, "Classic"));
|
||||
activity.recreate();
|
||||
}
|
||||
}
|
||||
|
||||
private SettingsFragment.Listener activity;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof SettingsFragment.Listener) {
|
||||
activity = (SettingsFragment.Listener) context;
|
||||
} else {
|
||||
throw new ClassCastException(context + " must implement Listener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Timber.d("onResume()");
|
||||
activity.setSubtitle(getString(R.string.menu_settings));
|
||||
activity.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
populateLanguages();
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void setToolbarButton(int type);
|
||||
|
||||
void setSubtitle(String title);
|
||||
|
||||
void recreate();
|
||||
|
||||
void setTheme(@StyleRes final int resId);
|
||||
}
|
||||
|
||||
public void populateLanguages() {
|
||||
ListPreference language = findPreference(getString(R.string.preferred_locale));
|
||||
assert language != null;
|
||||
|
||||
final ArrayList<Locale> availableLocales = LocaleHelper.getAvailableLocales(requireContext());
|
||||
Collections.sort(availableLocales, (locale1, locale2) -> {
|
||||
String localeString1 = LocaleHelper.getDisplayName(locale1, true);
|
||||
String localeString2 = LocaleHelper.getDisplayName(locale2, true);
|
||||
return localeString1.compareTo(localeString2);
|
||||
});
|
||||
|
||||
String[] localeDisplayNames = new String[1 + availableLocales.size()];
|
||||
localeDisplayNames[0] = getString(R.string.language_system_default);
|
||||
for (int i = 1; i < localeDisplayNames.length; i++) {
|
||||
localeDisplayNames[i] = LocaleHelper.getDisplayName(availableLocales.get(i - 1), true);
|
||||
}
|
||||
language.setEntries(localeDisplayNames);
|
||||
|
||||
String[] languageTags = new String[1 + availableLocales.size()];
|
||||
languageTags[0] = "";
|
||||
for (int i = 1; i < languageTags.length; i++) {
|
||||
languageTags[i] = availableLocales.get(i - 1).toLanguageTag();
|
||||
}
|
||||
language.setEntryValues(languageTags);
|
||||
}
|
||||
}
|
241
app/src/main/java/com/m2049r/xmrwallet/SubaddressFragment.java
Normal file
241
app/src/main/java/com/m2049r/xmrwallet/SubaddressFragment.java
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2017 m2049r
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.m2049r.xmrwallet.data.Subaddress;
|
||||
import com.m2049r.xmrwallet.layout.SubaddressInfoAdapter;
|
||||
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class SubaddressFragment extends Fragment implements SubaddressInfoAdapter.OnInteractionListener,
|
||||
View.OnClickListener, OnBlockUpdateListener {
|
||||
static public final String KEY_MODE = "mode";
|
||||
static public final String MODE_MANAGER = "manager";
|
||||
|
||||
private SubaddressInfoAdapter adapter;
|
||||
|
||||
private Listener activityCallback;
|
||||
|
||||
private Wallet wallet;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface Listener {
|
||||
void onSubaddressSelected(Subaddress subaddress);
|
||||
|
||||
void setSubtitle(String title);
|
||||
|
||||
void setToolbarButton(int type);
|
||||
|
||||
void showSubaddress(View view, final int subaddressIndex);
|
||||
|
||||
void saveWallet();
|
||||
}
|
||||
|
||||
public interface ProgressListener {
|
||||
void showProgressDialog(int msgId);
|
||||
|
||||
void showLedgerProgressDialog(int mode);
|
||||
|
||||
void dismissProgressDialog();
|
||||
}
|
||||
|
||||
private ProgressListener progressCallback = null;
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof ProgressListener) {
|
||||
progressCallback = (ProgressListener) context;
|
||||
}
|
||||
if (context instanceof Listener) {
|
||||
activityCallback = (Listener) context;
|
||||
} else {
|
||||
throw new ClassCastException(context.toString()
|
||||
+ " must implement Listener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
Timber.d("onPause()");
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
activityCallback.setSubtitle(getString(R.string.subbaddress_title));
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
Timber.d("onCreateView");
|
||||
|
||||
final Bundle b = getArguments();
|
||||
managerMode = ((b != null) && (MODE_MANAGER.equals(b.getString(KEY_MODE))));
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_subaddress, container, false);
|
||||
view.findViewById(R.id.fab).setOnClickListener(this);
|
||||
|
||||
if (managerMode) {
|
||||
view.findViewById(R.id.tvInstruction).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.tvHint).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final RecyclerView list = view.findViewById(R.id.list);
|
||||
adapter = new SubaddressInfoAdapter(getActivity(), this);
|
||||
list.setAdapter(adapter);
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||
list.scrollToPosition(positionStart);
|
||||
}
|
||||
});
|
||||
|
||||
Helper.hideKeyboard(getActivity());
|
||||
|
||||
wallet = WalletManager.getInstance().getWallet();
|
||||
|
||||
loadList();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
public void loadList() {
|
||||
Timber.d("loadList()");
|
||||
final int numSubaddresses = wallet.getNumSubaddresses();
|
||||
final List<Subaddress> list = new ArrayList<>();
|
||||
for (int i = 0; i < numSubaddresses; i++) {
|
||||
list.add(wallet.getSubaddressObject(i));
|
||||
}
|
||||
adapter.setInfos(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockUpdate(Wallet wallet) {
|
||||
loadList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.fab) {
|
||||
getNewSubaddress();
|
||||
}
|
||||
}
|
||||
|
||||
private int lastUsedSubaddress() {
|
||||
int lastUsedSubaddress = 0;
|
||||
for (TransactionInfo info : wallet.getHistory().getAll()) {
|
||||
if (info.addressIndex > lastUsedSubaddress)
|
||||
lastUsedSubaddress = info.addressIndex;
|
||||
}
|
||||
return lastUsedSubaddress;
|
||||
}
|
||||
|
||||
private void getNewSubaddress() {
|
||||
final int maxSubaddresses = lastUsedSubaddress() + wallet.getDeviceType().getSubaddressLookahead();
|
||||
if (wallet.getNumSubaddresses() < maxSubaddresses)
|
||||
new AsyncSubaddress().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
Toast.makeText(getActivity(), getString(R.string.max_subaddress_warning), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
@RequiredArgsConstructor
|
||||
private class AsyncSubaddress extends AsyncTask<Void, Void, Boolean> {
|
||||
boolean dialogOpened = false;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
if ((wallet.getDeviceType() == Wallet.Device.Device_Ledger) && (progressCallback != null)) {
|
||||
progressCallback.showLedgerProgressDialog(LedgerProgressDialog.TYPE_SUBADDRESS);
|
||||
dialogOpened = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
if (params.length != 0) return false;
|
||||
wallet.getNewSubaddress();
|
||||
if (activityCallback != null) {
|
||||
activityCallback.saveWallet();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
super.onPostExecute(result);
|
||||
if (dialogOpened)
|
||||
progressCallback.dismissProgressDialog();
|
||||
if (!isAdded()) // never mind then
|
||||
return;
|
||||
loadList();
|
||||
}
|
||||
}
|
||||
|
||||
boolean managerMode = false;
|
||||
|
||||
// Callbacks from SubaddressInfoAdapter
|
||||
@Override
|
||||
public void onInteraction(final View view, final Subaddress subaddress) {
|
||||
if (managerMode)
|
||||
activityCallback.showSubaddress(view, subaddress.getAddressIndex());
|
||||
else
|
||||
activityCallback.onSubaddressSelected(subaddress); // also closes the fragment with onBackpressed()
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongInteraction(View view, Subaddress subaddress) {
|
||||
activityCallback.showSubaddress(view, subaddress.getAddressIndex());
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2017 m2049r
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.transition.Transition;
|
||||
import androidx.transition.TransitionInflater;
|
||||
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.m2049r.xmrwallet.data.Subaddress;
|
||||
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class SubaddressInfoFragment extends Fragment
|
||||
implements TransactionInfoAdapter.OnInteractionListener, OnBlockUpdateListener {
|
||||
private TransactionInfoAdapter adapter;
|
||||
|
||||
private Subaddress subaddress;
|
||||
|
||||
private TextInputLayout etName;
|
||||
private TextView tvAddress;
|
||||
private TextView tvTxLabel;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_subaddressinfo, container, false);
|
||||
|
||||
etName = view.findViewById(R.id.etName);
|
||||
tvAddress = view.findViewById(R.id.tvAddress);
|
||||
tvTxLabel = view.findViewById(R.id.tvTxLabel);
|
||||
|
||||
final RecyclerView list = view.findViewById(R.id.list);
|
||||
adapter = new TransactionInfoAdapter(getActivity(), this);
|
||||
list.setAdapter(adapter);
|
||||
|
||||
final Wallet wallet = activityCallback.getWallet();
|
||||
|
||||
Bundle b = getArguments();
|
||||
final int subaddressIndex = b.getInt("subaddressIndex");
|
||||
subaddress = wallet.getSubaddressObject(subaddressIndex);
|
||||
|
||||
etName.getEditText().setText(subaddress.getDisplayLabel());
|
||||
tvAddress.setText(getContext().getString(R.string.subbaddress_info_subtitle,
|
||||
subaddress.getAddressIndex(), subaddress.getSquashedAddress()));
|
||||
|
||||
etName.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
wallet.setSubaddressLabel(subaddressIndex, etName.getEditText().getText().toString());
|
||||
}
|
||||
});
|
||||
etName.getEditText().setOnEditorActionListener((v, actionId, event) -> {
|
||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|
||||
|| (actionId == EditorInfo.IME_ACTION_DONE)) {
|
||||
Helper.hideKeyboard(getActivity());
|
||||
wallet.setSubaddressLabel(subaddressIndex, etName.getEditText().getText().toString());
|
||||
onRefreshed(wallet);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
onRefreshed(wallet);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Transition transform = TransitionInflater.from(requireContext())
|
||||
.inflateTransition(R.transition.details);
|
||||
setSharedElementEnterTransition(transform);
|
||||
}
|
||||
|
||||
public void onRefreshed(final Wallet wallet) {
|
||||
Timber.d("onRefreshed");
|
||||
List<TransactionInfo> list = new ArrayList<>();
|
||||
for (TransactionInfo info : wallet.getHistory().getAll()) {
|
||||
if (info.addressIndex == subaddress.getAddressIndex())
|
||||
list.add(info);
|
||||
}
|
||||
adapter.setInfos(list);
|
||||
if (list.isEmpty())
|
||||
tvTxLabel.setText(R.string.subaddress_notx_label);
|
||||
else
|
||||
tvTxLabel.setText(R.string.subaddress_tx_label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockUpdate(Wallet wallet) {
|
||||
onRefreshed(wallet);
|
||||
}
|
||||
|
||||
// Callbacks from TransactionInfoAdapter
|
||||
@Override
|
||||
public void onInteraction(final View view, final TransactionInfo infoItem) {
|
||||
activityCallback.onTxDetailsRequest(view, infoItem);
|
||||
}
|
||||
|
||||
Listener activityCallback;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface Listener {
|
||||
void onTxDetailsRequest(View view, TransactionInfo info);
|
||||
|
||||
Wallet getWallet();
|
||||
|
||||
void setToolbarButton(int type);
|
||||
|
||||
void setTitle(String title, String subtitle);
|
||||
|
||||
void setSubtitle(String subtitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof Listener) {
|
||||
this.activityCallback = (Listener) context;
|
||||
} else {
|
||||
throw new ClassCastException(context.toString()
|
||||
+ " must implement Listener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Timber.d("onResume()");
|
||||
activityCallback.setSubtitle(getString(R.string.subbaddress_title));
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,36 +16,50 @@
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.m2049r.xmrwallet.model.NetworkType;
|
||||
import com.m2049r.xmrwallet.util.LocaleHelper;
|
||||
import com.m2049r.xmrwallet.util.NetCipherHelper;
|
||||
import com.m2049r.xmrwallet.util.NightmodeHelper;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class XmrWalletApplication extends Application {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
FragmentManager.enableNewStateManager(false);
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(new Timber.DebugTree());
|
||||
}
|
||||
|
||||
NightmodeHelper.setPreferredNightmode(this);
|
||||
|
||||
NetCipherHelper.createInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context context) {
|
||||
super.attachBaseContext(LocaleHelper.setLocale(context, LocaleHelper.getLocale(context)));
|
||||
super.attachBaseContext(LocaleHelper.setPreferredLocale(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration configuration) {
|
||||
public void onConfigurationChanged(@NonNull Configuration configuration) {
|
||||
super.onConfigurationChanged(configuration);
|
||||
LocaleHelper.updateSystemDefaultLocale(configuration.locale);
|
||||
LocaleHelper.setLocale(XmrWalletApplication.this, LocaleHelper.getLocale(XmrWalletApplication.this));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
LocaleHelper.updateSystemDefaultLocale(configuration.getLocales().get(0));
|
||||
} else {
|
||||
LocaleHelper.updateSystemDefaultLocale(configuration.locale);
|
||||
}
|
||||
LocaleHelper.setPreferredLocale(this);
|
||||
}
|
||||
|
||||
static public NetworkType getNetworkType() {
|
||||
@@ -54,7 +68,7 @@ public class XmrWalletApplication extends Application {
|
||||
return NetworkType.NetworkType_Mainnet;
|
||||
case "stagenet":
|
||||
return NetworkType.NetworkType_Stagenet;
|
||||
case "testnet":
|
||||
case "devnet": // flavors cannot start with "test"
|
||||
return NetworkType.NetworkType_Testnet;
|
||||
default:
|
||||
throw new IllegalStateException("unknown net flavor " + BuildConfig.FLAVOR_net);
|
||||
|
File diff suppressed because it is too large
Load Diff
89
app/src/main/java/com/m2049r/xmrwallet/data/Crypto.java
Normal file
89
app/src/main/java/com/m2049r/xmrwallet/data/Crypto.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package com.m2049r.xmrwallet.data;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.m2049r.xmrwallet.R;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.validator.BitcoinAddressType;
|
||||
import com.m2049r.xmrwallet.util.validator.BitcoinAddressValidator;
|
||||
import com.m2049r.xmrwallet.util.validator.EthAddressValidator;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum Crypto {
|
||||
XMR("XMR", true, "monero:tx_amount:recipient_name:tx_description", R.id.ibXMR, R.drawable.ic_monero, R.drawable.ic_monero_bw, Wallet::isAddressValid),
|
||||
BTC("BTC", true, "bitcoin:amount:label:message", R.id.ibBTC, R.drawable.ic_xmrto_btc, R.drawable.ic_xmrto_btc_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.BTC);
|
||||
}),
|
||||
DASH("DASH", true, "dash:amount:label:message", R.id.ibDASH, R.drawable.ic_xmrto_dash, R.drawable.ic_xmrto_dash_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.DASH);
|
||||
}),
|
||||
DOGE("DOGE", true, "dogecoin:amount:label:message", R.id.ibDOGE, R.drawable.ic_xmrto_doge, R.drawable.ic_xmrto_doge_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.DOGE);
|
||||
}),
|
||||
ETH("ETH", false, "ethereum:amount:label:message", R.id.ibETH, R.drawable.ic_xmrto_eth, R.drawable.ic_xmrto_eth_off, EthAddressValidator::validate),
|
||||
LTC("LTC", true, "litecoin:amount:label:message", R.id.ibLTC, R.drawable.ic_xmrto_ltc, R.drawable.ic_xmrto_ltc_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.LTC);
|
||||
});
|
||||
|
||||
@Getter
|
||||
@NonNull
|
||||
private final String symbol;
|
||||
@Getter
|
||||
private final boolean casefull;
|
||||
@NonNull
|
||||
private final String uriSpec;
|
||||
@Getter
|
||||
private final int buttonId;
|
||||
@Getter
|
||||
private final int iconEnabledId;
|
||||
@Getter
|
||||
private final int iconDisabledId;
|
||||
@NonNull
|
||||
private final Validator validator;
|
||||
|
||||
@Nullable
|
||||
public static Crypto withScheme(@NonNull String scheme) {
|
||||
for (Crypto crypto : values()) {
|
||||
if (crypto.getUriScheme().equals(scheme)) return crypto;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Crypto withSymbol(@NonNull String symbol) {
|
||||
final String upperSymbol = symbol.toUpperCase();
|
||||
for (Crypto crypto : values()) {
|
||||
if (crypto.symbol.equals(upperSymbol)) return crypto;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
interface Validator {
|
||||
boolean validate(String address);
|
||||
}
|
||||
|
||||
// TODO maybe cache these segments
|
||||
String getUriScheme() {
|
||||
return uriSpec.split(":")[0];
|
||||
}
|
||||
|
||||
String getUriAmount() {
|
||||
return uriSpec.split(":")[1];
|
||||
}
|
||||
|
||||
String getUriLabel() {
|
||||
return uriSpec.split(":")[2];
|
||||
}
|
||||
|
||||
String getUriMessage() {
|
||||
return uriSpec.split(":")[3];
|
||||
}
|
||||
|
||||
boolean validate(String address) {
|
||||
return validator.validate(address);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user