mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-03 08:23:04 +02:00
Compare commits
393 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3f09e73df7 | ||
![]() |
11b7e23ad2 | ||
![]() |
ae48027689 | ||
![]() |
a42f750fc4 | ||
![]() |
3406f585f2 | ||
![]() |
7546637c89 | ||
![]() |
4da2106f04 | ||
![]() |
93c11fb90e | ||
![]() |
9fa710f75b | ||
![]() |
c53dd300bc | ||
![]() |
97f40648be | ||
![]() |
1ece6bfbeb | ||
![]() |
4b3b99ff2a | ||
![]() |
ca833d7017 | ||
![]() |
f1b6f859de | ||
![]() |
61d19c7066 | ||
![]() |
ffda0e965b | ||
![]() |
cc7cdb383c | ||
![]() |
ac1ea05ef6 | ||
![]() |
1ddd4f30b9 | ||
![]() |
1dc081834f | ||
![]() |
ce084927e1 | ||
![]() |
3610781f43 | ||
![]() |
ef3ddbac71 | ||
![]() |
0512af1496 | ||
![]() |
bd2c49669a | ||
![]() |
ac7831d0f9 | ||
![]() |
0f0b9a38c7 | ||
![]() |
807db19603 | ||
![]() |
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 | ||
![]() |
6b7bb164f4 | ||
![]() |
da1d4ea1bf | ||
![]() |
d5a967f690 | ||
![]() |
de8de02f9f | ||
![]() |
06456e33e4 | ||
![]() |
d97b36aa44 | ||
![]() |
8fa06e5b37 | ||
![]() |
8d95de828b | ||
![]() |
93a7be0452 | ||
![]() |
25c8ec1229 | ||
![]() |
0bf0444dce | ||
![]() |
b74f9c6bd7 | ||
![]() |
f843bb1685 | ||
![]() |
7d9d49c29e | ||
![]() |
4ca9328949 | ||
![]() |
08b5a87f19 | ||
![]() |
445d8acc38 | ||
![]() |
9385ac8c31 | ||
![]() |
4c7ebd8402 | ||
![]() |
67f3c5f948 | ||
![]() |
cd67a7e2bf | ||
![]() |
fa5fe313ea | ||
![]() |
ed4957a3cc | ||
![]() |
3e0eeebd51 | ||
![]() |
0d213a1eb4 | ||
![]() |
39d048fd5e | ||
![]() |
1a5d2d0399 | ||
![]() |
028057a672 | ||
![]() |
909ff8ca5e | ||
![]() |
ffd61e4495 | ||
![]() |
003dee382e | ||
![]() |
be0498c67d | ||
![]() |
06227a4a83 | ||
![]() |
4409087bd0 | ||
![]() |
965e52d8a5 | ||
![]() |
beba0f497b | ||
![]() |
9d1827ff0d | ||
![]() |
c04b192753 | ||
![]() |
888b5edaec | ||
![]() |
5ee5a81926 | ||
![]() |
c4e361a873 | ||
![]() |
dba6cb057e | ||
![]() |
9e1167c5b9 | ||
![]() |
12546a1ade | ||
![]() |
e9313bc235 | ||
![]() |
7e9bf84640 | ||
![]() |
94f87a5193 | ||
![]() |
8a8fc5ec9e | ||
![]() |
036d4ebf6c | ||
![]() |
c6d4de8599 | ||
![]() |
2ef7f8571c | ||
![]() |
d2612a26e5 | ||
![]() |
7e14572756 | ||
![]() |
6f840dcacf | ||
![]() |
36b389cd0f | ||
![]() |
ed2b95ea37 | ||
![]() |
8d41d1d03e | ||
![]() |
e2e9da3437 | ||
![]() |
7cd07d1988 | ||
![]() |
f5ae0525e3 | ||
![]() |
b32ed8caf2 | ||
![]() |
e0c2bfc4c4 | ||
![]() |
2986dfeaa7 | ||
![]() |
acb7398dca | ||
![]() |
c8322f5a83 | ||
![]() |
973472e0ef | ||
![]() |
2dad55e498 | ||
![]() |
8e82bd4cc8 | ||
![]() |
38a825d580 | ||
![]() |
be04185481 | ||
![]() |
5bfb920979 | ||
![]() |
29583fa40d | ||
![]() |
dc86f0469e | ||
![]() |
9e48f2bdcb | ||
![]() |
b71c260323 | ||
![]() |
46dbc0659b | ||
![]() |
85622b3958 | ||
![]() |
5a63481c09 | ||
![]() |
1cb558d78e | ||
![]() |
942c80e38b | ||
![]() |
24ec848f0f | ||
![]() |
0d1b1da5f3 | ||
![]() |
0840d2f350 | ||
![]() |
c7d933ea9d | ||
![]() |
c9b1800309 | ||
![]() |
e7b0b5999e | ||
![]() |
47e1871693 | ||
![]() |
900eab70c8 | ||
![]() |
b11357f379 | ||
![]() |
eba0156a6d | ||
![]() |
bf64d8bd89 | ||
![]() |
2d74281b31 | ||
![]() |
668cefb357 | ||
![]() |
1f5061df38 | ||
![]() |
51445f5941 | ||
![]() |
8c01ec36e8 | ||
![]() |
3cf84c599d | ||
![]() |
ead8564688 | ||
![]() |
b71b3badd8 | ||
![]() |
5ad46e2f54 | ||
![]() |
9d6895b60f |
@@ -3,7 +3,7 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/code
|
||||
docker:
|
||||
- image: bitriseio/android-ndk
|
||||
- image: cimg/android:2022.03-ndk
|
||||
environment:
|
||||
JVM_OPTS: -Xmx3200m
|
||||
steps:
|
||||
|
9
.gitignore
vendored
9
.gitignore
vendored
@@ -6,4 +6,13 @@
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.DS_Store
|
||||
/app/build
|
||||
/app/release
|
||||
/app/alpha
|
||||
/app/prod
|
||||
/app/alphaMainnet
|
||||
/app/prodMainnet
|
||||
/app/alphaStagenet
|
||||
/app/prodStagenet
|
||||
/app/.cxx
|
||||
/monerujo.id
|
||||
|
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
||||
workspace.xml
|
||||
markdown-*
|
||||
misc.xml
|
1
.idea/.name
generated
1
.idea/.name
generated
@@ -1 +0,0 @@
|
||||
xmrwallet
|
22
.idea/compiler.xml
generated
22
.idea/compiler.xml
generated
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
3
.idea/copyright/profiles_settings.xml
generated
3
.idea/copyright/profiles_settings.xml
generated
@@ -1,3 +0,0 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
19
.idea/gradle.xml
generated
19
.idea/gradle.xml
generated
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="disableWrapperSourceDistributionNotification" value="true" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
9
.idea/modules.xml
generated
9
.idea/modules.xml
generated
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/xmrwallet.iml" filepath="$PROJECT_DIR$/xmrwallet.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
12
.idea/runConfigurations.xml
generated
12
.idea/runConfigurations.xml
generated
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
3
app/.gitignore
vendored
3
app/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
.externalNativeBuild
|
||||
build
|
||||
app.iml
|
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
project(monerujo)
|
||||
message(STATUS ABI_INFO = ${ANDROID_ABI})
|
||||
|
||||
add_library( monerujo
|
||||
@@ -13,7 +14,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 +22,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 +34,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 +74,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}/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 +182,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 +213,13 @@ target_link_libraries( monerujo
|
||||
blocks
|
||||
checkpoints
|
||||
device
|
||||
device_trezor
|
||||
multisig
|
||||
version
|
||||
randomx
|
||||
hardforks
|
||||
rpc_base
|
||||
${EXTRA_LIBS}
|
||||
|
||||
boost_chrono
|
||||
boost_date_time
|
||||
|
110
app/build.gradle
110
app/build.gradle
@@ -1,15 +1,16 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion '28.0.2'
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion '33.0.2'
|
||||
ndkVersion '17.2.4988734'
|
||||
defaultConfig {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 27
|
||||
versionCode 131
|
||||
versionName "1.8.1 'Bullets And Octane-Pirates'"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
targetSdkVersion 31
|
||||
versionCode 3130
|
||||
versionName "3.1.3 'Fluorine Fermi'"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags "-std=c++11"
|
||||
@@ -17,14 +18,34 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
bundle {
|
||||
language {
|
||||
enableSplit = false
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "version"
|
||||
flavorDimensions 'type', 'net'
|
||||
productFlavors {
|
||||
mainnet {
|
||||
dimension 'net'
|
||||
}
|
||||
stagenet {
|
||||
dimension 'net'
|
||||
applicationIdSuffix '.stage'
|
||||
versionNameSuffix ' (stage)'
|
||||
}
|
||||
devnet {
|
||||
dimension 'net'
|
||||
applicationIdSuffix '.test'
|
||||
versionNameSuffix ' (test)'
|
||||
}
|
||||
alpha {
|
||||
applicationIdSuffix ".alpha"
|
||||
versionNameSuffix " (alpha)"
|
||||
dimension 'type'
|
||||
applicationIdSuffix '.alpha'
|
||||
versionNameSuffix ' (alpha)'
|
||||
}
|
||||
prod {
|
||||
dimension 'type'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +57,9 @@ android {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
variant.buildConfigField "String", "ID_A", "\"" + getId("ID_A") + "\""
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
@@ -48,7 +72,7 @@ android {
|
||||
abi {
|
||||
enable true
|
||||
reset()
|
||||
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
include 'armeabi-v7a', 'arm64-v8a', 'x86_64'
|
||||
universalApk true
|
||||
}
|
||||
}
|
||||
@@ -60,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.
|
||||
@@ -71,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(" '.*' ?", "")
|
||||
@@ -82,28 +106,56 @@ 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(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
|
||||
|
||||
implementation 'androidx.core:core:1.10.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.0'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
|
||||
implementation 'com.google.android.material:material:1.8.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.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.9'
|
||||
implementation 'org.jitsi:dnssecjava:1.2.0'
|
||||
implementation 'org.slf4j:slf4j-nop:1.7.36'
|
||||
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
||||
|
||||
implementation 'dnsjava:dnsjava:2.1.8'
|
||||
implementation 'org.jitsi:dnssecjava:1.1.3'
|
||||
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
||||
//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'
|
||||
|
||||
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:20140107'
|
||||
testImplementation 'net.jodah:concurrentunit:0.4.2'
|
||||
compileOnly 'org.projectlombok:lombok:1.18.22'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
||||
}
|
||||
|
BIN
app/src/alpha/ic_launcher-web.png
Normal file
BIN
app/src/alpha/ic_launcher-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 244 KiB |
BIN
app/src/alpha/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
app/src/alpha/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.0 KiB |
BIN
app/src/alpha/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
app/src/alpha/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/alpha/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
app/src/alpha/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
app/src/alpha/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
app/src/alpha/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
app/src/alpha/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
app/src/alpha/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">monerujo - Debug</string>
|
||||
</resources>
|
@@ -1,53 +1,110 @@
|
||||
<?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_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<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=".WalletActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:label="@string/wallet_activity_name"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".LoginActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:label="@string/app_name"
|
||||
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|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.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" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
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"
|
||||
android:description="@string/service_description"
|
||||
android:exported="false"
|
||||
android:label="Monero Wallet Service" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@@ -43,6 +43,9 @@ Copyright (c) 2014 Dushyanth Maguluru
|
||||
<h3>AndroidLicensesPage (https://github.com/adamsp/AndroidLicensesPage)</h3>
|
||||
Copyright (c) 2013 Adam Speakman
|
||||
|
||||
<h3>SwipeableRecyclerView (https://github.com/brnunes/SwipeableRecyclerView)</h3>
|
||||
Copyright (c) 2015 Bruno R. Nunes
|
||||
|
||||
<h3>Apache License, Version 2.0, January 2004</h3>
|
||||
http://www.apache.org/licenses/<br/>
|
||||
<br/>
|
||||
|
@@ -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,20 +54,22 @@ 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,
|
||||
HASH_DATA_AREA = 136
|
||||
};
|
||||
|
||||
void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed);
|
||||
void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height);
|
||||
|
||||
inline void slow_hash(const void *data, const size_t length, char *hash) {
|
||||
cn_slow_hash(data, length, hash, 0 /* variant */, 0/*prehashed*/);
|
||||
cn_slow_hash(data, length, hash, 0 /*variant*/, 0 /*prehashed*/, 0 /*height*/);
|
||||
}
|
||||
|
||||
inline void slow_hash_broken(const void *data, char *hash, int variant) {
|
||||
cn_slow_hash(data, 200 /*sizeof(union hash_state)*/, hash, variant, 1 /*prehashed*/);
|
||||
cn_slow_hash(data, 200 /*sizeof(union hash_state)*/, hash, variant, 1 /*prehashed*/, 0 /*height*/);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -20,12 +20,10 @@
|
||||
|
||||
package com.btchip.comm;
|
||||
|
||||
import com.btchip.BTChipException;
|
||||
|
||||
public interface BTChipTransport {
|
||||
public byte[] exchange(byte[] command);
|
||||
byte[] exchange(byte[] command);
|
||||
|
||||
public void close();
|
||||
void close();
|
||||
|
||||
public void setDebug(boolean debugFlag);
|
||||
void setDebug(boolean debugFlag);
|
||||
}
|
||||
|
@@ -28,7 +28,6 @@ import android.hardware.usb.UsbInterface;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbRequest;
|
||||
|
||||
import com.btchip.BTChipException;
|
||||
import com.btchip.comm.BTChipTransport;
|
||||
import com.btchip.comm.LedgerHelper;
|
||||
import com.btchip.utils.Dump;
|
||||
@@ -46,8 +45,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 +77,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;
|
||||
|
145
app/src/main/java/com/m2049r/levin/data/Bucket.java
Normal file
145
app/src/main/java/com/m2049r/levin/data/Bucket.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.data;
|
||||
|
||||
import com.m2049r.levin.util.HexHelper;
|
||||
import com.m2049r.levin.util.LevinReader;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Bucket {
|
||||
|
||||
// constants copied from monero p2p & epee
|
||||
|
||||
public final static int P2P_COMMANDS_POOL_BASE = 1000;
|
||||
public final static int COMMAND_HANDSHAKE_ID = P2P_COMMANDS_POOL_BASE + 1;
|
||||
public final static int COMMAND_TIMED_SYNC_ID = P2P_COMMANDS_POOL_BASE + 2;
|
||||
public final static int COMMAND_PING_ID = P2P_COMMANDS_POOL_BASE + 3;
|
||||
public final static int COMMAND_REQUEST_STAT_INFO_ID = P2P_COMMANDS_POOL_BASE + 4;
|
||||
public final static int COMMAND_REQUEST_NETWORK_STATE_ID = P2P_COMMANDS_POOL_BASE + 5;
|
||||
public final static int COMMAND_REQUEST_PEER_ID_ID = P2P_COMMANDS_POOL_BASE + 6;
|
||||
public final static int COMMAND_REQUEST_SUPPORT_FLAGS_ID = P2P_COMMANDS_POOL_BASE + 7;
|
||||
|
||||
public final static long LEVIN_SIGNATURE = 0x0101010101012101L; // Bender's nightmare
|
||||
|
||||
public final static long LEVIN_DEFAULT_MAX_PACKET_SIZE = 100000000; // 100MB by default
|
||||
|
||||
public final static int LEVIN_PACKET_REQUEST = 0x00000001;
|
||||
public final static int LEVIN_PACKET_RESPONSE = 0x00000002;
|
||||
|
||||
public final static int LEVIN_PROTOCOL_VER_0 = 0;
|
||||
public final static int LEVIN_PROTOCOL_VER_1 = 1;
|
||||
|
||||
public final static int LEVIN_OK = 0;
|
||||
public final static int LEVIN_ERROR_CONNECTION = -1;
|
||||
public final static int LEVIN_ERROR_CONNECTION_NOT_FOUND = -2;
|
||||
public final static int LEVIN_ERROR_CONNECTION_DESTROYED = -3;
|
||||
public final static int LEVIN_ERROR_CONNECTION_TIMEDOUT = -4;
|
||||
public final static int LEVIN_ERROR_CONNECTION_NO_DUPLEX_PROTOCOL = -5;
|
||||
public final static int LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED = -6;
|
||||
public final static int LEVIN_ERROR_FORMAT = -7;
|
||||
|
||||
public final static int P2P_SUPPORT_FLAG_FLUFFY_BLOCKS = 0x01;
|
||||
public final static int P2P_SUPPORT_FLAGS = P2P_SUPPORT_FLAG_FLUFFY_BLOCKS;
|
||||
|
||||
final private long signature;
|
||||
final private long cb;
|
||||
final public boolean haveToReturnData;
|
||||
final public int command;
|
||||
final public int returnCode;
|
||||
final private int flags;
|
||||
final private int protcolVersion;
|
||||
final byte[] payload;
|
||||
|
||||
final public Section payloadSection;
|
||||
|
||||
// create a request
|
||||
public Bucket(int command, byte[] payload) throws IOException {
|
||||
this.signature = LEVIN_SIGNATURE;
|
||||
this.cb = payload.length;
|
||||
this.haveToReturnData = true;
|
||||
this.command = command;
|
||||
this.returnCode = 0;
|
||||
this.flags = LEVIN_PACKET_REQUEST;
|
||||
this.protcolVersion = LEVIN_PROTOCOL_VER_1;
|
||||
this.payload = payload;
|
||||
payloadSection = LevinReader.readPayload(payload);
|
||||
}
|
||||
|
||||
// create a response
|
||||
public Bucket(int command, byte[] payload, int rc) throws IOException {
|
||||
this.signature = LEVIN_SIGNATURE;
|
||||
this.cb = payload.length;
|
||||
this.haveToReturnData = false;
|
||||
this.command = command;
|
||||
this.returnCode = rc;
|
||||
this.flags = LEVIN_PACKET_RESPONSE;
|
||||
this.protcolVersion = LEVIN_PROTOCOL_VER_1;
|
||||
this.payload = payload;
|
||||
payloadSection = LevinReader.readPayload(payload);
|
||||
}
|
||||
|
||||
public Bucket(DataInput in) throws IOException {
|
||||
signature = in.readLong();
|
||||
cb = in.readLong();
|
||||
haveToReturnData = in.readBoolean();
|
||||
command = in.readInt();
|
||||
returnCode = in.readInt();
|
||||
flags = in.readInt();
|
||||
protcolVersion = in.readInt();
|
||||
|
||||
if (signature == Bucket.LEVIN_SIGNATURE) {
|
||||
if (cb > Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException();
|
||||
payload = new byte[(int) cb];
|
||||
in.readFully(payload);
|
||||
} else
|
||||
throw new IllegalStateException();
|
||||
payloadSection = LevinReader.readPayload(payload);
|
||||
}
|
||||
|
||||
public Section getPayloadSection() {
|
||||
return payloadSection;
|
||||
}
|
||||
|
||||
public void send(DataOutput out) throws IOException {
|
||||
out.writeLong(signature);
|
||||
out.writeLong(cb);
|
||||
out.writeBoolean(haveToReturnData);
|
||||
out.writeInt(command);
|
||||
out.writeInt(returnCode);
|
||||
out.writeInt(flags);
|
||||
out.writeInt(protcolVersion);
|
||||
out.write(payload);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("sig: ").append(signature).append("\n");
|
||||
sb.append("cb: ").append(cb).append("\n");
|
||||
sb.append("call: ").append(haveToReturnData).append("\n");
|
||||
sb.append("cmd: ").append(command).append("\n");
|
||||
sb.append("rc: ").append(returnCode).append("\n");
|
||||
sb.append("flags:").append(flags).append("\n");
|
||||
sb.append("proto:").append(protcolVersion).append("\n");
|
||||
sb.append(HexHelper.bytesToHex(payload)).append("\n");
|
||||
sb.append(payloadSection.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
125
app/src/main/java/com/m2049r/levin/data/Section.java
Normal file
125
app/src/main/java/com/m2049r/levin/data/Section.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.data;
|
||||
|
||||
import com.m2049r.levin.util.HexHelper;
|
||||
import com.m2049r.levin.util.LevinReader;
|
||||
import com.m2049r.levin.util.LevinWriter;
|
||||
import com.m2049r.levin.util.LittleEndianDataOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Section {
|
||||
|
||||
// constants copied from monero p2p & epee
|
||||
|
||||
static final public int PORTABLE_STORAGE_SIGNATUREA = 0x01011101;
|
||||
static final public int PORTABLE_STORAGE_SIGNATUREB = 0x01020101;
|
||||
|
||||
static final public byte PORTABLE_STORAGE_FORMAT_VER = 1;
|
||||
|
||||
static final public byte PORTABLE_RAW_SIZE_MARK_MASK = 0x03;
|
||||
static final public byte PORTABLE_RAW_SIZE_MARK_BYTE = 0;
|
||||
static final public byte PORTABLE_RAW_SIZE_MARK_WORD = 1;
|
||||
static final public byte PORTABLE_RAW_SIZE_MARK_DWORD = 2;
|
||||
static final public byte PORTABLE_RAW_SIZE_MARK_INT64 = 3;
|
||||
|
||||
static final long MAX_STRING_LEN_POSSIBLE = 2000000000; // do not let string be so big
|
||||
|
||||
// data types
|
||||
static final public byte SERIALIZE_TYPE_INT64 = 1;
|
||||
static final public byte SERIALIZE_TYPE_INT32 = 2;
|
||||
static final public byte SERIALIZE_TYPE_INT16 = 3;
|
||||
static final public byte SERIALIZE_TYPE_INT8 = 4;
|
||||
static final public byte SERIALIZE_TYPE_UINT64 = 5;
|
||||
static final public byte SERIALIZE_TYPE_UINT32 = 6;
|
||||
static final public byte SERIALIZE_TYPE_UINT16 = 7;
|
||||
static final public byte SERIALIZE_TYPE_UINT8 = 8;
|
||||
static final public byte SERIALIZE_TYPE_DUOBLE = 9;
|
||||
static final public byte SERIALIZE_TYPE_STRING = 10;
|
||||
static final public byte SERIALIZE_TYPE_BOOL = 11;
|
||||
static final public byte SERIALIZE_TYPE_OBJECT = 12;
|
||||
static final public byte SERIALIZE_TYPE_ARRAY = 13;
|
||||
|
||||
static final public byte SERIALIZE_FLAG_ARRAY = (byte) 0x80;
|
||||
|
||||
private final Map<String, Object> entries = new HashMap<String, Object>();
|
||||
|
||||
public void add(String key, Object entry) {
|
||||
entries.put(key, entry);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return entries.size();
|
||||
}
|
||||
|
||||
public Set<Map.Entry<String, Object>> entrySet() {
|
||||
return entries.entrySet();
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
return entries.get(key);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("\n");
|
||||
for (Map.Entry<String, Object> entry : entries.entrySet()) {
|
||||
sb.append(entry.getKey()).append("=");
|
||||
final Object value = entry.getValue();
|
||||
if (value instanceof List) {
|
||||
@SuppressWarnings("unchecked") final List<Object> list = (List<Object>) value;
|
||||
for (Object listEntry : list) {
|
||||
sb.append(listEntry.toString()).append("\n");
|
||||
}
|
||||
} else if (value instanceof String) {
|
||||
sb.append("(").append(value).append(")\n");
|
||||
} else if (value instanceof byte[]) {
|
||||
sb.append(HexHelper.bytesToHex((byte[]) value)).append("\n");
|
||||
} else {
|
||||
sb.append(value.toString()).append("\n");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static public Section fromByteArray(byte[] buffer) {
|
||||
try {
|
||||
return LevinReader.readPayload(buffer);
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] asByteArray() {
|
||||
try {
|
||||
ByteArrayOutputStream bas = new ByteArrayOutputStream();
|
||||
DataOutput out = new LittleEndianDataOutputStream(bas);
|
||||
LevinWriter writer = new LevinWriter(out);
|
||||
writer.writePayload(this);
|
||||
return bas.toByteArray();
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
195
app/src/main/java/com/m2049r/levin/scanner/Dispatcher.java
Normal file
195
app/src/main/java/com/m2049r/levin/scanner/Dispatcher.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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 com.m2049r.xmrwallet.data.NodeInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class Dispatcher implements PeerRetriever.OnGetPeers {
|
||||
static final public int NUM_THREADS = 50;
|
||||
static final public int MAX_PEERS = 1000;
|
||||
static final public long MAX_TIME = 30000000000L; //30 seconds
|
||||
|
||||
private int peerCount = 0;
|
||||
final private Set<NodeInfo> knownNodes = new HashSet<>(); // set of nodes to test
|
||||
final private Set<NodeInfo> rpcNodes = new HashSet<>(); // set of RPC nodes we like
|
||||
final private ExecutorService exeService = Executors.newFixedThreadPool(NUM_THREADS);
|
||||
|
||||
public interface Listener {
|
||||
void onGet(NodeInfo nodeInfo);
|
||||
}
|
||||
|
||||
private Listener listener;
|
||||
|
||||
public Dispatcher(Listener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public Set<NodeInfo> getRpcNodes() {
|
||||
return rpcNodes;
|
||||
}
|
||||
|
||||
public int getPeerCount() {
|
||||
return peerCount;
|
||||
}
|
||||
|
||||
public boolean getMorePeers() {
|
||||
return peerCount < MAX_PEERS;
|
||||
}
|
||||
|
||||
public void awaitTermination(int nodesToFind) {
|
||||
try {
|
||||
final long t = System.nanoTime();
|
||||
while (!jobs.isEmpty()) {
|
||||
try {
|
||||
Timber.d("Remaining jobs %d", jobs.size());
|
||||
final PeerRetriever retrievedPeer = jobs.poll().get();
|
||||
if (retrievedPeer.isGood() && getMorePeers())
|
||||
retrievePeers(retrievedPeer);
|
||||
final NodeInfo nodeInfo = retrievedPeer.getNodeInfo();
|
||||
Timber.d("Retrieved %s", nodeInfo);
|
||||
if ((nodeInfo.isValid() || nodeInfo.isFavourite())) {
|
||||
nodeInfo.setDefaultName();
|
||||
rpcNodes.add(nodeInfo);
|
||||
Timber.d("RPC: %s", nodeInfo);
|
||||
// the following is not totally correct but it works (otherwise we need to
|
||||
// load much more before filtering - but we don't have time
|
||||
if (listener != null) listener.onGet(nodeInfo);
|
||||
if (rpcNodes.size() >= nodesToFind) {
|
||||
Timber.d("are we done here?");
|
||||
filterRpcNodes();
|
||||
if (rpcNodes.size() >= nodesToFind) {
|
||||
Timber.d("we're done here");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (System.nanoTime() - t > MAX_TIME) break; // watchdog
|
||||
} catch (ExecutionException ex) {
|
||||
Timber.d(ex); // tell us about it and continue
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
Timber.d(ex);
|
||||
} finally {
|
||||
Timber.d("Shutting down!");
|
||||
exeService.shutdownNow();
|
||||
try {
|
||||
exeService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
||||
} catch (InterruptedException ex) {
|
||||
Timber.d(ex);
|
||||
}
|
||||
}
|
||||
filterRpcNodes();
|
||||
}
|
||||
|
||||
static final public int HEIGHT_WINDOW = 1;
|
||||
|
||||
private boolean testHeight(long height, long consensus) {
|
||||
return (height >= (consensus - HEIGHT_WINDOW))
|
||||
&& (height <= (consensus + HEIGHT_WINDOW));
|
||||
}
|
||||
|
||||
private long calcConsensusHeight() {
|
||||
Timber.d("Calc Consensus height from %d nodes", rpcNodes.size());
|
||||
final Map<Long, Integer> nodeHeights = new TreeMap<Long, Integer>();
|
||||
for (NodeInfo info : rpcNodes) {
|
||||
if (!info.isValid()) continue;
|
||||
Integer h = nodeHeights.get(info.getHeight());
|
||||
if (h == null)
|
||||
h = 0;
|
||||
nodeHeights.put(info.getHeight(), h + 1);
|
||||
}
|
||||
long consensusHeight = 0;
|
||||
long consensusCount = 0;
|
||||
for (Map.Entry<Long, Integer> entry : nodeHeights.entrySet()) {
|
||||
final long entryHeight = entry.getKey();
|
||||
int count = 0;
|
||||
for (long i = entryHeight - HEIGHT_WINDOW; i <= entryHeight + HEIGHT_WINDOW; i++) {
|
||||
Integer v = nodeHeights.get(i);
|
||||
if (v == null)
|
||||
v = 0;
|
||||
count += v;
|
||||
}
|
||||
if (count >= consensusCount) {
|
||||
consensusCount = count;
|
||||
consensusHeight = entryHeight;
|
||||
}
|
||||
Timber.d("%d - %d/%d", entryHeight, count, entry.getValue());
|
||||
}
|
||||
return consensusHeight;
|
||||
}
|
||||
|
||||
private void filterRpcNodes() {
|
||||
long consensus = calcConsensusHeight();
|
||||
Timber.d("Consensus Height = %d for %d nodes", consensus, rpcNodes.size());
|
||||
for (Iterator<NodeInfo> iter = rpcNodes.iterator(); iter.hasNext(); ) {
|
||||
NodeInfo info = iter.next();
|
||||
// don't remove favourites
|
||||
if (!info.isFavourite()) {
|
||||
if (!testHeight(info.getHeight(), consensus)) {
|
||||
iter.remove();
|
||||
Timber.d("Removed %s", info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: does this NEED to be a ConcurrentLinkedDeque?
|
||||
private ConcurrentLinkedDeque<Future<PeerRetriever>> jobs = new ConcurrentLinkedDeque<>();
|
||||
|
||||
private void retrievePeer(NodeInfo nodeInfo) {
|
||||
if (knownNodes.add(nodeInfo)) {
|
||||
Timber.d("\t%d:%s", knownNodes.size(), nodeInfo);
|
||||
jobs.add(exeService.submit(new PeerRetriever(nodeInfo, this)));
|
||||
peerCount++; // jobs.size() does not perform well
|
||||
}
|
||||
}
|
||||
|
||||
private void retrievePeers(PeerRetriever peer) {
|
||||
for (LevinPeer levinPeer : peer.getPeers()) {
|
||||
if (getMorePeers())
|
||||
retrievePeer(new NodeInfo(levinPeer));
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void seedPeers(Collection<NodeInfo> seedNodes) {
|
||||
for (NodeInfo node : seedNodes) {
|
||||
if (node.isFavourite()) {
|
||||
rpcNodes.add(node);
|
||||
if (listener != null) listener.onGet(node);
|
||||
}
|
||||
retrievePeer(node);
|
||||
}
|
||||
}
|
||||
}
|
39
app/src/main/java/com/m2049r/levin/scanner/LevinPeer.java
Normal file
39
app/src/main/java/com/m2049r/levin/scanner/LevinPeer.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class LevinPeer {
|
||||
final public InetSocketAddress socketAddress;
|
||||
final public int version;
|
||||
final public long height;
|
||||
final public String top;
|
||||
|
||||
|
||||
public InetSocketAddress getSocketAddress() {
|
||||
return socketAddress;
|
||||
}
|
||||
|
||||
LevinPeer(InetAddress address, int port, int version, long height, String top) {
|
||||
this.socketAddress = new InetSocketAddress(address, port);
|
||||
this.version = version;
|
||||
this.height = height;
|
||||
this.top = top;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user