mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-06 02:27:11 +02:00
Compare commits
92 Commits
v1.1.2-alp
...
v1.4.5
Author | SHA1 | Date | |
---|---|---|---|
![]() |
df2ff8b3b7 | ||
![]() |
da8c8f80f1 | ||
![]() |
eda3de11fe | ||
![]() |
7d7de14827 | ||
![]() |
1c709da92c | ||
![]() |
a9092497b2 | ||
![]() |
b1f530e64a | ||
![]() |
8c086b77d3 | ||
![]() |
c0fdfe87be | ||
![]() |
6cfd840283 | ||
![]() |
d80cde1136 | ||
![]() |
bea4b06675 | ||
![]() |
88bc33b5a4 | ||
![]() |
2db36bb824 | ||
![]() |
dd689b1883 | ||
![]() |
641abd13f5 | ||
![]() |
a0b3a7fe5d | ||
![]() |
a0486f581f | ||
![]() |
36161137ec | ||
![]() |
c9927edbd1 | ||
![]() |
f0a3c05a9a | ||
![]() |
d6eb82c457 | ||
![]() |
7f47307307 | ||
![]() |
165dd3dfd1 | ||
![]() |
171727c9db | ||
![]() |
1492814ec9 | ||
![]() |
9b1225fe4b | ||
![]() |
595d88e42e | ||
![]() |
0e207d7401 | ||
![]() |
5920d6c9e8 | ||
![]() |
44fd3c10fa | ||
![]() |
91ab8a681c | ||
![]() |
d843bdb451 | ||
![]() |
2884fc711c | ||
![]() |
8ea2081270 | ||
![]() |
2296329962 | ||
![]() |
fc1bff2160 | ||
![]() |
e61c2b616e | ||
![]() |
ea1e8ac2c3 | ||
![]() |
1082175089 | ||
![]() |
90d64089a6 | ||
![]() |
b689628975 | ||
![]() |
f8e701aa07 | ||
![]() |
d855328c52 | ||
![]() |
bafe05117b | ||
![]() |
4b7c181040 | ||
![]() |
a3721ae784 | ||
![]() |
ae62c528aa | ||
![]() |
e6522769d0 | ||
![]() |
cab93e8c5e | ||
![]() |
ac78ecb298 | ||
![]() |
51876f788f | ||
![]() |
82c32d4442 | ||
![]() |
22b4905828 | ||
![]() |
0cb8ece336 | ||
![]() |
d2429da044 | ||
![]() |
92d867fbaa | ||
![]() |
a5e3986eb9 | ||
![]() |
8f7f4ee9f9 | ||
![]() |
c23597066a | ||
![]() |
dab5e08910 | ||
![]() |
c35deab283 | ||
![]() |
7c36ccfd9c | ||
![]() |
402d51ec6e | ||
![]() |
ca58211676 | ||
![]() |
97c6ba5334 | ||
![]() |
f1f2f250be | ||
![]() |
7b19e9a2bd | ||
![]() |
ed8010c92c | ||
![]() |
41580e5519 | ||
![]() |
1875e2df62 | ||
![]() |
347123d961 | ||
![]() |
f5ad07c2b0 | ||
![]() |
62695af9c6 | ||
![]() |
3b1c3d564b | ||
![]() |
b28a140b48 | ||
![]() |
75bba4a091 | ||
![]() |
cfb3c23003 | ||
![]() |
2cb87bab8e | ||
![]() |
1ddc3d6b58 | ||
![]() |
2fa48d7441 | ||
![]() |
545367db90 | ||
![]() |
d67e02cbcb | ||
![]() |
d3beb7ca3f | ||
![]() |
f951e1a621 | ||
![]() |
0e187d3b20 | ||
![]() |
716b830b7b | ||
![]() |
4ac6a03d63 | ||
![]() |
7eb86ea618 | ||
![]() |
4cfd166ed7 | ||
![]() |
44f241f4ee | ||
![]() |
62b77fc987 |
27
.circleci/config.yml
Normal file
27
.circleci/config.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
version: 2
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
working_directory: ~/code
|
||||||
|
docker:
|
||||||
|
- image: bitriseio/android-ndk
|
||||||
|
environment:
|
||||||
|
JVM_OPTS: -Xmx3200m
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- restore_cache:
|
||||||
|
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
|
||||||
|
- run:
|
||||||
|
name: Download Dependencies
|
||||||
|
command: ./gradlew androidDependencies
|
||||||
|
- save_cache:
|
||||||
|
paths:
|
||||||
|
- ~/.gradle
|
||||||
|
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
|
||||||
|
- run:
|
||||||
|
name: Run Tests
|
||||||
|
command: ./gradlew test
|
||||||
|
- store_artifacts:
|
||||||
|
path: app/build/reports
|
||||||
|
destination: reports
|
||||||
|
- store_test_results:
|
||||||
|
path: app/build/test-results
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@
|
|||||||
/captures
|
/captures
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/app/release
|
||||||
|
12
README.md
12
README.md
@@ -11,23 +11,19 @@ Another Android Monero Wallet
|
|||||||
You may lose all your Moneroj if you use this App. Be cautious when spending on the mainnet.
|
You may lose all your Moneroj if you use this App. Be cautious when spending on the mainnet.
|
||||||
|
|
||||||
### Random Notes
|
### Random Notes
|
||||||
- Based off monero v0.11.0.0 with PR #2289 applied
|
- Based off monero v0.11.1.0
|
||||||
- currently only android32 (runs on 64-bit as well)
|
- currently only android32 (runs on 64-bit as well)
|
||||||
- works on the testnet & mainnet
|
- works on the testnet & mainnet
|
||||||
- sync is slow due to 32-bit architecture
|
- sync is slow due to 32-bit architecture
|
||||||
- use your own daemon - it's easy
|
- use your own daemon - it's easy
|
||||||
- screen stays on until first sync is complete
|
- screen stays on until first sync is complete
|
||||||
- saves wallet only on first sync and when sending transactions or editing notes
|
|
||||||
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
|
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- review visibility of methods/classes
|
- see taiga.getmonero.org & issues on github
|
||||||
- more sensible error dialogs
|
|
||||||
|
|
||||||
### Issues / Pitfalls
|
### Issues / Pitfalls
|
||||||
- The backups folder is now called "backups" and not ".backups" - which in most file explorers was a hidden folder
|
- You should backup your wallet files in the "monerujo" folder periodically.
|
||||||
- Wallets are now created directly in the "monerujo" folder, and not in the ".new" folder as before
|
|
||||||
- You may want to check the old folders with a file browsing app and delete the ".new" and ".backups" folders AFTER moving neccessary wallet files to the new locations. Or simply make new backups from within Monerujo.
|
|
||||||
- Also note, that on some devices the backups will only be visible on a PC over USB after a reboot of the device (it's an Android bug/feature)
|
- Also note, that on some devices the backups will only be visible on a PC over USB after a reboot of the device (it's an Android bug/feature)
|
||||||
- Created wallets on a private testnet are unusable because the restore height is set to that
|
- Created wallets on a private testnet are unusable because the restore height is set to that
|
||||||
of the "real" testnet. After creating a new wallet, make a **new** one by recovering from the seed.
|
of the "real" testnet. After creating a new wallet, make a **new** one by recovering from the seed.
|
||||||
@@ -37,7 +33,7 @@ The official monero client shows the same behaviour.
|
|||||||
No need to build. Binaries are included:
|
No need to build. Binaries are included:
|
||||||
|
|
||||||
- openssl-1.0.2l
|
- openssl-1.0.2l
|
||||||
- monero-v0.11.0.0 + pull requests #2289
|
- monero-v0.11.1.0
|
||||||
- boost_1_64_0
|
- boost_1_64_0
|
||||||
|
|
||||||
If you want to build them yourself (recommended) check out [the instructions](doc/BUILDING-external-libs.md)
|
If you want to build them yourself (recommended) check out [the instructions](doc/BUILDING-external-libs.md)
|
||||||
|
@@ -60,9 +60,13 @@ set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
|||||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
|
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# Monero set(libs_to_merge wallet cryptonote_core cryptonote_basic mnemonics common cncrypto ringct)
|
# Monero
|
||||||
#############
|
#############
|
||||||
|
|
||||||
|
add_library(wallet_api STATIC IMPORTED)
|
||||||
|
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet_api.a)
|
||||||
|
|
||||||
add_library(wallet STATIC IMPORTED)
|
add_library(wallet STATIC IMPORTED)
|
||||||
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
|
||||||
@@ -91,11 +95,9 @@ add_library(ringct STATIC IMPORTED)
|
|||||||
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
|
||||||
|
|
||||||
#####
|
add_library(ringct_basic STATIC IMPORTED)
|
||||||
|
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
|
||||||
add_library(p2p STATIC IMPORTED)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct_basic.a)
|
||||||
set_target_properties(p2p PROPERTIES IMPORTED_LOCATION
|
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libp2p.a)
|
|
||||||
|
|
||||||
add_library(blockchain_db STATIC IMPORTED)
|
add_library(blockchain_db STATIC IMPORTED)
|
||||||
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
||||||
@@ -113,7 +115,6 @@ add_library(unbound STATIC IMPORTED)
|
|||||||
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
|
||||||
|
|
||||||
####
|
|
||||||
add_library(epee STATIC IMPORTED)
|
add_library(epee STATIC IMPORTED)
|
||||||
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
|
||||||
@@ -122,9 +123,21 @@ add_library(blocks STATIC IMPORTED)
|
|||||||
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
|
||||||
|
|
||||||
add_library(miniupnpc STATIC IMPORTED)
|
add_library(checkpoints STATIC IMPORTED)
|
||||||
set_target_properties(miniupnpc PROPERTIES IMPORTED_LOCATION
|
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libminiupnpc.a)
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcheckpoints.a)
|
||||||
|
|
||||||
|
add_library(device STATIC IMPORTED)
|
||||||
|
set_target_properties(device PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice.a)
|
||||||
|
|
||||||
|
add_library(multisig STATIC IMPORTED)
|
||||||
|
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmultisig.a)
|
||||||
|
|
||||||
|
add_library(version STATIC IMPORTED)
|
||||||
|
set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libversion.a)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# System
|
# System
|
||||||
@@ -137,23 +150,26 @@ include_directories( ${EXTERNAL_LIBS_DIR}/monero/include )
|
|||||||
message(STATUS EXTERNAL_LIBS_DIR : ${EXTERNAL_LIBS_DIR})
|
message(STATUS EXTERNAL_LIBS_DIR : ${EXTERNAL_LIBS_DIR})
|
||||||
|
|
||||||
target_link_libraries( monerujo
|
target_link_libraries( monerujo
|
||||||
|
|
||||||
|
wallet_api
|
||||||
wallet
|
wallet
|
||||||
cryptonote_core
|
cryptonote_core
|
||||||
cryptonote_basic
|
cryptonote_basic
|
||||||
mnemonics
|
mnemonics
|
||||||
ringct
|
ringct
|
||||||
|
ringct_basic
|
||||||
common
|
common
|
||||||
cncrypto
|
cncrypto
|
||||||
|
|
||||||
blockchain_db
|
blockchain_db
|
||||||
lmdb
|
lmdb
|
||||||
easylogging
|
easylogging
|
||||||
unbound
|
unbound
|
||||||
p2p
|
|
||||||
|
|
||||||
epee
|
epee
|
||||||
blocks
|
blocks
|
||||||
miniupnpc
|
checkpoints
|
||||||
|
device
|
||||||
|
multisig
|
||||||
|
version
|
||||||
|
|
||||||
boost_chrono
|
boost_chrono
|
||||||
boost_date_time
|
boost_date_time
|
||||||
|
@@ -8,8 +8,8 @@ android {
|
|||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 29
|
versionCode 85
|
||||||
versionName "1.1.2-alpha"
|
versionName "1.4.5 'Monero Spedner'"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
@@ -18,7 +18,7 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters 'armeabi-v7a'
|
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,12 +27,37 @@ android {
|
|||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
path "CMakeLists.txt"
|
path "CMakeLists.txt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
splits {
|
||||||
|
abi {
|
||||||
|
enable true
|
||||||
|
reset()
|
||||||
|
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||||
|
universalApk true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map for the version code that gives each ABI a value.
|
||||||
|
def abiCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2, 'x86': 3, 'x86_64': 4]
|
||||||
|
|
||||||
|
// APKs for the same app that all have the same version information.
|
||||||
|
android.applicationVariants.all { variant ->
|
||||||
|
// Assigns a different version code for each output APK.
|
||||||
|
variant.outputs.each {
|
||||||
|
output ->
|
||||||
|
def abiName = output.getFilter(com.android.build.OutputFile.ABI)
|
||||||
|
output.versionCodeOverride = abiCodes.get(abiName, 0) + 10 * variant.versionCode
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -43,28 +68,43 @@ dependencies {
|
|||||||
compile 'com.android.support:cardview-v7:25.4.0'
|
compile 'com.android.support:cardview-v7:25.4.0'
|
||||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
compile 'me.dm7.barcodescanner:zxing:1.9.8'
|
compile 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||||
|
|
||||||
|
compile "com.squareup.okhttp3:okhttp:$rootProject.ext.okHttpVersion"
|
||||||
|
compile "com.jakewharton.timber:timber:$rootProject.ext.timberVersion"
|
||||||
|
|
||||||
|
compile 'com.nulab-inc:zxcvbn:1.2.3'
|
||||||
|
|
||||||
|
testCompile "junit:junit:$rootProject.ext.junitVersion"
|
||||||
|
testCompile "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
||||||
|
testCompile "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
||||||
|
testCompile 'org.json:json:20140107'
|
||||||
|
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyVerification {
|
dependencyVerification {
|
||||||
verify = [
|
verify = [
|
||||||
'com.android.support:appcompat-v7:70551e62660db15b790c5275f56b9de4dd9407d1494d07c8f3dd5698f3638677',
|
|
||||||
'com.android.support:design:3f409bf2019967ffc344cfaf11e52131fac982468a1707aaeb25bf3c52838966',
|
'com.android.support:design:3f409bf2019967ffc344cfaf11e52131fac982468a1707aaeb25bf3c52838966',
|
||||||
|
'com.android.support:appcompat-v7:70551e62660db15b790c5275f56b9de4dd9407d1494d07c8f3dd5698f3638677',
|
||||||
|
'com.android.support:transition:848270144fb180efd2bf928a00ed176dbbc5290badfd638390ffba90088df8b3',
|
||||||
|
'me.dm7.barcodescanner:zxing:d43973c9527c23fa8e6d338c6a2c458e373ce1ac6bcaa3bc41d11ae49116000d',
|
||||||
|
'me.dm7.barcodescanner:core:a5c8a704089b58029db166172ed8e55d756877d010a85a0b1c94fdc96ffb8f9a',
|
||||||
'com.android.support:support-v4:ee44c481a1f4d6978568e223e8125379b52b2ececdd53450e09ebae144bd377d',
|
'com.android.support:support-v4:ee44c481a1f4d6978568e223e8125379b52b2ececdd53450e09ebae144bd377d',
|
||||||
'com.android.support:recyclerview-v7:a2fe121f9d01ed8980e97095b4a3fe9700a0aa0a7d4b0f8c594f765ad8455a0d',
|
'com.android.support:recyclerview-v7:a2fe121f9d01ed8980e97095b4a3fe9700a0aa0a7d4b0f8c594f765ad8455a0d',
|
||||||
'com.android.support:cardview-v7:f3fbbe1fcfdbec7333c6a2c516c5fd511a909d1975271818e268d6fe297d8c70',
|
'com.android.support:cardview-v7:f3fbbe1fcfdbec7333c6a2c516c5fd511a909d1975271818e268d6fe297d8c70',
|
||||||
'com.android.support.constraint:constraint-layout:b0c688cc2b7172608f8153a689d746da40f71e52d7e2fe2bfd9df2f92db77085',
|
'com.android.support.constraint:constraint-layout:b0c688cc2b7172608f8153a689d746da40f71e52d7e2fe2bfd9df2f92db77085',
|
||||||
'me.dm7.barcodescanner:zxing:d43973c9527c23fa8e6d338c6a2c458e373ce1ac6bcaa3bc41d11ae49116000d',
|
|
||||||
'com.android.support:support-annotations:a774272036941b4e912eb426d70c848bde7f06a3bf5fb491f75a427dc6595270',
|
|
||||||
'com.android.support:support-vector-drawable:077009d13882ee96f061e4bc2dbe7cce7ae1762d8297592a787ff741afbfb1f2',
|
|
||||||
'com.android.support:animated-vector-drawable:628ab1d56a6ee4cbedf32617af8b2a1fe02964ed0628e8f898cc09ddba6e1835',
|
'com.android.support:animated-vector-drawable:628ab1d56a6ee4cbedf32617af8b2a1fe02964ed0628e8f898cc09ddba6e1835',
|
||||||
'com.android.support:transition:848270144fb180efd2bf928a00ed176dbbc5290badfd638390ffba90088df8b3',
|
'com.android.support:support-vector-drawable:077009d13882ee96f061e4bc2dbe7cce7ae1762d8297592a787ff741afbfb1f2',
|
||||||
'com.android.support:support-compat:54019c63614ce08b02d7b9605490cd2b29ba5b2505f394a9517450b5f72b30ca',
|
'com.android.support:support-fragment:316d35d4d2d2902057efad104a73e4bdb50bee260a7075678185b8cd71170945',
|
||||||
|
'com.android.support:support-core-ui:e72ae29b823889686cff6fcb948d6745c2baf6d4c2af4fdffa1ec1e42e3833a3',
|
||||||
'com.android.support:support-media-compat:566a161d9cb0083ef62a53e46b71ce5b3d455b8635b1a0a4ae28d96d4b583de8',
|
'com.android.support:support-media-compat:566a161d9cb0083ef62a53e46b71ce5b3d455b8635b1a0a4ae28d96d4b583de8',
|
||||||
'com.android.support:support-core-utils:34b8437dfa95ff28d29cf57ffa3b1354a9fa9bfe4059f0fd5ce2f5e4326a1748',
|
'com.android.support:support-core-utils:34b8437dfa95ff28d29cf57ffa3b1354a9fa9bfe4059f0fd5ce2f5e4326a1748',
|
||||||
'com.android.support:support-core-ui:e72ae29b823889686cff6fcb948d6745c2baf6d4c2af4fdffa1ec1e42e3833a3',
|
'com.android.support:support-compat:54019c63614ce08b02d7b9605490cd2b29ba5b2505f394a9517450b5f72b30ca',
|
||||||
'com.android.support:support-fragment:316d35d4d2d2902057efad104a73e4bdb50bee260a7075678185b8cd71170945',
|
'com.android.support:support-annotations:a774272036941b4e912eb426d70c848bde7f06a3bf5fb491f75a427dc6595270',
|
||||||
'com.android.support.constraint:constraint-layout-solver:8c62525a9bc5cff5633a96cb9b32fffeccaf41b8841aa87fc22607070dea9b8d',
|
'com.android.support.constraint:constraint-layout-solver:8c62525a9bc5cff5633a96cb9b32fffeccaf41b8841aa87fc22607070dea9b8d',
|
||||||
'me.dm7.barcodescanner:core:a5c8a704089b58029db166172ed8e55d756877d010a85a0b1c94fdc96ffb8f9a',
|
|
||||||
'com.google.zxing:core:bba7724e02a997cec38213af77133ee8e24b0d5cf5fa7ecbc16a4fa93f11ee0d',
|
'com.google.zxing:core:bba7724e02a997cec38213af77133ee8e24b0d5cf5fa7ecbc16a4fa93f11ee0d',
|
||||||
|
'com.squareup.okio:okio:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850',
|
||||||
|
'com.squareup.okhttp3:okhttp:7265adbd6f028aade307f58569d814835cd02bc9beffb70c25f72c9de50d61c4',
|
||||||
|
'com.jakewharton.timber:timber:35c22867f2673132e97e17857d36bb2fc25f5790f0425406833ed0254d62fc66',
|
||||||
|
'com.nulab-inc:zxcvbn:18d7862a6abd2705defec478d77dedadf8f3bb7cf811df22995494f05485785f',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
4
app/src/debug/res/values/strings.xml
Normal file
4
app/src/debug/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name" translatable="false">monerujo - Debug</string>
|
||||||
|
</resources>
|
@@ -13,6 +13,7 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
|
android:name=".XmrWalletApplication"
|
||||||
android:theme="@style/MyMaterialTheme">
|
android:theme="@style/MyMaterialTheme">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
|
File diff suppressed because it is too large
Load Diff
BIN
app/src/main/ic_launcher-web.png
Normal file
BIN
app/src/main/ic_launcher-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 245 KiB |
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,6 @@ import android.os.AsyncTask;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@@ -35,14 +34,16 @@ import android.widget.ScrollView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class GenerateReviewFragment extends Fragment {
|
public class GenerateReviewFragment extends Fragment {
|
||||||
static final String TAG = "GenerateReviewFragment";
|
|
||||||
static final public String VIEW_TYPE_DETAILS = "details";
|
static final public String VIEW_TYPE_DETAILS = "details";
|
||||||
static final public String VIEW_TYPE_ACCEPT = "accept";
|
static final public String VIEW_TYPE_ACCEPT = "accept";
|
||||||
static final public String VIEW_TYPE_WALLET = "wallet";
|
static final public String VIEW_TYPE_WALLET = "wallet";
|
||||||
@@ -81,7 +82,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
|
|
||||||
bAccept = (Button) view.findViewById(R.id.bAccept);
|
bAccept = (Button) view.findViewById(R.id.bAccept);
|
||||||
|
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
boolean testnet = WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet;
|
||||||
tvWalletMnemonic.setTextIsSelectable(testnet);
|
tvWalletMnemonic.setTextIsSelectable(testnet);
|
||||||
tvWalletSpendKey.setTextIsSelectable(testnet);
|
tvWalletSpendKey.setTextIsSelectable(testnet);
|
||||||
|
|
||||||
@@ -103,18 +104,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
copyAddress();
|
copyAddress();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
view.findViewById(R.id.bCopySeed).setOnClickListener(new View.OnClickListener() {
|
bCopyAddress.setClickable(false);
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
nocopy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
view.findViewById(R.id.bCopySepndKey).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
nocopy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -196,6 +186,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
name = wallet.getName();
|
name = wallet.getName();
|
||||||
status = wallet.getStatus();
|
status = wallet.getStatus();
|
||||||
if (status != Wallet.Status.Status_Ok) {
|
if (status != Wallet.Status.Status_Ok) {
|
||||||
|
Timber.e(wallet.getErrorString());
|
||||||
if (closeWallet) wallet.close();
|
if (closeWallet) wallet.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -225,7 +216,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
tvWalletViewKey.setText(viewKey);
|
tvWalletViewKey.setText(viewKey);
|
||||||
tvWalletSpendKey.setText(spendKey);
|
tvWalletSpendKey.setText(spendKey);
|
||||||
bAdvancedInfo.setVisibility(View.VISIBLE);
|
bAdvancedInfo.setVisibility(View.VISIBLE);
|
||||||
bCopyAddress.setEnabled(true);
|
bCopyAddress.setClickable(true);
|
||||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||||
activityCallback.setTitle(name, getString(R.string.details_title));
|
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||||
activityCallback.setToolbarButton(
|
activityCallback.setToolbarButton(
|
||||||
@@ -276,7 +267,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Log.d(TAG, "onResume()");
|
Timber.d("onResume()");
|
||||||
String name = tvWalletName.getText().toString();
|
String name = tvWalletName.getText().toString();
|
||||||
if (name.isEmpty()) name = null;
|
if (name.isEmpty()) name = null;
|
||||||
activityCallback.setTitle(name, getString(R.string.details_title));
|
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||||
@@ -305,5 +296,6 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
inflater.inflate(R.menu.wallet_details_menu, menu);
|
inflater.inflate(R.menu.wallet_details_menu, menu);
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
public interface OnBackPressedListener {
|
||||||
|
boolean onBackPressed();
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,6 @@ import android.content.Context;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -30,21 +29,21 @@ import com.google.zxing.BarcodeFormat;
|
|||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
|
||||||
import me.dm7.barcodescanner.zxing.ZXingScannerView;
|
import me.dm7.barcodescanner.zxing.ZXingScannerView;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class ScannerFragment extends Fragment implements ZXingScannerView.ResultHandler {
|
public class ScannerFragment extends Fragment implements ZXingScannerView.ResultHandler {
|
||||||
static final String TAG = "ScannerFragment";
|
|
||||||
|
|
||||||
Listener activityCallback;
|
private OnScannedListener onScannedListener;
|
||||||
|
|
||||||
public interface Listener {
|
public interface OnScannedListener {
|
||||||
boolean onAddressScanned(String uri);
|
boolean onScanned(String qrCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ZXingScannerView mScannerView;
|
private ZXingScannerView mScannerView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
Log.d(TAG, "onCreateView");
|
Timber.d("onCreateView");
|
||||||
mScannerView = new ZXingScannerView(getActivity());
|
mScannerView = new ZXingScannerView(getActivity());
|
||||||
return mScannerView;
|
return mScannerView;
|
||||||
}
|
}
|
||||||
@@ -52,20 +51,15 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Log.d(TAG, "onResume");
|
Timber.d("onResume");
|
||||||
mScannerView.setResultHandler(this);
|
mScannerView.setResultHandler(this);
|
||||||
mScannerView.startCamera();
|
mScannerView.startCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
static final String QR_SCHEME = "monero:";
|
|
||||||
static final String QR_PAYMENTID = "tx_payment_id";
|
|
||||||
static final String QR_AMOUNT = "tx_amount";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleResult(Result rawResult) {
|
public void handleResult(Result rawResult) {
|
||||||
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE) &&
|
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE)) {
|
||||||
(rawResult.getText().startsWith(QR_SCHEME))) {
|
if (onScannedListener.onScanned(rawResult.getText())) {
|
||||||
if (activityCallback.onAddressScanned(rawResult.getText())) {
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getActivity(), getString(R.string.send_qr_address_invalid), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), getString(R.string.send_qr_address_invalid), Toast.LENGTH_SHORT).show();
|
||||||
@@ -91,7 +85,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
Log.d(TAG, "onPause");
|
Timber.d("onPause");
|
||||||
mScannerView.stopCamera();
|
mScannerView.stopCamera();
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
@@ -99,11 +93,11 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
if (context instanceof Listener) {
|
if (context instanceof OnScannedListener) {
|
||||||
this.activityCallback = (Listener) context;
|
this.onScannedListener = (OnScannedListener) context;
|
||||||
} else {
|
} else {
|
||||||
throw new ClassCastException(context.toString()
|
throw new ClassCastException(context.toString()
|
||||||
+ " must implement Listener");
|
+ " must implement Listener");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
39
app/src/main/java/com/m2049r/xmrwallet/SecureActivity.java
Normal file
39
app/src/main/java/com/m2049r/xmrwallet/SecureActivity.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static android.view.WindowManager.LayoutParams;
|
||||||
|
|
||||||
|
public abstract class SecureActivity extends AppCompatActivity {
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||||
|
if (!BuildConfig.DEBUG) {
|
||||||
|
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -30,11 +30,14 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Transfer;
|
import com.m2049r.xmrwallet.model.Transfer;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.UserNotes;
|
||||||
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@@ -44,7 +47,6 @@ import java.util.Set;
|
|||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
public class TxFragment extends Fragment {
|
public class TxFragment extends Fragment {
|
||||||
static final String TAG = "TxFragment";
|
|
||||||
|
|
||||||
static public final String ARG_INFO = "info";
|
static public final String ARG_INFO = "info";
|
||||||
|
|
||||||
@@ -57,17 +59,23 @@ public class TxFragment extends Fragment {
|
|||||||
TS_FORMATTER.setTimeZone(tz);
|
TS_FORMATTER.setTimeZone(tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextView tvTxTimestamp;
|
private TextView tvTxTimestamp;
|
||||||
TextView tvTxId;
|
private TextView tvTxId;
|
||||||
TextView tvTxKey;
|
private TextView tvTxKey;
|
||||||
TextView tvDestination;
|
private TextView tvDestination;
|
||||||
TextView tvTxPaymentId;
|
private TextView tvTxPaymentId;
|
||||||
TextView tvTxBlockheight;
|
private TextView tvTxBlockheight;
|
||||||
TextView tvTxAmount;
|
private TextView tvTxAmount;
|
||||||
TextView tvTxFee;
|
private TextView tvTxFee;
|
||||||
TextView tvTxTransfers;
|
private TextView tvTxTransfers;
|
||||||
TextView etTxNotes;
|
private TextView etTxNotes;
|
||||||
Button bTxNotes;
|
private Button bTxNotes;
|
||||||
|
|
||||||
|
// XMRTO stuff
|
||||||
|
private View cvXmrTo;
|
||||||
|
private TextView tvTxXmrToKey;
|
||||||
|
private TextView tvDestinationBtc;
|
||||||
|
private TextView tvTxAmountBtc;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
@@ -75,6 +83,11 @@ public class TxFragment extends Fragment {
|
|||||||
|
|
||||||
View view = inflater.inflate(R.layout.fragment_tx_info, container, false);
|
View view = inflater.inflate(R.layout.fragment_tx_info, container, false);
|
||||||
|
|
||||||
|
cvXmrTo = view.findViewById(R.id.cvXmrTo);
|
||||||
|
tvTxXmrToKey = (TextView) view.findViewById(R.id.tvTxXmrToKey);
|
||||||
|
tvDestinationBtc = (TextView) view.findViewById(R.id.tvDestinationBtc);
|
||||||
|
tvTxAmountBtc = (TextView) view.findViewById(R.id.tvTxAmountBtc);
|
||||||
|
|
||||||
tvTxTimestamp = (TextView) view.findViewById(R.id.tvTxTimestamp);
|
tvTxTimestamp = (TextView) view.findViewById(R.id.tvTxTimestamp);
|
||||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||||
tvTxKey = (TextView) view.findViewById(R.id.tvTxKey);
|
tvTxKey = (TextView) view.findViewById(R.id.tvTxKey);
|
||||||
@@ -95,7 +108,16 @@ public class TxFragment extends Fragment {
|
|||||||
info.notes = null; // force reload on next view
|
info.notes = null; // force reload on next view
|
||||||
bTxNotes.setEnabled(false);
|
bTxNotes.setEnabled(false);
|
||||||
etTxNotes.setEnabled(false);
|
etTxNotes.setEnabled(false);
|
||||||
activityCallback.onSetNote(info.hash, etTxNotes.getText().toString());
|
userNotes.setNote(etTxNotes.getText().toString());
|
||||||
|
activityCallback.onSetNote(info.hash, userNotes.txNotes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tvTxXmrToKey.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_xmrtokey), tvTxXmrToKey.getText().toString());
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.message_copy_xmrtokey), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -167,8 +189,7 @@ public class TxFragment extends Fragment {
|
|||||||
sb.append("-");
|
sb.append("-");
|
||||||
}
|
}
|
||||||
sb.append("\n\n");
|
sb.append("\n\n");
|
||||||
//Helper.clipBoardCopy(getActivity(), getString(R.string.tx_copy_label), sb.toString());
|
|
||||||
//Toast.makeText(getActivity(), getString(R.string.tx_copy_message), Toast.LENGTH_SHORT).show();
|
|
||||||
Intent sendIntent = new Intent();
|
Intent sendIntent = new Intent();
|
||||||
sendIntent.setAction(Intent.ACTION_SEND);
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, sb.toString());
|
sendIntent.putExtra(Intent.EXTRA_TEXT, sb.toString());
|
||||||
@@ -177,12 +198,14 @@ public class TxFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TransactionInfo info = null;
|
TransactionInfo info = null;
|
||||||
|
UserNotes userNotes = null;
|
||||||
|
|
||||||
void loadNotes(TransactionInfo info) {
|
void loadNotes(TransactionInfo info) {
|
||||||
if (info.notes == null) {
|
if ((userNotes == null) || (info.notes == null)) {
|
||||||
info.notes = activityCallback.getTxNotes(info.hash);
|
info.notes = activityCallback.getTxNotes(info.hash);
|
||||||
}
|
}
|
||||||
etTxNotes.setText(info.notes);
|
userNotes = new UserNotes(info.notes);
|
||||||
|
etTxNotes.setText(userNotes.note);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTxColour(int clr) {
|
private void setTxColour(int clr) {
|
||||||
@@ -212,18 +235,20 @@ public class TxFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
|
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
|
||||||
|
|
||||||
tvTxAmount.setText(sign + Wallet.getDisplayAmount(info.amount));
|
long realAmount = info.amount;
|
||||||
|
if (info.isPending) {
|
||||||
|
realAmount = realAmount - info.fee;
|
||||||
|
}
|
||||||
|
tvTxAmount.setText(sign + Wallet.getDisplayAmount(realAmount));
|
||||||
|
|
||||||
if ((info.fee > 0)) {
|
if ((info.fee > 0)) {
|
||||||
String fee = Wallet.getDisplayAmount(info.fee);
|
String fee = Wallet.getDisplayAmount(info.fee);
|
||||||
if (info.isPending) {
|
tvTxFee.setText(getString(R.string.tx_list_fee, fee));
|
||||||
tvTxFee.setText(getString(R.string.tx_list_fee_pending, fee));
|
|
||||||
} else {
|
|
||||||
tvTxFee.setText(getString(R.string.tx_list_fee, fee));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
tvTxFee.setText(null);
|
tvTxFee.setText(null);
|
||||||
tvTxFee.setVisibility(View.GONE);
|
tvTxFee.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.isFailed) {
|
if (info.isFailed) {
|
||||||
tvTxAmount.setText(getString(R.string.tx_list_amount_failed, Wallet.getDisplayAmount(info.amount)));
|
tvTxAmount.setText(getString(R.string.tx_list_amount_failed, Wallet.getDisplayAmount(info.amount)));
|
||||||
tvTxFee.setText(getString(R.string.tx_list_failed_text));
|
tvTxFee.setText(getString(R.string.tx_list_failed_text));
|
||||||
@@ -266,8 +291,21 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxTransfers.setText(sb.toString());
|
tvTxTransfers.setText(sb.toString());
|
||||||
tvDestination.setText(dstSb.toString());
|
tvDestination.setText(dstSb.toString());
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
showBtcInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showBtcInfo() {
|
||||||
|
if (userNotes.xmrtoKey != null) {
|
||||||
|
cvXmrTo.setVisibility(View.VISIBLE);
|
||||||
|
tvTxXmrToKey.setText(userNotes.xmrtoKey);
|
||||||
|
tvDestinationBtc.setText(userNotes.xmrtoDestination);
|
||||||
|
tvTxAmountBtc.setText(userNotes.xmrtoAmount + " BTC");
|
||||||
|
} else {
|
||||||
|
cvXmrTo.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -307,4 +345,4 @@ public class TxFragment extends Fragment {
|
|||||||
+ " must implement Listener");
|
+ " must implement Listener");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 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.Application;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
public class XmrWalletApplication extends Application {
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
Timber.plant(new Timber.DebugTree());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
201
app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java
Normal file
201
app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
public class BarcodeData {
|
||||||
|
public static final String XMR_SCHEME = "monero:";
|
||||||
|
public static final String XMR_PAYMENTID = "tx_payment_id";
|
||||||
|
public static final String XMR_AMOUNT = "tx_amount";
|
||||||
|
|
||||||
|
static final String BTC_SCHEME = "bitcoin:";
|
||||||
|
static final String BTC_AMOUNT = "amount";
|
||||||
|
|
||||||
|
public enum Asset {
|
||||||
|
XMR, BTC
|
||||||
|
}
|
||||||
|
|
||||||
|
public Asset asset = null;
|
||||||
|
public String address = null;
|
||||||
|
public String paymentId = null;
|
||||||
|
public String amount = null;
|
||||||
|
|
||||||
|
public BarcodeData(Asset asset, String address) {
|
||||||
|
this.asset = asset;
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BarcodeData(Asset asset, String address, String amount) {
|
||||||
|
this.asset = asset;
|
||||||
|
this.address = address;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BarcodeData(Asset asset, String address, String paymentId, String amount) {
|
||||||
|
this.asset = asset;
|
||||||
|
this.address = address;
|
||||||
|
this.paymentId = paymentId;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public BarcodeData fromQrCode(String qrCode) {
|
||||||
|
// check for monero uri
|
||||||
|
BarcodeData bcData = parseMoneroUri(qrCode);
|
||||||
|
// check for naked monero address / integrated address
|
||||||
|
if (bcData == null) {
|
||||||
|
bcData = parseMoneroNaked(qrCode);
|
||||||
|
}
|
||||||
|
// check for btc uri
|
||||||
|
if (bcData == null) {
|
||||||
|
bcData = parseBitcoinUri(qrCode);
|
||||||
|
}
|
||||||
|
// check for naked btc addres
|
||||||
|
if (bcData == null) {
|
||||||
|
bcData = parseBitcoinNaked(qrCode);
|
||||||
|
}
|
||||||
|
return bcData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse and decode a monero scheme string. It is here because it needs to validate the data.
|
||||||
|
*
|
||||||
|
* @param uri String containing a monero URL
|
||||||
|
* @return BarcodeData object or null if uri not valid
|
||||||
|
*/
|
||||||
|
|
||||||
|
static public BarcodeData parseMoneroUri(String uri) {
|
||||||
|
Timber.d("parseMoneroUri=%s", uri);
|
||||||
|
|
||||||
|
if (uri == null) return null;
|
||||||
|
|
||||||
|
if (!uri.startsWith(XMR_SCHEME)) return null;
|
||||||
|
|
||||||
|
String noScheme = uri.substring(XMR_SCHEME.length());
|
||||||
|
Uri monero = Uri.parse(noScheme);
|
||||||
|
Map<String, String> parms = new HashMap<>();
|
||||||
|
String query = monero.getQuery();
|
||||||
|
if (query != null) {
|
||||||
|
String[] args = query.split("&");
|
||||||
|
for (String arg : args) {
|
||||||
|
String[] namevalue = arg.split("=");
|
||||||
|
if (namevalue.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parms.put(Uri.decode(namevalue[0]).toLowerCase(),
|
||||||
|
namevalue.length > 1 ? Uri.decode(namevalue[1]) : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String address = monero.getPath();
|
||||||
|
String paymentId = parms.get(XMR_PAYMENTID);
|
||||||
|
String amount = parms.get(XMR_AMOUNT);
|
||||||
|
if (amount != null) {
|
||||||
|
try {
|
||||||
|
Double.parseDouble(amount);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
Timber.d(ex.getLocalizedMessage());
|
||||||
|
return null; // we have an amount but its not a number!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((paymentId != null) && !Wallet.isPaymentIdValid(paymentId)) {
|
||||||
|
Timber.d("paymentId invalid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Wallet.isAddressValid(address)) {
|
||||||
|
Timber.d("address invalid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new BarcodeData(Asset.XMR, address, paymentId, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public BarcodeData parseMoneroNaked(String address) {
|
||||||
|
Timber.d("parseMoneroNaked=%s", address);
|
||||||
|
|
||||||
|
if (address == null) return null;
|
||||||
|
|
||||||
|
if (!Wallet.isAddressValid(address)) {
|
||||||
|
Timber.d("address invalid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BarcodeData(Asset.XMR, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bitcoin:mpQ84J43EURZHkCnXbyQ4PpNDLLBqdsMW2?amount=0.01
|
||||||
|
static public BarcodeData parseBitcoinUri(String uri) {
|
||||||
|
Timber.d("parseBitcoinUri=%s", uri);
|
||||||
|
|
||||||
|
if (uri == null) return null;
|
||||||
|
|
||||||
|
if (!uri.startsWith(BTC_SCHEME)) return null;
|
||||||
|
|
||||||
|
String noScheme = uri.substring(BTC_SCHEME.length());
|
||||||
|
Uri bitcoin = Uri.parse(noScheme);
|
||||||
|
Map<String, String> parms = new HashMap<>();
|
||||||
|
String query = bitcoin.getQuery();
|
||||||
|
if (query != null) {
|
||||||
|
String[] args = query.split("&");
|
||||||
|
for (String arg : args) {
|
||||||
|
String[] namevalue = arg.split("=");
|
||||||
|
if (namevalue.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parms.put(Uri.decode(namevalue[0]).toLowerCase(),
|
||||||
|
namevalue.length > 1 ? Uri.decode(namevalue[1]) : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String address = bitcoin.getPath();
|
||||||
|
String amount = parms.get(BTC_AMOUNT);
|
||||||
|
if (amount != null) {
|
||||||
|
try {
|
||||||
|
Double.parseDouble(amount);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
Timber.d(ex.getLocalizedMessage());
|
||||||
|
return null; // we have an amount but its not a number!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!BitcoinAddressValidator.validate(address)) {
|
||||||
|
Timber.d("address invalid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new BarcodeData(BarcodeData.Asset.BTC, address, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public BarcodeData parseBitcoinNaked(String address) {
|
||||||
|
Timber.d("parseBitcoinNaked=%s", address);
|
||||||
|
|
||||||
|
if (address == null) return null;
|
||||||
|
|
||||||
|
if (!BitcoinAddressValidator.validate(address)) {
|
||||||
|
Timber.d("address invalid");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BarcodeData(BarcodeData.Asset.BTC, address);
|
||||||
|
}
|
||||||
|
}
|
39
app/src/main/java/com/m2049r/xmrwallet/data/PendingTx.java
Normal file
39
app/src/main/java/com/m2049r/xmrwallet/data/PendingTx.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
|
||||||
|
public class PendingTx {
|
||||||
|
final public PendingTransaction.Status status;
|
||||||
|
final public String error;
|
||||||
|
final public long amount;
|
||||||
|
final public long dust;
|
||||||
|
final public long fee;
|
||||||
|
final public String txId;
|
||||||
|
final public long txCount;
|
||||||
|
|
||||||
|
public PendingTx(PendingTransaction pendingTransaction) {
|
||||||
|
status = pendingTransaction.getStatus();
|
||||||
|
error = pendingTransaction.getErrorString();
|
||||||
|
amount = pendingTransaction.getAmount();
|
||||||
|
dust = pendingTransaction.getDust();
|
||||||
|
fee = pendingTransaction.getFee();
|
||||||
|
txId = pendingTransaction.getFirstTxId();
|
||||||
|
txCount = pendingTransaction.getTxCount();
|
||||||
|
}
|
||||||
|
}
|
@@ -14,36 +14,101 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet.util;
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
import com.m2049r.xmrwallet.util.UserNotes;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
||||||
public class TxData implements Parcelable {
|
public class TxData implements Parcelable {
|
||||||
public TxData(String dst_addr,
|
|
||||||
|
public TxData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TxData(TxData txData) {
|
||||||
|
this.dstAddr = txData.dstAddr;
|
||||||
|
this.paymentId = txData.paymentId;
|
||||||
|
this.amount = txData.amount;
|
||||||
|
this.mixin = txData.mixin;
|
||||||
|
this.priority = txData.priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TxData(String dstAddr,
|
||||||
String paymentId,
|
String paymentId,
|
||||||
long amount,
|
long amount,
|
||||||
int mixin,
|
int mixin,
|
||||||
PendingTransaction.Priority priority) {
|
PendingTransaction.Priority priority) {
|
||||||
this.dst_addr = dst_addr;
|
this.dstAddr = dstAddr;
|
||||||
this.paymentId = paymentId;
|
this.paymentId = paymentId;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.mixin = mixin;
|
this.mixin = mixin;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String dst_addr;
|
public String getDestinationAddress() {
|
||||||
public String paymentId;
|
return dstAddr;
|
||||||
public long amount;
|
}
|
||||||
public int mixin;
|
|
||||||
public PendingTransaction.Priority priority;
|
public String getPaymentId() {
|
||||||
|
return paymentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMixin() {
|
||||||
|
return mixin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PendingTransaction.Priority getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDestinationAddress(String dstAddr) {
|
||||||
|
this.dstAddr = dstAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaymentId(String paymentId) {
|
||||||
|
this.paymentId = paymentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMixin(int mixin) {
|
||||||
|
this.mixin = mixin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(PendingTransaction.Priority priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserNotes getUserNotes() {
|
||||||
|
return userNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserNotes(UserNotes userNotes) {
|
||||||
|
this.userNotes = userNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String dstAddr;
|
||||||
|
private String paymentId;
|
||||||
|
private long amount;
|
||||||
|
private int mixin;
|
||||||
|
private PendingTransaction.Priority priority;
|
||||||
|
|
||||||
|
private UserNotes userNotes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel out, int flags) {
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
out.writeString(dst_addr);
|
out.writeString(dstAddr);
|
||||||
out.writeString(paymentId);
|
out.writeString(paymentId);
|
||||||
out.writeLong(amount);
|
out.writeLong(amount);
|
||||||
out.writeInt(mixin);
|
out.writeInt(mixin);
|
||||||
@@ -61,8 +126,8 @@ public class TxData implements Parcelable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private TxData(Parcel in) {
|
protected TxData(Parcel in) {
|
||||||
dst_addr = in.readString();
|
dstAddr = in.readString();
|
||||||
paymentId = in.readString();
|
paymentId = in.readString();
|
||||||
amount = in.readLong();
|
amount = in.readLong();
|
||||||
mixin = in.readInt();
|
mixin = in.readInt();
|
||||||
@@ -78,8 +143,8 @@ public class TxData implements Parcelable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append("dst_addr:");
|
sb.append("dstAddr:");
|
||||||
sb.append(dst_addr);
|
sb.append(dstAddr);
|
||||||
sb.append(",paymentId:");
|
sb.append(",paymentId:");
|
||||||
sb.append(paymentId);
|
sb.append(paymentId);
|
||||||
sb.append(",amount:");
|
sb.append(",amount:");
|
||||||
@@ -87,7 +152,7 @@ public class TxData implements Parcelable {
|
|||||||
sb.append(",mixin:");
|
sb.append(",mixin:");
|
||||||
sb.append(mixin);
|
sb.append(mixin);
|
||||||
sb.append(",priority:");
|
sb.append(",priority:");
|
||||||
sb.append(priority.toString());
|
sb.append(String.valueOf(priority));
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
98
app/src/main/java/com/m2049r/xmrwallet/data/TxDataBtc.java
Normal file
98
app/src/main/java/com/m2049r/xmrwallet/data/TxDataBtc.java
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
|
||||||
|
public class TxDataBtc extends TxData {
|
||||||
|
|
||||||
|
private String xmrtoUuid;
|
||||||
|
private String btcAddress;
|
||||||
|
private double btcAmount;
|
||||||
|
|
||||||
|
public TxDataBtc() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TxDataBtc(TxDataBtc txDataBtc) {
|
||||||
|
super(txDataBtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getXmrtoUuid() {
|
||||||
|
return xmrtoUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXmrtoUuid(String xmrtoUuid) {
|
||||||
|
this.xmrtoUuid = xmrtoUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBtcAddress() {
|
||||||
|
return btcAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtcAddress(String btcAddress) {
|
||||||
|
this.btcAddress = btcAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBtcAmount() {
|
||||||
|
return btcAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtcAmount(double btcAmount) {
|
||||||
|
this.btcAmount = btcAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
super.writeToParcel(out, flags);
|
||||||
|
out.writeString(xmrtoUuid);
|
||||||
|
out.writeString(btcAddress);
|
||||||
|
out.writeDouble(btcAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
|
||||||
|
public static final Creator<TxDataBtc> CREATOR = new Creator<TxDataBtc>() {
|
||||||
|
public TxDataBtc createFromParcel(Parcel in) {
|
||||||
|
return new TxDataBtc(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TxDataBtc[] newArray(int size) {
|
||||||
|
return new TxDataBtc[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected TxDataBtc(Parcel in) {
|
||||||
|
super(in);
|
||||||
|
xmrtoUuid = in.readString();
|
||||||
|
btcAddress = in.readString();
|
||||||
|
btcAmount = in.readDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(",xmrtoUuid:");
|
||||||
|
sb.append(xmrtoUuid);
|
||||||
|
sb.append(",btcAddress:");
|
||||||
|
sb.append(btcAddress);
|
||||||
|
sb.append(",btcAmount:");
|
||||||
|
sb.append(btcAmount);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
108
app/src/main/java/com/m2049r/xmrwallet/data/WalletNode.java
Normal file
108
app/src/main/java/com/m2049r/xmrwallet/data/WalletNode.java
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
public class WalletNode {
|
||||||
|
private final String name;
|
||||||
|
private final String host;
|
||||||
|
private final int port;
|
||||||
|
private final String user;
|
||||||
|
private final String password;
|
||||||
|
private final NetworkType networkType;
|
||||||
|
|
||||||
|
public WalletNode(String walletName, String daemon, NetworkType networkType) {
|
||||||
|
if ((daemon == null) || daemon.isEmpty())
|
||||||
|
throw new IllegalArgumentException("daemon is empty");
|
||||||
|
this.name = walletName;
|
||||||
|
String daemonAddress;
|
||||||
|
String a[] = daemon.split("@");
|
||||||
|
if (a.length == 1) { // no credentials
|
||||||
|
daemonAddress = a[0];
|
||||||
|
user = "";
|
||||||
|
password = "";
|
||||||
|
} else if (a.length == 2) { // credentials
|
||||||
|
String userPassword[] = a[0].split(":");
|
||||||
|
if (userPassword.length != 2)
|
||||||
|
throw new IllegalArgumentException("User:Password invalid");
|
||||||
|
user = userPassword[0];
|
||||||
|
if (!user.isEmpty()) {
|
||||||
|
password = userPassword[1];
|
||||||
|
} else {
|
||||||
|
password = "";
|
||||||
|
}
|
||||||
|
daemonAddress = a[1];
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Too many @");
|
||||||
|
}
|
||||||
|
|
||||||
|
String da[] = daemonAddress.split(":");
|
||||||
|
if ((da.length > 2) || (da.length < 1))
|
||||||
|
throw new IllegalArgumentException("Too many ':' or too few");
|
||||||
|
host = da[0];
|
||||||
|
if (da.length == 2) {
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(da[1]);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new IllegalArgumentException("Port not numeric");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (networkType) {
|
||||||
|
case NetworkType_Mainnet:
|
||||||
|
port = 18081;
|
||||||
|
break;
|
||||||
|
case NetworkType_Testnet:
|
||||||
|
port = 28081;
|
||||||
|
break;
|
||||||
|
case NetworkType_Stagenet:
|
||||||
|
port = 38081;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
port = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.networkType = networkType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return host + ":" + port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketAddress getSocketAddress() {
|
||||||
|
return new InetSocketAddress(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return !host.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user