mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-05 09:58:42 +02:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e56369b91a | ||
![]() |
b04aa24269 | ||
![]() |
dda86bd5de | ||
![]() |
a19ad7fd52 | ||
![]() |
0443fd808c | ||
![]() |
faf57c96fc |
@@ -13,7 +13,7 @@ set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../external-libs)
|
|||||||
|
|
||||||
add_library(sodium STATIC IMPORTED)
|
add_library(sodium STATIC IMPORTED)
|
||||||
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/libsodium/lib/${ANDROID_ABI}/libsodium.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libsodium.a)
|
||||||
|
|
||||||
############
|
############
|
||||||
# OpenSSL
|
# OpenSSL
|
||||||
@@ -21,11 +21,11 @@ set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
|||||||
|
|
||||||
add_library(crypto STATIC IMPORTED)
|
add_library(crypto STATIC IMPORTED)
|
||||||
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
|
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libcrypto.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libcrypto.a)
|
||||||
|
|
||||||
add_library(ssl STATIC IMPORTED)
|
add_library(ssl STATIC IMPORTED)
|
||||||
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libssl.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libssl.a)
|
||||||
|
|
||||||
############
|
############
|
||||||
# Boost
|
# Boost
|
||||||
@@ -33,39 +33,39 @@ set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
|||||||
|
|
||||||
add_library(boost_chrono STATIC IMPORTED)
|
add_library(boost_chrono STATIC IMPORTED)
|
||||||
set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_date_time STATIC IMPORTED)
|
||||||
set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_filesystem STATIC IMPORTED)
|
||||||
set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_program_options STATIC IMPORTED)
|
||||||
set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_regex STATIC IMPORTED)
|
||||||
set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_serialization STATIC IMPORTED)
|
||||||
set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_system STATIC IMPORTED)
|
||||||
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_thread STATIC IMPORTED)
|
||||||
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(boost_wserialization STATIC IMPORTED)
|
||||||
set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
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
|
# Monero
|
||||||
@@ -73,99 +73,103 @@ set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
|||||||
|
|
||||||
add_library(wallet_api STATIC IMPORTED)
|
add_library(wallet_api STATIC IMPORTED)
|
||||||
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
|
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)
|
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}/${ANDROID_ABI}/monero/libwallet.a)
|
||||||
|
|
||||||
add_library(cryptonote_core STATIC IMPORTED)
|
add_library(cryptonote_core STATIC IMPORTED)
|
||||||
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(cryptonote_basic STATIC IMPORTED)
|
||||||
set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(mnemonics STATIC IMPORTED)
|
||||||
set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(common STATIC IMPORTED)
|
||||||
set_target_properties(common PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(cncrypto STATIC IMPORTED)
|
||||||
set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
|
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)
|
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}/${ANDROID_ABI}/monero/libringct.a)
|
||||||
|
|
||||||
add_library(ringct_basic STATIC IMPORTED)
|
add_library(ringct_basic STATIC IMPORTED)
|
||||||
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(blockchain_db STATIC IMPORTED)
|
||||||
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(lmdb STATIC IMPORTED)
|
||||||
set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(easylogging STATIC IMPORTED)
|
||||||
set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
|
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)
|
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}/${ANDROID_ABI}/monero/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}/${ANDROID_ABI}/monero/libepee.a)
|
||||||
|
|
||||||
add_library(blocks STATIC IMPORTED)
|
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}/${ANDROID_ABI}/monero/libblocks.a)
|
||||||
|
|
||||||
add_library(checkpoints STATIC IMPORTED)
|
add_library(checkpoints STATIC IMPORTED)
|
||||||
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(device STATIC IMPORTED)
|
||||||
set_target_properties(device PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(device_trezor STATIC IMPORTED)
|
||||||
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
|
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice_trezor.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libdevice_trezor.a)
|
||||||
|
|
||||||
add_library(multisig STATIC IMPORTED)
|
add_library(multisig STATIC IMPORTED)
|
||||||
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(version STATIC IMPORTED)
|
||||||
set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
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)
|
add_library(net STATIC IMPORTED)
|
||||||
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libnet.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libnet.a)
|
||||||
|
|
||||||
add_library(hardforks STATIC IMPORTED)
|
add_library(hardforks STATIC IMPORTED)
|
||||||
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libhardforks.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libhardforks.a)
|
||||||
|
|
||||||
add_library(randomx STATIC IMPORTED)
|
add_library(randomx STATIC IMPORTED)
|
||||||
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
|
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librandomx.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/librandomx.a)
|
||||||
|
|
||||||
add_library(rpc_base STATIC IMPORTED)
|
add_library(rpc_base STATIC IMPORTED)
|
||||||
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librpc_base.a)
|
${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)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# System
|
# System
|
||||||
@@ -173,10 +177,16 @@ set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
|||||||
|
|
||||||
find_library( log-lib log )
|
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})
|
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
|
target_link_libraries( monerujo
|
||||||
|
|
||||||
wallet_api
|
wallet_api
|
||||||
@@ -203,6 +213,7 @@ target_link_libraries( monerujo
|
|||||||
randomx
|
randomx
|
||||||
hardforks
|
hardforks
|
||||||
rpc_base
|
rpc_base
|
||||||
|
${EXTRA_LIBS}
|
||||||
|
|
||||||
boost_chrono
|
boost_chrono
|
||||||
boost_date_time
|
boost_date_time
|
||||||
|
@@ -7,8 +7,8 @@ android {
|
|||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 702
|
versionCode 707
|
||||||
versionName "1.17.2 'Druk'"
|
versionName "1.17.7 'Druk'"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
|
@@ -213,7 +213,7 @@ public class BaseActivity extends SecureActivity implements GenerateReviewFragme
|
|||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||||
} else {
|
} else {
|
||||||
BarcodeData bc = BarcodeData.fromQrCode(uri.toString());
|
BarcodeData bc = BarcodeData.fromString(uri.toString());
|
||||||
if (bc == null)
|
if (bc == null)
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||||
else
|
else
|
||||||
|
@@ -58,6 +58,7 @@ import com.google.zxing.qrcode.QRCodeWriter;
|
|||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||||
import com.m2049r.xmrwallet.BuildConfig;
|
import com.m2049r.xmrwallet.BuildConfig;
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
|
import com.m2049r.xmrwallet.data.Crypto;
|
||||||
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
@@ -469,7 +470,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
Timber.d("CLEARQR");
|
Timber.d("CLEARQR");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bcData = new BarcodeData(BarcodeData.Asset.XMR, address, notes, xmrAmount);
|
bcData = new BarcodeData(Crypto.XMR, address, notes, xmrAmount);
|
||||||
int size = Math.max(ivQrCode.getWidth(), ivQrCode.getHeight());
|
int size = Math.max(ivQrCode.getWidth(), ivQrCode.getHeight());
|
||||||
Bitmap qr = generate(bcData.getUriString(), size, size);
|
Bitmap qr = generate(bcData.getUriString(), size, size);
|
||||||
if (qr != null) {
|
if (qr != null) {
|
||||||
|
@@ -73,14 +73,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
// * On older devices continuously stopping and resuming camera preview can result in freezing the app.
|
// * On older devices continuously stopping and resuming camera preview can result in freezing the app.
|
||||||
// * I don't know why this is the case but I don't have the time to figure out.
|
// * I don't know why this is the case but I don't have the time to figure out.
|
||||||
Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
handler.postDelayed(new
|
handler.postDelayed(() -> mScannerView.resumeCameraPreview(ScannerFragment.this), 2000);
|
||||||
|
|
||||||
Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mScannerView.resumeCameraPreview(ScannerFragment.this);
|
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -300,7 +300,7 @@ public class TxFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
tvTxXmrToKey.setText(key);
|
tvTxXmrToKey.setText(key);
|
||||||
tvDestinationBtc.setText(userNotes.xmrtoDestination);
|
tvDestinationBtc.setText(userNotes.xmrtoDestination);
|
||||||
tvTxAmountBtc.setText(userNotes.xmrtoAmount + " BTC");
|
tvTxAmountBtc.setText(userNotes.xmrtoAmount + " "+ userNotes.xmrtoCurrency);
|
||||||
switch (userNotes.xmrtoTag) {
|
switch (userNotes.xmrtoTag) {
|
||||||
case "xmrto":
|
case "xmrto":
|
||||||
tvXmrToSupport.setVisibility(View.GONE);
|
tvXmrToSupport.setVisibility(View.GONE);
|
||||||
|
@@ -921,7 +921,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
@Override
|
@Override
|
||||||
public boolean onScanned(String qrCode) {
|
public boolean onScanned(String qrCode) {
|
||||||
// #gurke
|
// #gurke
|
||||||
BarcodeData bcData = BarcodeData.fromQrCode(qrCode);
|
BarcodeData bcData = BarcodeData.fromString(qrCode);
|
||||||
if (bcData != null) {
|
if (bcData != null) {
|
||||||
popFragmentStack(null);
|
popFragmentStack(null);
|
||||||
Timber.d("AAA");
|
Timber.d("AAA");
|
||||||
|
@@ -49,6 +49,7 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
|||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
@@ -242,7 +243,7 @@ public class WalletFragment extends Fragment
|
|||||||
String balanceCurrency = Helper.BASE_CRYPTO;
|
String balanceCurrency = Helper.BASE_CRYPTO;
|
||||||
double balanceRate = 1.0;
|
double balanceRate = 1.0;
|
||||||
|
|
||||||
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
|
private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi();
|
||||||
|
|
||||||
void refreshBalance() {
|
void refreshBalance() {
|
||||||
double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
|
double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
|
||||||
|
File diff suppressed because it is too large
Load Diff
89
app/src/main/java/com/m2049r/xmrwallet/data/Crypto.java
Normal file
89
app/src/main/java/com/m2049r/xmrwallet/data/Crypto.java
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.R;
|
||||||
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
|
import com.m2049r.xmrwallet.util.validator.BitcoinAddressType;
|
||||||
|
import com.m2049r.xmrwallet.util.validator.BitcoinAddressValidator;
|
||||||
|
import com.m2049r.xmrwallet.util.validator.EthAddressValidator;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum Crypto {
|
||||||
|
XMR("XMR", true, "monero:tx_amount:recipient_name:tx_description", R.id.ibXMR, R.drawable.ic_monero, R.drawable.ic_monero_bw, Wallet::isAddressValid),
|
||||||
|
BTC("BTC", true, "bitcoin:amount:label:message", R.id.ibBTC, R.drawable.ic_xmrto_btc, R.drawable.ic_xmrto_btc_off, address -> {
|
||||||
|
return BitcoinAddressValidator.validate(address, BitcoinAddressType.BTC);
|
||||||
|
}),
|
||||||
|
DASH("DASH", true, "dash:amount:label:message", R.id.ibDASH, R.drawable.ic_xmrto_dash, R.drawable.ic_xmrto_dash_off, address -> {
|
||||||
|
return BitcoinAddressValidator.validate(address, BitcoinAddressType.DASH);
|
||||||
|
}),
|
||||||
|
DOGE("DOGE", true, "dogecoin:amount:label:message", R.id.ibDOGE, R.drawable.ic_xmrto_doge, R.drawable.ic_xmrto_doge_off, address -> {
|
||||||
|
return BitcoinAddressValidator.validate(address, BitcoinAddressType.DOGE);
|
||||||
|
}),
|
||||||
|
ETH("ETH", false, "ethereum:amount:label:message", R.id.ibETH, R.drawable.ic_xmrto_eth, R.drawable.ic_xmrto_eth_off, EthAddressValidator::validate),
|
||||||
|
LTC("LTC", true, "litecoin:amount:label:message", R.id.ibLTC, R.drawable.ic_xmrto_ltc, R.drawable.ic_xmrto_ltc_off, address -> {
|
||||||
|
return BitcoinAddressValidator.validate(address, BitcoinAddressType.LTC);
|
||||||
|
});
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NonNull
|
||||||
|
private final String symbol;
|
||||||
|
@Getter
|
||||||
|
private final boolean casefull;
|
||||||
|
@NonNull
|
||||||
|
private final String uriSpec;
|
||||||
|
@Getter
|
||||||
|
private final int buttonId;
|
||||||
|
@Getter
|
||||||
|
private final int iconEnabledId;
|
||||||
|
@Getter
|
||||||
|
private final int iconDisabledId;
|
||||||
|
@NonNull
|
||||||
|
private final Validator validator;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Crypto withScheme(@NonNull String scheme) {
|
||||||
|
for (Crypto crypto : values()) {
|
||||||
|
if (crypto.getUriScheme().equals(scheme)) return crypto;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Crypto withSymbol(@NonNull String symbol) {
|
||||||
|
final String upperSymbol = symbol.toUpperCase();
|
||||||
|
for (Crypto crypto : values()) {
|
||||||
|
if (crypto.symbol.equals(upperSymbol)) return crypto;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Validator {
|
||||||
|
boolean validate(String address);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO maybe cache these segments
|
||||||
|
String getUriScheme() {
|
||||||
|
return uriSpec.split(":")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
String getUriAmount() {
|
||||||
|
return uriSpec.split(":")[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
String getUriLabel() {
|
||||||
|
return uriSpec.split(":")[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
String getUriMessage() {
|
||||||
|
return uriSpec.split(":")[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean validate(String address) {
|
||||||
|
return validator.validate(address);
|
||||||
|
}
|
||||||
|
}
|
@@ -24,6 +24,9 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
public class TxDataBtc extends TxData {
|
public class TxDataBtc extends TxData {
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private String btcSymbol; // the actual non-XMR thing we're sending
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private String xmrtoOrderId; // shown in success screen
|
private String xmrtoOrderId; // shown in success screen
|
||||||
@@ -45,6 +48,7 @@ public class TxDataBtc extends TxData {
|
|||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel out, int flags) {
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
super.writeToParcel(out, flags);
|
super.writeToParcel(out, flags);
|
||||||
|
out.writeString(btcSymbol);
|
||||||
out.writeString(xmrtoOrderId);
|
out.writeString(xmrtoOrderId);
|
||||||
out.writeString(btcAddress);
|
out.writeString(btcAddress);
|
||||||
out.writeDouble(btcAmount);
|
out.writeDouble(btcAmount);
|
||||||
@@ -63,6 +67,7 @@ public class TxDataBtc extends TxData {
|
|||||||
|
|
||||||
protected TxDataBtc(Parcel in) {
|
protected TxDataBtc(Parcel in) {
|
||||||
super(in);
|
super(in);
|
||||||
|
btcSymbol = in.readString();
|
||||||
xmrtoOrderId = in.readString();
|
xmrtoOrderId = in.readString();
|
||||||
btcAddress = in.readString();
|
btcAddress = in.readString();
|
||||||
btcAmount = in.readDouble();
|
btcAmount = in.readDouble();
|
||||||
@@ -74,10 +79,23 @@ public class TxDataBtc extends TxData {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("xmrtoOrderId:");
|
sb.append("xmrtoOrderId:");
|
||||||
sb.append(xmrtoOrderId);
|
sb.append(xmrtoOrderId);
|
||||||
|
sb.append(",btcSymbol:");
|
||||||
|
sb.append(btcSymbol);
|
||||||
sb.append(",btcAddress:");
|
sb.append(",btcAddress:");
|
||||||
sb.append(btcAddress);
|
sb.append(btcAddress);
|
||||||
sb.append(",btcAmount:");
|
sb.append(",btcAmount:");
|
||||||
sb.append(btcAmount);
|
sb.append(btcAmount);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean validateAddress(@NonNull String address) {
|
||||||
|
if ((btcSymbol == null) || (btcAddress == null)) return false;
|
||||||
|
final Crypto crypto = Crypto.withSymbol(btcSymbol);
|
||||||
|
if (crypto == null) return false;
|
||||||
|
if (crypto.isCasefull()) { // compare as-is
|
||||||
|
return address.equals(btcAddress);
|
||||||
|
} else { // normalize & compare (e.g. ETH with and without checksum capitals
|
||||||
|
return address.toLowerCase().equals(btcAddress.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ public class UserNotes {
|
|||||||
public String xmrtoTag = null;
|
public String xmrtoTag = null;
|
||||||
public String xmrtoKey = null;
|
public String xmrtoKey = null;
|
||||||
public String xmrtoAmount = null; // could be a double - but we are not doing any calculations
|
public String xmrtoAmount = null; // could be a double - but we are not doing any calculations
|
||||||
|
public String xmrtoCurrency = null;
|
||||||
public String xmrtoDestination = null;
|
public String xmrtoDestination = null;
|
||||||
|
|
||||||
public UserNotes(final String txNotes) {
|
public UserNotes(final String txNotes) {
|
||||||
@@ -35,14 +36,15 @@ public class UserNotes {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.txNotes = txNotes;
|
this.txNotes = txNotes;
|
||||||
Pattern p = Pattern.compile("^\\{([a-z]+)-(\\w{6,}),([0-9.]*)BTC,(\\w*)\\} ?(.*)");
|
Pattern p = Pattern.compile("^\\{([a-z]+)-(\\w{6,}),([0-9.]*)([A-Z]+),(\\w*)\\} ?(.*)");
|
||||||
Matcher m = p.matcher(txNotes);
|
Matcher m = p.matcher(txNotes);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
xmrtoTag = m.group(1);
|
xmrtoTag = m.group(1);
|
||||||
xmrtoKey = m.group(2);
|
xmrtoKey = m.group(2);
|
||||||
xmrtoAmount = m.group(3);
|
xmrtoAmount = m.group(3);
|
||||||
xmrtoDestination = m.group(4);
|
xmrtoCurrency = m.group(4);
|
||||||
note = m.group(5);
|
xmrtoDestination = m.group(5);
|
||||||
|
note = m.group(6);
|
||||||
} else {
|
} else {
|
||||||
note = txNotes;
|
note = txNotes;
|
||||||
}
|
}
|
||||||
@@ -62,6 +64,7 @@ public class UserNotes {
|
|||||||
xmrtoTag = order.TAG;
|
xmrtoTag = order.TAG;
|
||||||
xmrtoKey = order.getOrderId();
|
xmrtoKey = order.getOrderId();
|
||||||
xmrtoAmount = Helper.getDisplayAmount(order.getBtcAmount());
|
xmrtoAmount = Helper.getDisplayAmount(order.getBtcAmount());
|
||||||
|
xmrtoCurrency = order.getBtcCurrency();
|
||||||
xmrtoDestination = order.getBtcAddress();
|
xmrtoDestination = order.getBtcAddress();
|
||||||
} else {
|
} else {
|
||||||
xmrtoTag = null;
|
xmrtoTag = null;
|
||||||
@@ -83,7 +86,8 @@ public class UserNotes {
|
|||||||
sb.append(xmrtoKey);
|
sb.append(xmrtoKey);
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
sb.append(xmrtoAmount);
|
sb.append(xmrtoAmount);
|
||||||
sb.append("BTC,");
|
sb.append(xmrtoCurrency);
|
||||||
|
sb.append(",");
|
||||||
sb.append(xmrtoDestination);
|
sb.append(xmrtoDestination);
|
||||||
sb.append("}");
|
sb.append("}");
|
||||||
if ((note != null) && (!note.isEmpty()))
|
if ((note != null) && (!note.isEmpty()))
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -42,9 +42,8 @@ public class SendAmountWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
Listener sendListener;
|
Listener sendListener;
|
||||||
|
|
||||||
public SendAmountWizardFragment setSendListener(Listener listener) {
|
public void setSendListener(Listener listener) {
|
||||||
this.sendListener = listener;
|
this.sendListener = listener;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
|
@@ -28,16 +28,16 @@ import com.m2049r.xmrwallet.R;
|
|||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.data.TxDataBtc;
|
import com.m2049r.xmrwallet.data.TxDataBtc;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
|
||||||
import com.m2049r.xmrwallet.widget.ExchangeOtherEditText;
|
|
||||||
import com.m2049r.xmrwallet.widget.SendProgressView;
|
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftError;
|
import com.m2049r.xmrwallet.service.shift.ShiftError;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftException;
|
import com.m2049r.xmrwallet.service.shift.ShiftException;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
|
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
|
||||||
|
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
import com.m2049r.xmrwallet.widget.ExchangeOtherEditText;
|
||||||
|
import com.m2049r.xmrwallet.widget.SendProgressView;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -85,6 +85,7 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
|
|||||||
|
|
||||||
etAmount = view.findViewById(R.id.etAmount);
|
etAmount = view.findViewById(R.id.etAmount);
|
||||||
etAmount.requestFocus();
|
etAmount.requestFocus();
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,20 +131,26 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
|
|||||||
public void onResumeFragment() {
|
public void onResumeFragment() {
|
||||||
super.onResumeFragment();
|
super.onResumeFragment();
|
||||||
Timber.d("onResumeFragment()");
|
Timber.d("onResumeFragment()");
|
||||||
|
final String btcSymbol = ((TxDataBtc) sendListener.getTxData()).getBtcSymbol();
|
||||||
|
if (!btcSymbol.toLowerCase().equals(ServiceHelper.ASSET))
|
||||||
|
throw new IllegalStateException("Asset Symbol is wrong!");
|
||||||
final long funds = getTotalFunds();
|
final long funds = getTotalFunds();
|
||||||
if (!sendListener.getActivityCallback().isStreetMode()) {
|
if (!sendListener.getActivityCallback().isStreetMode()) {
|
||||||
tvFunds.setText(getString(R.string.send_available,
|
tvFunds.setText(getString(R.string.send_available,
|
||||||
Wallet.getDisplayAmount(funds)));
|
Wallet.getDisplayAmount(funds)));
|
||||||
|
//TODO
|
||||||
} else {
|
} else {
|
||||||
tvFunds.setText(getString(R.string.send_available,
|
tvFunds.setText(getString(R.string.send_available,
|
||||||
getString(R.string.unknown_amount)));
|
getString(R.string.unknown_amount)));
|
||||||
}
|
}
|
||||||
|
etAmount.setAmount("");
|
||||||
final BarcodeData data = sendListener.popBarcodeData();
|
final BarcodeData data = sendListener.popBarcodeData();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
if (data.amount != null) {
|
if (data.amount != null) {
|
||||||
etAmount.setAmount(data.amount);
|
etAmount.setAmount(data.amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
etAmount.setBaseCurrency(btcSymbol);
|
||||||
callXmrTo();
|
callXmrTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +173,9 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
|
|||||||
String min = df.format(minBtc);
|
String min = df.format(minBtc);
|
||||||
String max = df.format(maxBtc);
|
String max = df.format(maxBtc);
|
||||||
String rate = df.format(price);
|
String rate = df.format(price);
|
||||||
Spanned xmrParmText = Html.fromHtml(getString(R.string.info_send_xmrto_parms, min, max, rate));
|
final TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData();
|
||||||
|
Spanned xmrParmText = Html.fromHtml(getString(R.string.info_send_xmrto_parms,
|
||||||
|
min, max, rate, txDataBtc.getBtcSymbol()));
|
||||||
tvXmrToParms.setText(xmrParmText);
|
tvXmrToParms.setText(xmrParmText);
|
||||||
|
|
||||||
final long funds = getTotalFunds();
|
final long funds = getTotalFunds();
|
||||||
@@ -183,7 +192,8 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
|
|||||||
}
|
}
|
||||||
tvFunds.setText(getString(R.string.send_available_btc,
|
tvFunds.setText(getString(R.string.send_available_btc,
|
||||||
availXmrString,
|
availXmrString,
|
||||||
availBtcString));
|
availBtcString,
|
||||||
|
((TxDataBtc) sendListener.getTxData()).getBtcSymbol()));
|
||||||
llXmrToParms.setVisibility(View.VISIBLE);
|
llXmrToParms.setVisibility(View.VISIBLE);
|
||||||
evParams.hideProgress();
|
evParams.hideProgress();
|
||||||
});
|
});
|
||||||
@@ -246,7 +256,7 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (xmrToApi == null) {
|
if (xmrToApi == null) {
|
||||||
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(),
|
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(),
|
||||||
Helper.getXmrToBaseUrl());
|
ServiceHelper.getXmrToBaseUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,16 +29,17 @@ import com.m2049r.xmrwallet.data.TxData;
|
|||||||
import com.m2049r.xmrwallet.data.TxDataBtc;
|
import com.m2049r.xmrwallet.data.TxDataBtc;
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
|
||||||
import com.m2049r.xmrwallet.widget.SendProgressView;
|
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftError;
|
import com.m2049r.xmrwallet.service.shift.ShiftError;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftException;
|
import com.m2049r.xmrwallet.service.shift.ShiftException;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.CreateOrder;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.CreateOrder;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
|
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
import com.m2049r.xmrwallet.widget.SendProgressView;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -67,6 +68,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
private TextView tvTxBtcAmount;
|
private TextView tvTxBtcAmount;
|
||||||
private TextView tvTxBtcRate;
|
private TextView tvTxBtcRate;
|
||||||
private TextView tvTxBtcAddress;
|
private TextView tvTxBtcAddress;
|
||||||
|
private TextView tvTxBtcAddressLabel;
|
||||||
private TextView tvTxXmrToKey;
|
private TextView tvTxXmrToKey;
|
||||||
private TextView tvTxFee;
|
private TextView tvTxFee;
|
||||||
private TextView tvTxTotal;
|
private TextView tvTxTotal;
|
||||||
@@ -84,6 +86,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
R.layout.fragment_send_btc_confirm, container, false);
|
R.layout.fragment_send_btc_confirm, container, false);
|
||||||
|
|
||||||
tvTxBtcAddress = view.findViewById(R.id.tvTxBtcAddress);
|
tvTxBtcAddress = view.findViewById(R.id.tvTxBtcAddress);
|
||||||
|
tvTxBtcAddressLabel = view.findViewById(R.id.tvTxBtcAddressLabel);
|
||||||
tvTxBtcAmount = view.findViewById(R.id.tvTxBtcAmount);
|
tvTxBtcAmount = view.findViewById(R.id.tvTxBtcAmount);
|
||||||
tvTxBtcRate = view.findViewById(R.id.tvTxBtcRate);
|
tvTxBtcRate = view.findViewById(R.id.tvTxBtcRate);
|
||||||
tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey);
|
tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey);
|
||||||
@@ -259,6 +262,8 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
if (sendListener.getMode() != SendFragment.Mode.BTC) {
|
if (sendListener.getMode() != SendFragment.Mode.BTC) {
|
||||||
throw new IllegalStateException("Mode is not BTC!");
|
throw new IllegalStateException("Mode is not BTC!");
|
||||||
}
|
}
|
||||||
|
if (!((TxDataBtc) sendListener.getTxData()).getBtcSymbol().toLowerCase().equals(ServiceHelper.ASSET))
|
||||||
|
throw new IllegalStateException("Asset Symbol is wrong!");
|
||||||
Helper.hideKeyboard(getActivity());
|
Helper.hideKeyboard(getActivity());
|
||||||
llStageA.setVisibility(View.INVISIBLE);
|
llStageA.setVisibility(View.INVISIBLE);
|
||||||
evStageA.hideProgress();
|
evStageA.hideProgress();
|
||||||
@@ -392,9 +397,10 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
df.setMaximumFractionDigits(12);
|
df.setMaximumFractionDigits(12);
|
||||||
final String btcAmount = df.format(xmrtoQuote.getBtcAmount());
|
final String btcAmount = df.format(xmrtoQuote.getBtcAmount());
|
||||||
final String xmrAmountTotal = df.format(xmrtoQuote.getXmrAmount());
|
final String xmrAmountTotal = df.format(xmrtoQuote.getXmrAmount());
|
||||||
tvTxBtcAmount.setText(getString(R.string.text_send_btc_amount, btcAmount, xmrAmountTotal));
|
tvTxBtcAmount.setText(getString(R.string.text_send_btc_amount,
|
||||||
|
btcAmount, xmrAmountTotal, txDataBtc.getBtcSymbol()));
|
||||||
final String xmrPriceBtc = df.format(xmrtoQuote.getPrice());
|
final String xmrPriceBtc = df.format(xmrtoQuote.getPrice());
|
||||||
tvTxBtcRate.setText(getString(R.string.text_send_btc_rate, xmrPriceBtc));
|
tvTxBtcRate.setText(getString(R.string.text_send_btc_rate, xmrPriceBtc, txDataBtc.getBtcSymbol()));
|
||||||
hideProgress();
|
hideProgress();
|
||||||
});
|
});
|
||||||
stageB(requestQuote.getId());
|
stageB(requestQuote.getId());
|
||||||
@@ -477,13 +483,14 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData();
|
TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData();
|
||||||
// verify amount & destination
|
// verify amount & destination
|
||||||
if ((order.getBtcAmount() != txDataBtc.getBtcAmount())
|
if ((order.getBtcAmount() != txDataBtc.getBtcAmount())
|
||||||
|| (!order.getBtcAddress().equals(txDataBtc.getBtcAddress()))) {
|
|| (!txDataBtc.validateAddress(order.getBtcAddress()))) {
|
||||||
throw new IllegalStateException("Order does not fulfill quote!"); // something is terribly wrong - die
|
throw new IllegalStateException("Order does not fulfill quote!"); // something is terribly wrong - die
|
||||||
}
|
}
|
||||||
xmrtoOrder = order;
|
xmrtoOrder = order;
|
||||||
getView().post(() -> {
|
getView().post(() -> {
|
||||||
tvTxXmrToKey.setText(order.getOrderId());
|
tvTxXmrToKey.setText(order.getOrderId());
|
||||||
tvTxBtcAddress.setText(order.getBtcAddress());
|
tvTxBtcAddress.setText(order.getBtcAddress());
|
||||||
|
tvTxBtcAddressLabel.setText(getString(R.string.label_send_btc_address, txDataBtc.getBtcSymbol()));
|
||||||
hideProgress();
|
hideProgress();
|
||||||
Timber.d("Expires @ %s", order.getExpiresAt().toString());
|
Timber.d("Expires @ %s", order.getExpiresAt().toString());
|
||||||
final int timeout = (int) (order.getExpiresAt().getTime() - order.getCreatedAt().getTime()) / 1000 - 60; // -1 minute buffer
|
final int timeout = (int) (order.getExpiresAt().getTime() - order.getCreatedAt().getTime()) / 1000 - 60; // -1 minute buffer
|
||||||
@@ -561,7 +568,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (xmrToApi == null) {
|
if (xmrToApi == null) {
|
||||||
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(),
|
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(),
|
||||||
Helper.getXmrToBaseUrl());
|
ServiceHelper.getXmrToBaseUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
import com.m2049r.xmrwallet.data.Crypto;
|
||||||
import com.m2049r.xmrwallet.data.PendingTx;
|
import com.m2049r.xmrwallet.data.PendingTx;
|
||||||
import com.m2049r.xmrwallet.data.TxDataBtc;
|
import com.m2049r.xmrwallet.data.TxDataBtc;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
@@ -39,6 +40,7 @@ import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
|||||||
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
|
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -62,10 +64,10 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
|||||||
ImageButton bCopyTxId;
|
ImageButton bCopyTxId;
|
||||||
private TextView tvTxId;
|
private TextView tvTxId;
|
||||||
private TextView tvTxAddress;
|
private TextView tvTxAddress;
|
||||||
private TextView tvTxPaymentId;
|
|
||||||
private TextView tvTxAmount;
|
private TextView tvTxAmount;
|
||||||
private TextView tvTxFee;
|
private TextView tvTxFee;
|
||||||
private TextView tvXmrToAmount;
|
private TextView tvXmrToAmount;
|
||||||
|
private ImageView ivXmrToIcon;
|
||||||
private TextView tvXmrToStatus;
|
private TextView tvXmrToStatus;
|
||||||
private ImageView ivXmrToStatus;
|
private ImageView ivXmrToStatus;
|
||||||
private ImageView ivXmrToStatusBig;
|
private ImageView ivXmrToStatusBig;
|
||||||
@@ -90,13 +92,13 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tvXmrToAmount = view.findViewById(R.id.tvXmrToAmount);
|
tvXmrToAmount = view.findViewById(R.id.tvXmrToAmount);
|
||||||
|
ivXmrToIcon = view.findViewById(R.id.ivXmrToIcon);
|
||||||
tvXmrToStatus = view.findViewById(R.id.tvXmrToStatus);
|
tvXmrToStatus = view.findViewById(R.id.tvXmrToStatus);
|
||||||
ivXmrToStatus = view.findViewById(R.id.ivXmrToStatus);
|
ivXmrToStatus = view.findViewById(R.id.ivXmrToStatus);
|
||||||
ivXmrToStatusBig = view.findViewById(R.id.ivXmrToStatusBig);
|
ivXmrToStatusBig = view.findViewById(R.id.ivXmrToStatusBig);
|
||||||
|
|
||||||
tvTxId = view.findViewById(R.id.tvTxId);
|
tvTxId = view.findViewById(R.id.tvTxId);
|
||||||
tvTxAddress = view.findViewById(R.id.tvTxAddress);
|
tvTxAddress = view.findViewById(R.id.tvTxAddress);
|
||||||
tvTxPaymentId = view.findViewById(R.id.tvTxPaymentId);
|
|
||||||
tvTxAmount = view.findViewById(R.id.tvTxAmount);
|
tvTxAmount = view.findViewById(R.id.tvTxAmount);
|
||||||
tvTxFee = view.findViewById(R.id.tvTxFee);
|
tvTxFee = view.findViewById(R.id.tvTxFee);
|
||||||
|
|
||||||
@@ -150,9 +152,11 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
|||||||
NumberFormat df = NumberFormat.getInstance(Locale.US);
|
NumberFormat df = NumberFormat.getInstance(Locale.US);
|
||||||
df.setMaximumFractionDigits(12);
|
df.setMaximumFractionDigits(12);
|
||||||
String btcAmount = df.format(btcData.getBtcAmount());
|
String btcAmount = df.format(btcData.getBtcAmount());
|
||||||
tvXmrToAmount.setText(getString(R.string.info_send_xmrto_success_btc, btcAmount));
|
tvXmrToAmount.setText(getString(R.string.info_send_xmrto_success_btc, btcAmount, btcData.getBtcSymbol()));
|
||||||
//TODO btcData.getBtcAddress();
|
//TODO btcData.getBtcAddress();
|
||||||
tvTxXmrToKey.setText(btcData.getXmrtoOrderId());
|
tvTxXmrToKey.setText(btcData.getXmrtoOrderId());
|
||||||
|
final Crypto crypto = Crypto.withSymbol(btcData.getBtcSymbol());
|
||||||
|
ivXmrToIcon.setImageResource(crypto.getIconEnabledId());
|
||||||
tvXmrToSupport.setOnClickListener(v -> {
|
tvXmrToSupport.setOnClickListener(v -> {
|
||||||
Uri orderUri = getXmrToApi().getQueryOrderUri(btcData.getXmrtoOrderId());
|
Uri orderUri = getXmrToApi().getQueryOrderUri(btcData.getXmrtoOrderId());
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, orderUri);
|
Intent intent = new Intent(Intent.ACTION_VIEW, orderUri);
|
||||||
@@ -211,7 +215,7 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
|||||||
statusResource = R.drawable.ic_error_red_24dp;
|
statusResource = R.drawable.ic_error_red_24dp;
|
||||||
pbXmrto.getIndeterminateDrawable().setColorFilter(0xff8b0000, android.graphics.PorterDuff.Mode.MULTIPLY);
|
pbXmrto.getIndeterminateDrawable().setColorFilter(0xff8b0000, android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||||
} else if (status.isSent() || status.isPaid()) {
|
} else if (status.isSent() || status.isPaid()) {
|
||||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_sent));
|
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_sent, btcData.getBtcSymbol()));
|
||||||
statusResource = R.drawable.ic_success_green_24dp;
|
statusResource = R.drawable.ic_success_green_24dp;
|
||||||
pbXmrto.getIndeterminateDrawable().setColorFilter(0xFF417505, android.graphics.PorterDuff.Mode.MULTIPLY);
|
pbXmrto.getIndeterminateDrawable().setColorFilter(0xFF417505, android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||||
} else if (status.isWaiting()) {
|
} else if (status.isWaiting()) {
|
||||||
@@ -228,6 +232,7 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
|||||||
ivXmrToStatus.setImageResource(statusResource);
|
ivXmrToStatus.setImageResource(statusResource);
|
||||||
if (status.isTerminal()) {
|
if (status.isTerminal()) {
|
||||||
pbXmrto.setVisibility(View.INVISIBLE);
|
pbXmrto.setVisibility(View.INVISIBLE);
|
||||||
|
ivXmrToIcon.setVisibility(View.GONE);
|
||||||
ivXmrToStatus.setVisibility(View.GONE);
|
ivXmrToStatus.setVisibility(View.GONE);
|
||||||
ivXmrToStatusBig.setImageResource(statusResource);
|
ivXmrToStatusBig.setImageResource(statusResource);
|
||||||
ivXmrToStatusBig.setVisibility(View.VISIBLE);
|
ivXmrToStatusBig.setVisibility(View.VISIBLE);
|
||||||
@@ -241,7 +246,7 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (xmrToApi == null) {
|
if (xmrToApi == null) {
|
||||||
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(),
|
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(),
|
||||||
Helper.getXmrToBaseUrl());
|
ServiceHelper.getXmrToBaseUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
@@ -92,8 +93,6 @@ public class SendFragment extends Fragment
|
|||||||
void setOnUriScannedListener(OnUriScannedListener onUriScannedListener);
|
void setOnUriScannedListener(OnUriScannedListener onUriScannedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EditText etDummy;
|
|
||||||
|
|
||||||
private View llNavBar;
|
private View llNavBar;
|
||||||
private DotBar dotBar;
|
private DotBar dotBar;
|
||||||
private Button bPrev;
|
private Button bPrev;
|
||||||
@@ -101,7 +100,7 @@ public class SendFragment extends Fragment
|
|||||||
|
|
||||||
private Button bDone;
|
private Button bDone;
|
||||||
|
|
||||||
static private int MAX_FALLBACK = Integer.MAX_VALUE;
|
static private final int MAX_FALLBACK = Integer.MAX_VALUE;
|
||||||
|
|
||||||
public static SendFragment newInstance(String uri) {
|
public static SendFragment newInstance(String uri) {
|
||||||
SendFragment f = new SendFragment();
|
SendFragment f = new SendFragment();
|
||||||
@@ -166,28 +165,18 @@ public class SendFragment extends Fragment
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bPrev.setOnClickListener(new View.OnClickListener() {
|
bPrev.setOnClickListener(v -> spendViewPager.previous());
|
||||||
public void onClick(View v) {
|
|
||||||
spendViewPager.previous();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bNext.setOnClickListener(new View.OnClickListener() {
|
bNext.setOnClickListener(v -> spendViewPager.next());
|
||||||
public void onClick(View v) {
|
|
||||||
spendViewPager.next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bDone.setOnClickListener(new View.OnClickListener() {
|
bDone.setOnClickListener(v -> {
|
||||||
public void onClick(View v) {
|
Timber.d("bDone.onClick");
|
||||||
Timber.d("bDone.onClick");
|
activityCallback.onFragmentDone();
|
||||||
activityCallback.onFragmentDone();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
updatePosition(0);
|
updatePosition(0);
|
||||||
|
|
||||||
etDummy = view.findViewById(R.id.etDummy);
|
final EditText etDummy = view.findViewById(R.id.etDummy);
|
||||||
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
etDummy.requestFocus();
|
etDummy.requestFocus();
|
||||||
Helper.hideKeyboard(getActivity());
|
Helper.hideKeyboard(getActivity());
|
||||||
@@ -197,7 +186,7 @@ public class SendFragment extends Fragment
|
|||||||
String uri = args.getString(WalletActivity.REQUEST_URI);
|
String uri = args.getString(WalletActivity.REQUEST_URI);
|
||||||
Timber.d("URI: %s", uri);
|
Timber.d("URI: %s", uri);
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
barcodeData = BarcodeData.fromQrCode(uri);
|
barcodeData = BarcodeData.fromString(uri);
|
||||||
Timber.d("barcodeData: %s", barcodeData != null ? barcodeData.toString() : "null");
|
Timber.d("barcodeData: %s", barcodeData != null ? barcodeData.toString() : "null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,7 +225,7 @@ public class SendFragment extends Fragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(@NonNull Context context) {
|
||||||
Timber.d("onAttach %s", context);
|
Timber.d("onAttach %s", context);
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
if (context instanceof Listener) {
|
if (context instanceof Listener) {
|
||||||
@@ -300,12 +289,7 @@ public class SendFragment extends Fragment
|
|||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Mode " + String.valueOf(aMode) + " unknown!");
|
throw new IllegalArgumentException("Mode " + String.valueOf(aMode) + " unknown!");
|
||||||
}
|
}
|
||||||
getView().post(new Runnable() {
|
getView().post(() -> pagerAdapter.notifyDataSetChanged());
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
pagerAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Timber.d("New Mode = %s", mode.toString());
|
Timber.d("New Mode = %s", mode.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,8 +322,9 @@ public class SendFragment extends Fragment
|
|||||||
return numPages;
|
return numPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Object instantiateItem(ViewGroup container, int position) {
|
public Object instantiateItem(@NonNull ViewGroup container, int position) {
|
||||||
Timber.d("instantiateItem %d", position);
|
Timber.d("instantiateItem %d", position);
|
||||||
SendWizardFragment fragment = (SendWizardFragment) super.instantiateItem(container, position);
|
SendWizardFragment fragment = (SendWizardFragment) super.instantiateItem(container, position);
|
||||||
myFragments.put(position, new WeakReference<>(fragment));
|
myFragments.put(position, new WeakReference<>(fragment));
|
||||||
@@ -347,20 +332,21 @@ public class SendFragment extends Fragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||||
Timber.d("destroyItem %d", position);
|
Timber.d("destroyItem %d", position);
|
||||||
myFragments.remove(position);
|
myFragments.remove(position);
|
||||||
super.destroyItem(container, position, object);
|
super.destroyItem(container, position, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SendWizardFragment getFragment(int position) {
|
public SendWizardFragment getFragment(int position) {
|
||||||
WeakReference ref = myFragments.get(position);
|
WeakReference<SendWizardFragment> ref = myFragments.get(position);
|
||||||
if (ref != null)
|
if (ref != null)
|
||||||
return myFragments.get(position).get();
|
return myFragments.get(position).get();
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public SendWizardFragment getItem(int position) {
|
public SendWizardFragment getItem(int position) {
|
||||||
Timber.d("getItem(%d) CREATE", position);
|
Timber.d("getItem(%d) CREATE", position);
|
||||||
@@ -415,7 +401,7 @@ public class SendFragment extends Fragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemPosition(Object object) {
|
public int getItemPosition(@NonNull Object object) {
|
||||||
Timber.d("getItemPosition %s", String.valueOf(object));
|
Timber.d("getItemPosition %s", String.valueOf(object));
|
||||||
if (object instanceof SendAddressWizardFragment) {
|
if (object instanceof SendAddressWizardFragment) {
|
||||||
// keep these pages
|
// keep these pages
|
||||||
|
@@ -17,18 +17,20 @@
|
|||||||
package com.m2049r.xmrwallet.layout;
|
package com.m2049r.xmrwallet.layout;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
import com.m2049r.xmrwallet.data.Crypto;
|
||||||
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.data.UserNotes;
|
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -141,7 +143,13 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
|
|
||||||
UserNotes userNotes = new UserNotes(infoItem.notes);
|
UserNotes userNotes = new UserNotes(infoItem.notes);
|
||||||
if (userNotes.xmrtoKey != null) {
|
if (userNotes.xmrtoKey != null) {
|
||||||
ivTxType.setVisibility(View.VISIBLE);
|
final Crypto crypto = Crypto.withSymbol(userNotes.xmrtoCurrency);
|
||||||
|
if (crypto != null) {
|
||||||
|
ivTxType.setImageResource(crypto.getIconEnabledId());
|
||||||
|
ivTxType.setVisibility(View.VISIBLE);
|
||||||
|
} else {// otherwirse pretend we don't know it's a shift
|
||||||
|
ivTxType.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ivTxType.setVisibility(View.GONE); // gives us more space for the amount
|
ivTxType.setVisibility(View.GONE); // gives us more space for the amount
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,8 @@ import java.util.Date;
|
|||||||
public interface CreateOrder {
|
public interface CreateOrder {
|
||||||
String TAG = "side";
|
String TAG = "side";
|
||||||
|
|
||||||
|
String getBtcCurrency();
|
||||||
|
|
||||||
double getBtcAmount();
|
double getBtcAmount();
|
||||||
|
|
||||||
String getBtcAddress();
|
String getBtcAddress();
|
||||||
|
@@ -23,8 +23,6 @@ import androidx.annotation.NonNull;
|
|||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
|
|
||||||
public interface SideShiftApi {
|
public interface SideShiftApi {
|
||||||
|
|
||||||
String ASSET = "btc";
|
|
||||||
int QUERY_INTERVAL = 5000; // ms
|
int QUERY_INTERVAL = 5000; // ms
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -25,6 +25,7 @@ import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
|||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.CreateOrder;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.CreateOrder;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
||||||
import com.m2049r.xmrwallet.util.DateHelper;
|
import com.m2049r.xmrwallet.util.DateHelper;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@@ -35,6 +36,8 @@ import java.util.Date;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
class CreateOrderImpl implements CreateOrder {
|
class CreateOrderImpl implements CreateOrder {
|
||||||
|
@Getter
|
||||||
|
private final String btcCurrency;
|
||||||
@Getter
|
@Getter
|
||||||
private final double btcAmount;
|
private final double btcAmount;
|
||||||
@Getter
|
@Getter
|
||||||
@@ -56,9 +59,10 @@ class CreateOrderImpl implements CreateOrder {
|
|||||||
// sanity checks
|
// sanity checks
|
||||||
final String depositMethod = jsonObject.getString("depositMethodId");
|
final String depositMethod = jsonObject.getString("depositMethodId");
|
||||||
final String settleMethod = jsonObject.getString("settleMethodId");
|
final String settleMethod = jsonObject.getString("settleMethodId");
|
||||||
if (!"xmr".equals(depositMethod) || !SideShiftApi.ASSET.equals(settleMethod))
|
if (!"xmr".equals(depositMethod) || !ServiceHelper.ASSET.equals(settleMethod))
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
|
||||||
|
btcCurrency = settleMethod.toUpperCase();
|
||||||
btcAmount = jsonObject.getDouble("settleAmount");
|
btcAmount = jsonObject.getDouble("settleAmount");
|
||||||
JSONObject settleAddress = jsonObject.getJSONObject("settleAddress");
|
JSONObject settleAddress = jsonObject.getJSONObject("settleAddress");
|
||||||
btcAddress = settleAddress.getString("address");
|
btcAddress = settleAddress.getString("address");
|
||||||
|
@@ -23,6 +23,7 @@ import com.m2049r.xmrwallet.service.shift.ShiftApiCall;
|
|||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@@ -53,7 +54,7 @@ class QueryOrderParametersImpl implements QueryOrderParameters {
|
|||||||
|
|
||||||
public static void call(@NonNull final ShiftApiCall api,
|
public static void call(@NonNull final ShiftApiCall api,
|
||||||
@NonNull final ShiftCallback<QueryOrderParameters> callback) {
|
@NonNull final ShiftCallback<QueryOrderParameters> callback) {
|
||||||
api.call("pairs/xmr/" + SideShiftApi.ASSET, new NetworkCallback() {
|
api.call("pairs/xmr/" + ServiceHelper.ASSET, new NetworkCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(JSONObject jsonObject) {
|
public void onSuccess(JSONObject jsonObject) {
|
||||||
try {
|
try {
|
||||||
|
@@ -24,6 +24,7 @@ import com.m2049r.xmrwallet.util.DateHelper;
|
|||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@@ -55,7 +56,7 @@ class RequestQuoteImpl implements RequestQuote {
|
|||||||
// sanity checks
|
// sanity checks
|
||||||
final String depositMethod = jsonObject.getString("depositMethod");
|
final String depositMethod = jsonObject.getString("depositMethod");
|
||||||
final String settleMethod = jsonObject.getString("settleMethod");
|
final String settleMethod = jsonObject.getString("settleMethod");
|
||||||
if (!"xmr".equals(depositMethod) || !SideShiftApi.ASSET.equals(settleMethod))
|
if (!"xmr".equals(depositMethod) || !ServiceHelper.ASSET.equals(settleMethod))
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
|
||||||
btcAmount = jsonObject.getDouble("settleAmount");
|
btcAmount = jsonObject.getDouble("settleAmount");
|
||||||
@@ -106,7 +107,7 @@ class RequestQuoteImpl implements RequestQuote {
|
|||||||
static JSONObject createRequest(final double xmrAmount) throws JSONException {
|
static JSONObject createRequest(final double xmrAmount) throws JSONException {
|
||||||
final JSONObject jsonObject = new JSONObject();
|
final JSONObject jsonObject = new JSONObject();
|
||||||
jsonObject.put("depositMethod", "xmr");
|
jsonObject.put("depositMethod", "xmr");
|
||||||
jsonObject.put("settleMethod", SideShiftApi.ASSET);
|
jsonObject.put("settleMethod", ServiceHelper.ASSET);
|
||||||
// #sideshift is silly and likes numbers as strings
|
// #sideshift is silly and likes numbers as strings
|
||||||
String amount = AmountFormatter.format(xmrAmount);
|
String amount = AmountFormatter.format(xmrAmount);
|
||||||
jsonObject.put("depositAmount", amount);
|
jsonObject.put("depositAmount", amount);
|
||||||
|
@@ -323,15 +323,6 @@ public class Helper {
|
|||||||
return ShakeAnimation;
|
return ShakeAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public HttpUrl getXmrToBaseUrl() {
|
|
||||||
if ((WalletManager.getInstance() == null)
|
|
||||||
|| (WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet)) {
|
|
||||||
throw new IllegalStateException("Only mainnet not supported");
|
|
||||||
} else {
|
|
||||||
return HttpUrl.parse("https://sideshift.ai/api/v1/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static char[] HexArray = "0123456789ABCDEF".toCharArray();
|
private final static char[] HexArray = "0123456789ABCDEF".toCharArray();
|
||||||
|
|
||||||
public static String bytesToHex(byte[] data) {
|
public static String bytesToHex(byte[] data) {
|
||||||
@@ -639,10 +630,6 @@ public class Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public ExchangeApi getExchangeApi() {
|
|
||||||
return new com.m2049r.xmrwallet.service.exchange.krakenEcb.ExchangeApiImpl(OkHttpHelper.getOkHttpClient());
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Action {
|
public interface Action {
|
||||||
boolean run();
|
boolean run();
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ package com.m2049r.xmrwallet.util;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
|
import com.m2049r.xmrwallet.data.Crypto;
|
||||||
|
|
||||||
import org.jitsi.dnssec.validator.ValidatingResolver;
|
import org.jitsi.dnssec.validator.ValidatingResolver;
|
||||||
import org.xbill.DNS.DClass;
|
import org.xbill.DNS.DClass;
|
||||||
@@ -52,7 +53,6 @@ public class OpenAliasHelper {
|
|||||||
public static final String OA1_NAME = "recipient_name";
|
public static final String OA1_NAME = "recipient_name";
|
||||||
public static final String OA1_DESCRIPTION = "tx_description";
|
public static final String OA1_DESCRIPTION = "tx_description";
|
||||||
public static final String OA1_AMOUNT = "tx_amount";
|
public static final String OA1_AMOUNT = "tx_amount";
|
||||||
public static final String OA1_PAYMENTID = "tx_payment_id";
|
|
||||||
|
|
||||||
public static final int DNS_LOOKUP_TIMEOUT = 2500; // ms
|
public static final int DNS_LOOKUP_TIMEOUT = 2500; // ms
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public class OpenAliasHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface OnResolvedListener {
|
public interface OnResolvedListener {
|
||||||
void onResolved(Map<BarcodeData.Asset, BarcodeData> dataMap);
|
void onResolved(Map<Crypto, BarcodeData> dataMap);
|
||||||
|
|
||||||
void onFailure();
|
void onFailure();
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ public class OpenAliasHelper {
|
|||||||
public void onPostExecute(Boolean success) {
|
public void onPostExecute(Boolean success) {
|
||||||
if (resolvedListener != null)
|
if (resolvedListener != null)
|
||||||
if (success) {
|
if (success) {
|
||||||
Map<BarcodeData.Asset, BarcodeData> dataMap = new HashMap<>();
|
Map<Crypto, BarcodeData> dataMap = new HashMap<>();
|
||||||
for (String txt : txts) {
|
for (String txt : txts) {
|
||||||
BarcodeData bc = BarcodeData.parseOpenAlias(txt, dnssec);
|
BarcodeData bc = BarcodeData.parseOpenAlias(txt, dnssec);
|
||||||
if (bc != null) {
|
if (bc != null) {
|
||||||
|
@@ -0,0 +1,24 @@
|
|||||||
|
package com.m2049r.xmrwallet.util;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
||||||
|
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
|
public class ServiceHelper {
|
||||||
|
public static String ASSET = null;
|
||||||
|
|
||||||
|
static public HttpUrl getXmrToBaseUrl() {
|
||||||
|
if ((WalletManager.getInstance() == null)
|
||||||
|
|| (WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet)) {
|
||||||
|
throw new IllegalStateException("Only mainnet not supported");
|
||||||
|
} else {
|
||||||
|
return HttpUrl.parse("https://sideshift.ai/api/v1/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public ExchangeApi getExchangeApi() {
|
||||||
|
return new com.m2049r.xmrwallet.service.exchange.krakenEcb.ExchangeApiImpl(OkHttpHelper.getOkHttpClient());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,51 @@
|
|||||||
|
package com.m2049r.xmrwallet.util.validator;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public enum BitcoinAddressType {
|
||||||
|
BTC(Type.BTC, Type.BTC_BECH32_PREFIX),
|
||||||
|
LTC(Type.LTC, Type.LTC_BECH32_PREFIX),
|
||||||
|
DASH(Type.DASH, null),
|
||||||
|
DOGE(Type.DOGE, null);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final byte[] production;
|
||||||
|
@Getter
|
||||||
|
private final byte[] testnet;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String productionBech32Prefix;
|
||||||
|
@Getter
|
||||||
|
private final String testnetBech32Prefix;
|
||||||
|
|
||||||
|
public boolean hasBech32() {
|
||||||
|
return productionBech32Prefix != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBech32Prefix(boolean testnet) {
|
||||||
|
return testnet ? testnetBech32Prefix : productionBech32Prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitcoinAddressType(byte[][] types, String[] bech32Prefix) {
|
||||||
|
production = types[0];
|
||||||
|
testnet = types[1];
|
||||||
|
if (bech32Prefix != null) {
|
||||||
|
productionBech32Prefix = bech32Prefix[0];
|
||||||
|
testnetBech32Prefix = bech32Prefix[1];
|
||||||
|
} else {
|
||||||
|
productionBech32Prefix = null;
|
||||||
|
testnetBech32Prefix = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Java is silly and doesn't allow array initializers in the construction
|
||||||
|
private static class Type {
|
||||||
|
private static final byte[][] BTC = {{0x00, 0x05}, {0x6f, (byte) 0xc4}};
|
||||||
|
private static final String[] BTC_BECH32_PREFIX = {"bc", "tb"};
|
||||||
|
private static final byte[][] LTC = {{0x30, 0x05, 0x32}, {0x6f, (byte) 0xc4, 0x3a}};
|
||||||
|
private static final String[] LTC_BECH32_PREFIX = {"ltc", "tltc"};
|
||||||
|
private static final byte[][] DASH = {{0x4c, 0x10}, {(byte) 0x8c, 0x13}};
|
||||||
|
private static final byte[][] DOGE = {{0x1e, 0x16}, {0x71, (byte) 0xc4}};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -14,10 +14,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet.util;
|
package com.m2049r.xmrwallet.util.validator;
|
||||||
|
|
||||||
// mostly based on https://rosettacode.org/wiki/Bitcoin/address_validation#Java
|
// mostly based on https://rosettacode.org/wiki/Bitcoin/address_validation#Java
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.data.Crypto;
|
||||||
import com.m2049r.xmrwallet.model.NetworkType;
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
|
||||||
@@ -28,28 +29,47 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class BitcoinAddressValidator {
|
public class BitcoinAddressValidator {
|
||||||
|
|
||||||
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||||
|
|
||||||
public static boolean validate(String addrress) {
|
public static Crypto validate(String address) {
|
||||||
boolean testnet = WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet;
|
for (BitcoinAddressType type : BitcoinAddressType.values()) {
|
||||||
if (validate(addrress, testnet)) return true;
|
if (validate(address, type))
|
||||||
return validateBech32Segwit(addrress, testnet);
|
return Crypto.valueOf(type.name());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validate(String addrress, boolean testnet) {
|
// just for tests
|
||||||
|
public static boolean validateBTC(String addrress, boolean testnet) {
|
||||||
|
return validate(addrress, BitcoinAddressType.BTC, testnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validate(String addrress, BitcoinAddressType type, boolean testnet) {
|
||||||
|
if (validate(addrress, testnet ? type.getTestnet() : type.getProduction()))
|
||||||
|
return true;
|
||||||
|
if (type.hasBech32())
|
||||||
|
return validateBech32Segwit(addrress, type, testnet);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validate(String addrress, BitcoinAddressType type) {
|
||||||
|
final boolean testnet = WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet;
|
||||||
|
return validate(addrress, type, testnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validate(String addrress, byte[] addressTypes) {
|
||||||
if (addrress.length() < 26 || addrress.length() > 35)
|
if (addrress.length() < 26 || addrress.length() > 35)
|
||||||
return false;
|
return false;
|
||||||
byte[] decoded = decodeBase58To25Bytes(addrress);
|
byte[] decoded = decodeBase58To25Bytes(addrress);
|
||||||
if (decoded == null)
|
if (decoded == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int v = decoded[0] & 0xFF;
|
int v = decoded[0] & 0xFF;
|
||||||
if (!testnet) {
|
boolean nok = true;
|
||||||
if ((v != 0x00) && (v != 0x05)) return false;
|
for (byte b : addressTypes) {
|
||||||
} else {
|
nok = nok && (v != (b & 0xFF));
|
||||||
if ((v != 0x6f) && (v != 0xc4)) return false;
|
|
||||||
}
|
}
|
||||||
|
if (nok) return false;
|
||||||
|
|
||||||
byte[] hash1 = sha256(Arrays.copyOfRange(decoded, 0, 21));
|
byte[] hash1 = sha256(Arrays.copyOfRange(decoded, 0, 21));
|
||||||
byte[] hash2 = sha256(hash1);
|
byte[] hash2 = sha256(hash1);
|
||||||
@@ -95,18 +115,20 @@ public class BitcoinAddressValidator {
|
|||||||
|
|
||||||
private static final String DATA_CHARS = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
private static final String DATA_CHARS = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
||||||
|
|
||||||
public static boolean validateBech32Segwit(String bech32, boolean testnet) {
|
public static boolean validateBech32Segwit(String bech32, BitcoinAddressType type, boolean testnet) {
|
||||||
if (!bech32.equals(bech32.toLowerCase()) && !bech32.equals(bech32.toUpperCase())) {
|
if (!bech32.equals(bech32.toLowerCase()) && !bech32.equals(bech32.toUpperCase())) {
|
||||||
return false; // mixing upper and lower case not allowed
|
return false; // mixing upper and lower case not allowed
|
||||||
}
|
}
|
||||||
bech32 = bech32.toLowerCase();
|
bech32 = bech32.toLowerCase();
|
||||||
|
|
||||||
if (testnet && !bech32.startsWith("tb1")) return false;
|
if (!bech32.startsWith(type.getBech32Prefix(testnet))) return false;
|
||||||
if (!testnet && !bech32.startsWith("bc1")) return false;
|
|
||||||
|
|
||||||
if ((bech32.length() < 14) || (bech32.length() > 74)) return false;
|
final int hrpLength = type.getBech32Prefix(testnet).length();
|
||||||
int mod = bech32.length() % 8;
|
|
||||||
if ((mod == 0) || (mod == 3) || (mod == 5)) return false;
|
if ((bech32.length() < (12 + hrpLength)) || (bech32.length() > (72 + hrpLength)))
|
||||||
|
return false;
|
||||||
|
int mod = (bech32.length() - hrpLength) % 8;
|
||||||
|
if ((mod == 6) || (mod == 1) || (mod == 3)) return false;
|
||||||
|
|
||||||
int sep = -1;
|
int sep = -1;
|
||||||
final byte[] bytes = bech32.getBytes(StandardCharsets.US_ASCII);
|
final byte[] bytes = bech32.getBytes(StandardCharsets.US_ASCII);
|
||||||
@@ -117,7 +139,7 @@ public class BitcoinAddressValidator {
|
|||||||
if (bytes[i] == 49) sep = i; // 49 := '1' in ASCII
|
if (bytes[i] == 49) sep = i; // 49 := '1' in ASCII
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sep != 2) return false; // bech32 always has len(hrp)==2
|
if (sep != hrpLength) return false;
|
||||||
if (sep > bytes.length - 7) {
|
if (sep > bytes.length - 7) {
|
||||||
return false; // min 6 bytes data
|
return false; // min 6 bytes data
|
||||||
}
|
}
|
||||||
@@ -158,12 +180,12 @@ public class BitcoinAddressValidator {
|
|||||||
private static byte[] hrpExpand(byte[] hrp) {
|
private static byte[] hrpExpand(byte[] hrp) {
|
||||||
final byte[] expanded = new byte[(2 * hrp.length) + 1];
|
final byte[] expanded = new byte[(2 * hrp.length) + 1];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int j = 0; j < hrp.length; j++) {
|
for (byte b : hrp) {
|
||||||
expanded[i++] = (byte) (hrp[j] >> 5);
|
expanded[i++] = (byte) (b >> 5);
|
||||||
}
|
}
|
||||||
expanded[i++] = 0;
|
expanded[i++] = 0;
|
||||||
for (int j = 0; j < hrp.length; j++) {
|
for (byte b : hrp) {
|
||||||
expanded[i++] = (byte) (hrp[j] & 0x1f);
|
expanded[i++] = (byte) (b & 0x1f);
|
||||||
}
|
}
|
||||||
return expanded;
|
return expanded;
|
||||||
}
|
}
|
||||||
@@ -195,4 +217,4 @@ public class BitcoinAddressValidator {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 m2049r er 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.util.validator;
|
||||||
|
|
||||||
|
// mostly based on https://github.com/ognus/wallet-address-validator/blob/master/src/ethereum_validator.js
|
||||||
|
|
||||||
|
import com.theromus.sha.Keccak;
|
||||||
|
import com.theromus.sha.Parameters;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class EthAddressValidator {
|
||||||
|
static private final Pattern ETH_ADDRESS = Pattern.compile("^0x[0-9a-fA-F]{40}$");
|
||||||
|
static private final Pattern ETH_ALLLOWER = Pattern.compile("^0x[0-9a-f]{40}$");
|
||||||
|
static private final Pattern ETH_ALLUPPER = Pattern.compile("^0x[0-9A-F]{40}$");
|
||||||
|
|
||||||
|
public static boolean validate(String address) {
|
||||||
|
// Check if it has the basic requirements of an address
|
||||||
|
if (!ETH_ADDRESS.matcher(address).matches())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If it's all small caps or all all caps, return true
|
||||||
|
if (ETH_ALLLOWER.matcher(address).matches() || ETH_ALLUPPER.matcher(address).matches()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise check each case
|
||||||
|
return validateChecksum(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean validateChecksum(String address) {
|
||||||
|
// Check each case
|
||||||
|
address = address.substring(2); // strip 0x
|
||||||
|
|
||||||
|
Keccak keccak = new Keccak();
|
||||||
|
final byte[] addressHash = keccak.getHash(
|
||||||
|
address.toLowerCase().getBytes(StandardCharsets.US_ASCII),
|
||||||
|
Parameters.KECCAK_256);
|
||||||
|
for (int i = 0; i < 40; i++) {
|
||||||
|
boolean upper = (addressHash[i / 2] & ((i % 2) == 0 ? 128 : 8)) != 0;
|
||||||
|
char c = address.charAt(i);
|
||||||
|
if (Character.isAlphabetic(c)) {
|
||||||
|
if (Character.isUpperCase(c) && !upper) return false;
|
||||||
|
if (Character.isLowerCase(c) && upper) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -40,6 +40,7 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
|||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -184,6 +185,12 @@ public class ExchangeEditText extends LinearLayout {
|
|||||||
|
|
||||||
private boolean isInitialized = false;
|
private boolean isInitialized = false;
|
||||||
|
|
||||||
|
void postInitialize() {
|
||||||
|
setInitialSpinnerSelections(sCurrencyA, sCurrencyB);
|
||||||
|
isInitialized = true;
|
||||||
|
startExchange();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@@ -212,14 +219,7 @@ public class ExchangeEditText extends LinearLayout {
|
|||||||
setCurrencyAdapter(sCurrencyA);
|
setCurrencyAdapter(sCurrencyA);
|
||||||
setCurrencyAdapter(sCurrencyB);
|
setCurrencyAdapter(sCurrencyB);
|
||||||
|
|
||||||
post(new Runnable() {
|
post(this::postInitialize);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setInitialSpinnerSelections(sCurrencyA, sCurrencyB);
|
|
||||||
isInitialized = true;
|
|
||||||
startExchange();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// make progress circle gray
|
// make progress circle gray
|
||||||
pbExchange.getIndeterminateDrawable().
|
pbExchange.getIndeterminateDrawable().
|
||||||
@@ -296,7 +296,7 @@ public class ExchangeEditText extends LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
|
private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi();
|
||||||
|
|
||||||
// starts exchange through exchange api
|
// starts exchange through exchange api
|
||||||
void startExchange() {
|
void startExchange() {
|
||||||
|
@@ -25,6 +25,8 @@ import android.os.Looper;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||||
@@ -46,12 +48,15 @@ public class ExchangeOtherEditText extends ExchangeEditText {
|
|||||||
|
|
||||||
public void setExchangeRate(double rate) {
|
public void setExchangeRate(double rate) {
|
||||||
exchangeRate = rate;
|
exchangeRate = rate;
|
||||||
post(new Runnable() {
|
post(this::startExchange);
|
||||||
@Override
|
}
|
||||||
public void run() {
|
|
||||||
startExchange();
|
public void setBaseCurrency(@NonNull String symbol) {
|
||||||
}
|
if (symbol.equals(baseCurrency)) return;
|
||||||
});
|
baseCurrency = symbol;
|
||||||
|
setCurrencyAdapter(sCurrencyA);
|
||||||
|
setCurrencyAdapter(sCurrencyB);
|
||||||
|
post(this::postInitialize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBaseCurrency(Context context, AttributeSet attrs) {
|
private void setBaseCurrency(Context context, AttributeSet attrs) {
|
||||||
@@ -184,12 +189,7 @@ public class ExchangeOtherEditText extends ExchangeEditText {
|
|||||||
@Override
|
@Override
|
||||||
public void onError(final Exception e) {
|
public void onError(final Exception e) {
|
||||||
Timber.e(e.getLocalizedMessage());
|
Timber.e(e.getLocalizedMessage());
|
||||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
new Handler(Looper.getMainLooper()).post(() -> exchangeFailed());
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
exchangeFailed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user