mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-13 16:10:51 +02:00
Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4ca9328949 | ||
![]() |
08b5a87f19 | ||
![]() |
445d8acc38 | ||
![]() |
9385ac8c31 | ||
![]() |
4c7ebd8402 | ||
![]() |
67f3c5f948 | ||
![]() |
cd67a7e2bf | ||
![]() |
fa5fe313ea | ||
![]() |
ed4957a3cc | ||
![]() |
3e0eeebd51 | ||
![]() |
0d213a1eb4 | ||
![]() |
39d048fd5e | ||
![]() |
1a5d2d0399 | ||
![]() |
028057a672 | ||
![]() |
909ff8ca5e | ||
![]() |
ffd61e4495 | ||
![]() |
003dee382e | ||
![]() |
be0498c67d | ||
![]() |
06227a4a83 | ||
![]() |
4409087bd0 | ||
![]() |
965e52d8a5 | ||
![]() |
beba0f497b | ||
![]() |
9d1827ff0d | ||
![]() |
c04b192753 | ||
![]() |
888b5edaec | ||
![]() |
5ee5a81926 | ||
![]() |
c4e361a873 | ||
![]() |
dba6cb057e | ||
![]() |
9e1167c5b9 | ||
![]() |
12546a1ade | ||
![]() |
e9313bc235 | ||
![]() |
7e9bf84640 | ||
![]() |
94f87a5193 | ||
![]() |
8a8fc5ec9e | ||
![]() |
036d4ebf6c | ||
![]() |
c6d4de8599 | ||
![]() |
2ef7f8571c | ||
![]() |
d2612a26e5 | ||
![]() |
7e14572756 | ||
![]() |
6f840dcacf |
@@ -3,11 +3,13 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
working_directory: ~/code
|
working_directory: ~/code
|
||||||
docker:
|
docker:
|
||||||
- image: bitriseio/android-ndk
|
- image: circleci/android:api-28-ndk
|
||||||
environment:
|
environment:
|
||||||
JVM_OPTS: -Xmx3200m
|
JVM_OPTS: -Xmx3200m
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- run: yes | sdkmanager --licenses || exit 0
|
||||||
|
- run: yes | sdkmanager --update || exit 0
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
|
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
|
||||||
- run:
|
- run:
|
||||||
|
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
workspace.xml
|
|
||||||
markdown-*
|
|
||||||
misc.xml
|
|
1
.idea/.name
generated
1
.idea/.name
generated
@@ -1 +0,0 @@
|
|||||||
xmrwallet
|
|
22
.idea/compiler.xml
generated
22
.idea/compiler.xml
generated
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<resourceExtensions />
|
|
||||||
<wildcardResourcePatterns>
|
|
||||||
<entry name="!?*.java" />
|
|
||||||
<entry name="!?*.form" />
|
|
||||||
<entry name="!?*.class" />
|
|
||||||
<entry name="!?*.groovy" />
|
|
||||||
<entry name="!?*.scala" />
|
|
||||||
<entry name="!?*.flex" />
|
|
||||||
<entry name="!?*.kt" />
|
|
||||||
<entry name="!?*.clj" />
|
|
||||||
<entry name="!?*.aj" />
|
|
||||||
</wildcardResourcePatterns>
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile default="true" name="Default" enabled="false">
|
|
||||||
<processorPath useClasspath="true" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
3
.idea/copyright/profiles_settings.xml
generated
3
.idea/copyright/profiles_settings.xml
generated
@@ -1,3 +0,0 @@
|
|||||||
<component name="CopyrightManager">
|
|
||||||
<settings default="" />
|
|
||||||
</component>
|
|
19
.idea/gradle.xml
generated
19
.idea/gradle.xml
generated
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<option name="disableWrapperSourceDistributionNotification" value="true" />
|
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
<option value="$PROJECT_DIR$/app" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
9
.idea/modules.xml
generated
9
.idea/modules.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/xmrwallet.iml" filepath="$PROJECT_DIR$/xmrwallet.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
12
.idea/runConfigurations.xml
generated
12
.idea/runConfigurations.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@@ -7,8 +7,8 @@ android {
|
|||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 157
|
versionCode 166
|
||||||
versionName "1.10.7 'Node-O-matiC'"
|
versionName "1.10.16 'Node-O-matiC'"
|
||||||
|
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
@@ -113,10 +113,12 @@ dependencies {
|
|||||||
implementation 'dnsjava:dnsjava:2.1.8'
|
implementation 'dnsjava:dnsjava:2.1.8'
|
||||||
implementation 'org.jitsi:dnssecjava:1.1.3'
|
implementation 'org.jitsi:dnssecjava:1.1.3'
|
||||||
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
||||||
|
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
||||||
|
|
||||||
testImplementation "junit:junit:$rootProject.ext.junitVersion"
|
testImplementation "junit:junit:$rootProject.ext.junitVersion"
|
||||||
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
||||||
testImplementation "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
testImplementation "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
||||||
testImplementation 'org.json:json:20140107'
|
testImplementation 'org.json:json:20180813'
|
||||||
testImplementation 'net.jodah:concurrentunit:0.4.2'
|
testImplementation 'net.jodah:concurrentunit:0.4.4'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,22 @@
|
|||||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter android:label="@string/app_name">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<data android:scheme="monero" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter android:label="@string/app_name">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<data android:scheme="bitcoin" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||||
android:resource="@xml/usb_device_filter" />
|
android:resource="@xml/usb_device_filter" />
|
||||||
|
@@ -43,6 +43,9 @@ Copyright (c) 2014 Dushyanth Maguluru
|
|||||||
<h3>AndroidLicensesPage (https://github.com/adamsp/AndroidLicensesPage)</h3>
|
<h3>AndroidLicensesPage (https://github.com/adamsp/AndroidLicensesPage)</h3>
|
||||||
Copyright (c) 2013 Adam Speakman
|
Copyright (c) 2013 Adam Speakman
|
||||||
|
|
||||||
|
<h3>SwipeableRecyclerView (https://github.com/brnunes/SwipeableRecyclerView)</h3>
|
||||||
|
Copyright (c) 2015 Bruno R. Nunes
|
||||||
|
|
||||||
<h3>Apache License, Version 2.0, January 2004</h3>
|
<h3>Apache License, Version 2.0, January 2004</h3>
|
||||||
http://www.apache.org/licenses/<br/>
|
http://www.apache.org/licenses/<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
@@ -417,8 +417,8 @@ Java_com_m2049r_xmrwallet_model_WalletManager_verifyWalletPassword(JNIEnv *env,
|
|||||||
//virtual int queryWalletHardware(const std::string &keys_file_name, const std::string &password) const = 0;
|
//virtual int queryWalletHardware(const std::string &keys_file_name, const std::string &password) const = 0;
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_queryWalletDeviceJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_queryWalletDeviceJ(JNIEnv *env, jobject instance,
|
||||||
jstring keys_file_name,
|
jstring keys_file_name,
|
||||||
jstring password) {
|
jstring password) {
|
||||||
const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, NULL);
|
const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
Bitmonero::Wallet::Device device_type;
|
Bitmonero::Wallet::Device device_type;
|
||||||
@@ -442,12 +442,6 @@ Java_com_m2049r_xmrwallet_model_WalletManager_findWallets(JNIEnv *env, jobject i
|
|||||||
return cpp2java(env, walletPaths);
|
return cpp2java(env, walletPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_getErrorString(JNIEnv *env, jobject instance) {
|
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
|
||||||
return env->NewStringUTF(wallet->errorString().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO virtual bool checkPayment(const std::string &address, const std::string &txid, const std::string &txkey, const std::string &daemon_address, uint64_t &received, uint64_t &height, std::string &error) const = 0;
|
//TODO virtual bool checkPayment(const std::string &address, const std::string &txid, const std::string &txkey, const std::string &daemon_address, uint64_t &received, uint64_t &height, std::string &error) const = 0;
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
@@ -1185,10 +1179,11 @@ jobject newTransferList(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
|||||||
|
|
||||||
jobject newTransactionInfo(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
jobject newTransactionInfo(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||||
jmethodID c = env->GetMethodID(class_TransactionInfo, "<init>",
|
jmethodID c = env->GetMethodID(class_TransactionInfo, "<init>",
|
||||||
"(IZZJJJLjava/lang/String;JLjava/lang/String;IIJLjava/util/List;)V");
|
"(IZZJJJLjava/lang/String;JLjava/lang/String;IIJLjava/lang/String;Ljava/util/List;)V");
|
||||||
jobject transfers = newTransferList(env, info);
|
jobject transfers = newTransferList(env, info);
|
||||||
jstring _hash = env->NewStringUTF(info->hash().c_str());
|
jstring _hash = env->NewStringUTF(info->hash().c_str());
|
||||||
jstring _paymentId = env->NewStringUTF(info->paymentId().c_str());
|
jstring _paymentId = env->NewStringUTF(info->paymentId().c_str());
|
||||||
|
jstring _label = env->NewStringUTF(info->label().c_str());
|
||||||
uint32_t subaddrIndex = 0;
|
uint32_t subaddrIndex = 0;
|
||||||
if (info->direction() == Bitmonero::TransactionInfo::Direction_In)
|
if (info->direction() == Bitmonero::TransactionInfo::Direction_In)
|
||||||
subaddrIndex = *(info->subaddrIndex().begin());
|
subaddrIndex = *(info->subaddrIndex().begin());
|
||||||
@@ -1205,6 +1200,7 @@ jobject newTransactionInfo(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
|||||||
info->subaddrAccount(),
|
info->subaddrAccount(),
|
||||||
subaddrIndex,
|
subaddrIndex,
|
||||||
info->confirmations(),
|
info->confirmations(),
|
||||||
|
_label,
|
||||||
transfers);
|
transfers);
|
||||||
env->DeleteLocalRef(transfers);
|
env->DeleteLocalRef(transfers);
|
||||||
env->DeleteLocalRef(_hash);
|
env->DeleteLocalRef(_hash);
|
||||||
@@ -1397,7 +1393,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_setLogLevel(JNIEnv *env, jclass cl
|
|||||||
*
|
*
|
||||||
* @return length of received data in response or -1 if error
|
* @return length of received data in response or -1 if error
|
||||||
*/
|
*/
|
||||||
int LedgerExchange(
|
int LedgerExchange(
|
||||||
unsigned char *command,
|
unsigned char *command,
|
||||||
unsigned int cmd_len,
|
unsigned int cmd_len,
|
||||||
unsigned char *response,
|
unsigned char *response,
|
||||||
|
@@ -18,7 +18,6 @@ package com.m2049r.levin.scanner;
|
|||||||
|
|
||||||
import com.m2049r.xmrwallet.data.NodeInfo;
|
import com.m2049r.xmrwallet.data.NodeInfo;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -176,9 +175,9 @@ public class Dispatcher implements PeerRetriever.OnGetPeers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void retrievePeers(PeerRetriever peer) {
|
private void retrievePeers(PeerRetriever peer) {
|
||||||
for (InetSocketAddress socketAddress : peer.getPeers()) {
|
for (LevinPeer levinPeer : peer.getPeers()) {
|
||||||
if (getMorePeers())
|
if (getMorePeers())
|
||||||
retrievePeer(new NodeInfo(socketAddress));
|
retrievePeer(new NodeInfo(levinPeer));
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
23
app/src/main/java/com/m2049r/levin/scanner/LevinPeer.java
Normal file
23
app/src/main/java/com/m2049r/levin/scanner/LevinPeer.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package com.m2049r.levin.scanner;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
public class LevinPeer {
|
||||||
|
final public InetSocketAddress socketAddress;
|
||||||
|
final public int version;
|
||||||
|
final public long height;
|
||||||
|
final public String top;
|
||||||
|
|
||||||
|
|
||||||
|
public InetSocketAddress getSocketAddress() {
|
||||||
|
return socketAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
LevinPeer(InetAddress address, int port, int version, long height, String top) {
|
||||||
|
this.socketAddress = new InetSocketAddress(address, port);
|
||||||
|
this.version = version;
|
||||||
|
this.height = height;
|
||||||
|
this.top = top;
|
||||||
|
}
|
||||||
|
}
|
@@ -28,7 +28,6 @@ import java.io.DataInput;
|
|||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -45,7 +44,7 @@ public class PeerRetriever implements Callable<PeerRetriever> {
|
|||||||
static final private byte[] HANDSHAKE = handshakeRequest().asByteArray();
|
static final private byte[] HANDSHAKE = handshakeRequest().asByteArray();
|
||||||
static final private byte[] FLAGS_RESP = flagsResponse().asByteArray();
|
static final private byte[] FLAGS_RESP = flagsResponse().asByteArray();
|
||||||
|
|
||||||
final private List<InetSocketAddress> peers = new ArrayList<>();
|
final private List<LevinPeer> peers = new ArrayList<>();
|
||||||
|
|
||||||
private NodeInfo nodeInfo;
|
private NodeInfo nodeInfo;
|
||||||
private OnGetPeers onGetPeersCallback;
|
private OnGetPeers onGetPeersCallback;
|
||||||
@@ -67,7 +66,7 @@ public class PeerRetriever implements Callable<PeerRetriever> {
|
|||||||
return !peers.isEmpty();
|
return !peers.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<InetSocketAddress> getPeers() {
|
public List<LevinPeer> getPeers() {
|
||||||
return peers;
|
return peers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,12 +106,18 @@ public class PeerRetriever implements Callable<PeerRetriever> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void readAddressList(Section section) {
|
private void readAddressList(Section section) {
|
||||||
|
Section data = (Section) section.get("payload_data");
|
||||||
|
int topVersion = (Integer) data.get("top_version");
|
||||||
|
long currentHeight = (Long) data.get("current_height");
|
||||||
|
String topId = HexHelper.bytesToHex((byte[]) data.get("top_id"));
|
||||||
|
Timber.d("PAYLOAD_DATA %d/%d/%s", topVersion, currentHeight, topId);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Section> peerList = (List<Section>) section.get("local_peerlist_new");
|
List<Section> peerList = (List<Section>) section.get("local_peerlist_new");
|
||||||
if (peerList != null) {
|
if (peerList != null) {
|
||||||
for (Section peer : peerList) {
|
for (Section peer : peerList) {
|
||||||
Section adr = (Section) peer.get("adr");
|
Section adr = (Section) peer.get("adr");
|
||||||
Byte type = (Byte) adr.get("type");
|
Integer type = (Integer) adr.get("type");
|
||||||
if ((type == null) || (type != 1))
|
if ((type == null) || (type != 1))
|
||||||
continue;
|
continue;
|
||||||
Section addr = (Section) adr.get("addr");
|
Section addr = (Section) adr.get("addr");
|
||||||
@@ -121,7 +126,7 @@ public class PeerRetriever implements Callable<PeerRetriever> {
|
|||||||
Integer ip = (Integer) addr.get("m_ip");
|
Integer ip = (Integer) addr.get("m_ip");
|
||||||
if (ip == null)
|
if (ip == null)
|
||||||
continue;
|
continue;
|
||||||
Short sport = (Short) addr.get("m_port");
|
Integer sport = (Integer) addr.get("m_port");
|
||||||
if (sport == null)
|
if (sport == null)
|
||||||
continue;
|
continue;
|
||||||
int port = sport;
|
int port = sport;
|
||||||
@@ -133,7 +138,7 @@ public class PeerRetriever implements Callable<PeerRetriever> {
|
|||||||
&& !inet.isLoopbackAddress()
|
&& !inet.isLoopbackAddress()
|
||||||
&& !inet.isMulticastAddress()
|
&& !inet.isMulticastAddress()
|
||||||
&& !inet.isLinkLocalAddress()) {
|
&& !inet.isLinkLocalAddress()) {
|
||||||
peers.add(new InetSocketAddress(inet, port));
|
peers.add(new LevinPeer(inet, port, topVersion, currentHeight, topId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -83,9 +83,11 @@ public class LevinReader {
|
|||||||
case Section.SERIALIZE_TYPE_INT32:
|
case Section.SERIALIZE_TYPE_INT32:
|
||||||
return in.readInt();
|
return in.readInt();
|
||||||
case Section.SERIALIZE_TYPE_UINT16:
|
case Section.SERIALIZE_TYPE_UINT16:
|
||||||
|
return in.readUnsignedShort();
|
||||||
case Section.SERIALIZE_TYPE_INT16:
|
case Section.SERIALIZE_TYPE_INT16:
|
||||||
return in.readShort();
|
return in.readShort();
|
||||||
case Section.SERIALIZE_TYPE_UINT8:
|
case Section.SERIALIZE_TYPE_UINT8:
|
||||||
|
return in.readUnsignedByte();
|
||||||
case Section.SERIALIZE_TYPE_INT8:
|
case Section.SERIALIZE_TYPE_INT8:
|
||||||
return in.readByte();
|
return in.readByte();
|
||||||
case Section.SERIALIZE_TYPE_OBJECT:
|
case Section.SERIALIZE_TYPE_OBJECT:
|
||||||
|
@@ -92,6 +92,11 @@ public class LoginActivity extends BaseActivity
|
|||||||
|
|
||||||
Set<NodeInfo> favouriteNodes = new HashSet<>();
|
Set<NodeInfo> favouriteNodes = new HashSet<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeInfo getNode() {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(NodeInfo node) {
|
public void setNode(NodeInfo node) {
|
||||||
if ((node != null) && (node.getNetworkType() != WalletManager.getInstance().getNetworkType()))
|
if ((node != null) && (node.getNetworkType() != WalletManager.getInstance().getNetworkType()))
|
||||||
@@ -264,7 +269,11 @@ public class LoginActivity extends BaseActivity
|
|||||||
} else {
|
} else {
|
||||||
Timber.i("Waiting for permissions");
|
Timber.i("Waiting for permissions");
|
||||||
}
|
}
|
||||||
processUsbIntent(getIntent());
|
|
||||||
|
// try intents
|
||||||
|
Intent intent = getIntent();
|
||||||
|
if (!processUsbIntent(intent))
|
||||||
|
processUriIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean checkServiceRunning() {
|
boolean checkServiceRunning() {
|
||||||
@@ -711,6 +720,10 @@ public class LoginActivity extends BaseActivity
|
|||||||
intent.putExtra(WalletActivity.REQUEST_PW, walletPassword);
|
intent.putExtra(WalletActivity.REQUEST_PW, walletPassword);
|
||||||
intent.putExtra(WalletActivity.REQUEST_FINGERPRINT_USED, fingerprintUsed);
|
intent.putExtra(WalletActivity.REQUEST_FINGERPRINT_USED, fingerprintUsed);
|
||||||
intent.putExtra(WalletActivity.REQUEST_STREETMODE, streetmode);
|
intent.putExtra(WalletActivity.REQUEST_STREETMODE, streetmode);
|
||||||
|
if (uri != null) {
|
||||||
|
intent.putExtra(WalletActivity.REQUEST_URI, uri);
|
||||||
|
uri = null; // use only once
|
||||||
|
}
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1380,7 +1393,7 @@ public class LoginActivity extends BaseActivity
|
|||||||
processUsbIntent(intent);
|
processUsbIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processUsbIntent(Intent intent) {
|
private boolean processUsbIntent(Intent intent) {
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
|
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@@ -1393,6 +1406,21 @@ public class LoginActivity extends BaseActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String uri = null;
|
||||||
|
|
||||||
|
private void processUriIntent(Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (Intent.ACTION_VIEW.equals(action)) {
|
||||||
|
synchronized (this) {
|
||||||
|
uri = intent.getDataString();
|
||||||
|
Timber.d("URI Intent %s", uri);
|
||||||
|
HelpFragment.display(getSupportFragmentManager(), R.string.help_uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -99,6 +99,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
|
|
||||||
void setNode(NodeInfo node);
|
void setNode(NodeInfo node);
|
||||||
|
|
||||||
|
NodeInfo getNode();
|
||||||
|
|
||||||
Set<NodeInfo> getFavouriteNodes();
|
Set<NodeInfo> getFavouriteNodes();
|
||||||
|
|
||||||
boolean hasLedger();
|
boolean hasLedger();
|
||||||
@@ -128,7 +130,11 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
activityCallback.setTitle(null);
|
activityCallback.setTitle(null);
|
||||||
activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS);
|
activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS);
|
||||||
activityCallback.showNet();
|
activityCallback.showNet();
|
||||||
findBestNode();
|
NodeInfo node = activityCallback.getNode();
|
||||||
|
if (node == null)
|
||||||
|
findBestNode();
|
||||||
|
else
|
||||||
|
showNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -181,7 +187,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (activityCallback.getFavouriteNodes().isEmpty())
|
if (activityCallback.getFavouriteNodes().isEmpty())
|
||||||
activityCallback.onNodePrefs();
|
startNodePrefs();
|
||||||
else
|
else
|
||||||
findBestNode();
|
findBestNode();
|
||||||
}
|
}
|
||||||
@@ -191,8 +197,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
view.findViewById(R.id.ibOption).setOnClickListener(new View.OnClickListener() {
|
view.findViewById(R.id.ibOption).setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (activityCallback != null)
|
startNodePrefs();
|
||||||
activityCallback.onNodePrefs();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -476,4 +481,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
tvNodeAddress.setText(nodeInfo.getAddress());
|
tvNodeAddress.setText(nodeInfo.getAddress());
|
||||||
tvNodeAddress.setVisibility(View.VISIBLE);
|
tvNodeAddress.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startNodePrefs() {
|
||||||
|
activityCallback.setNode(null);
|
||||||
|
activityCallback.onNodePrefs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,7 @@ 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.Helper;
|
||||||
import com.m2049r.xmrwallet.util.UserNotes;
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -60,6 +60,7 @@ public class TxFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TextView tvAccount;
|
private TextView tvAccount;
|
||||||
|
private TextView tvAddress;
|
||||||
private TextView tvTxTimestamp;
|
private TextView tvTxTimestamp;
|
||||||
private TextView tvTxId;
|
private TextView tvTxId;
|
||||||
private TextView tvTxKey;
|
private TextView tvTxKey;
|
||||||
@@ -90,6 +91,7 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxAmountBtc = view.findViewById(R.id.tvTxAmountBtc);
|
tvTxAmountBtc = view.findViewById(R.id.tvTxAmountBtc);
|
||||||
|
|
||||||
tvAccount = view.findViewById(R.id.tvAccount);
|
tvAccount = view.findViewById(R.id.tvAccount);
|
||||||
|
tvAddress = view.findViewById(R.id.tvAddress);
|
||||||
tvTxTimestamp = view.findViewById(R.id.tvTxTimestamp);
|
tvTxTimestamp = view.findViewById(R.id.tvTxTimestamp);
|
||||||
tvTxId = view.findViewById(R.id.tvTxId);
|
tvTxId = view.findViewById(R.id.tvTxId);
|
||||||
tvTxKey = view.findViewById(R.id.tvTxKey);
|
tvTxKey = view.findViewById(R.id.tvTxKey);
|
||||||
@@ -219,12 +221,16 @@ public class TxFragment extends Fragment {
|
|||||||
if (info.txKey == null) {
|
if (info.txKey == null) {
|
||||||
info.txKey = activityCallback.getTxKey(info.hash);
|
info.txKey = activityCallback.getTxKey(info.hash);
|
||||||
}
|
}
|
||||||
|
if (info.address == null) {
|
||||||
|
info.address = activityCallback.getTxAddress(info.account, info.subaddress);
|
||||||
|
}
|
||||||
loadNotes(info);
|
loadNotes(info);
|
||||||
|
|
||||||
activityCallback.setSubtitle(getString(R.string.tx_title));
|
activityCallback.setSubtitle(getString(R.string.tx_title));
|
||||||
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||||
|
|
||||||
tvAccount.setText(getString(R.string.tx_account_formatted, info.account, info.subaddress));
|
tvAccount.setText(getString(R.string.tx_account_formatted, info.account, info.subaddress));
|
||||||
|
tvAddress.setText(info.address);
|
||||||
|
|
||||||
tvTxTimestamp.setText(TS_FORMATTER.format(new Date(info.timestamp * 1000)));
|
tvTxTimestamp.setText(TS_FORMATTER.format(new Date(info.timestamp * 1000)));
|
||||||
tvTxId.setText(info.hash);
|
tvTxId.setText(info.hash);
|
||||||
@@ -331,6 +337,8 @@ public class TxFragment extends Fragment {
|
|||||||
|
|
||||||
String getTxNotes(String hash);
|
String getTxNotes(String hash);
|
||||||
|
|
||||||
|
String getTxAddress(int major, int minor);
|
||||||
|
|
||||||
void onSetNote(String txId, String notes);
|
void onSetNote(String txId, String notes);
|
||||||
|
|
||||||
void setToolbarButton(int type);
|
void setToolbarButton(int type);
|
||||||
|
@@ -47,6 +47,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
import com.m2049r.xmrwallet.dialog.CreditsFragment;
|
import com.m2049r.xmrwallet.dialog.CreditsFragment;
|
||||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||||
import com.m2049r.xmrwallet.fragment.send.SendAddressWizardFragment;
|
import com.m2049r.xmrwallet.fragment.send.SendAddressWizardFragment;
|
||||||
@@ -59,7 +60,6 @@ import com.m2049r.xmrwallet.model.WalletManager;
|
|||||||
import com.m2049r.xmrwallet.service.WalletService;
|
import com.m2049r.xmrwallet.service.WalletService;
|
||||||
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 com.m2049r.xmrwallet.util.UserNotes;
|
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -81,6 +81,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
public static final String REQUEST_PW = "pw";
|
public static final String REQUEST_PW = "pw";
|
||||||
public static final String REQUEST_FINGERPRINT_USED = "fingerprint";
|
public static final String REQUEST_FINGERPRINT_USED = "fingerprint";
|
||||||
public static final String REQUEST_STREETMODE = "streetmode";
|
public static final String REQUEST_STREETMODE = "streetmode";
|
||||||
|
public static final String REQUEST_URI = "uri";
|
||||||
|
|
||||||
private NavigationView accountsView;
|
private NavigationView accountsView;
|
||||||
private DrawerLayout drawer;
|
private DrawerLayout drawer;
|
||||||
@@ -92,6 +93,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
|
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
private String uri = null;
|
||||||
|
|
||||||
private long streetMode = 0;
|
private long streetMode = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -144,6 +147,9 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
} else {
|
} else {
|
||||||
streetMode = 0;
|
streetMode = 0;
|
||||||
}
|
}
|
||||||
|
final WalletFragment walletFragment = (WalletFragment)
|
||||||
|
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
||||||
|
if (walletFragment != null) walletFragment.resetDismissedTransactions();
|
||||||
updateAccountsBalance();
|
updateAccountsBalance();
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
}
|
}
|
||||||
@@ -168,6 +174,11 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
return getWallet().getUserNote(txId);
|
return getWallet().getUserNote(txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTxAddress(int major, int minor) {
|
||||||
|
return getWallet().getSubaddress(major, minor);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
@@ -183,6 +194,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
// we can set the streetmode height AFTER opening the wallet
|
// we can set the streetmode height AFTER opening the wallet
|
||||||
requestStreetMode = extras.getBoolean(REQUEST_STREETMODE);
|
requestStreetMode = extras.getBoolean(REQUEST_STREETMODE);
|
||||||
password = extras.getString(REQUEST_PW);
|
password = extras.getString(REQUEST_PW);
|
||||||
|
uri = extras.getString(REQUEST_URI);
|
||||||
connectWalletService(walletId, password);
|
connectWalletService(walletId, password);
|
||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
@@ -281,7 +293,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
showNet();
|
showNet();
|
||||||
}
|
}
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onEnableStreetMode() {
|
private void onEnableStreetMode() {
|
||||||
@@ -505,7 +516,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendRequest() {
|
public void onSendRequest() {
|
||||||
replaceFragment(new SendFragment(), null, null);
|
replaceFragment(SendFragment.newInstance(uri), null, null);
|
||||||
|
uri = null; // only use uri once
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -951,8 +963,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
}
|
}
|
||||||
if (!processed || (onUriScannedListener == null)) {
|
if (!processed || (onUriScannedListener == null)) {
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_what), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.nfc_tag_read_what), Toast.LENGTH_LONG).show();
|
||||||
} else {
|
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_success), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@ import android.widget.ProgressBar;
|
|||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.github.brnunes.swipeablerecyclerview.SwipeableRecyclerViewTouchListener;
|
||||||
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
@@ -73,6 +74,12 @@ public class WalletFragment extends Fragment
|
|||||||
|
|
||||||
private Spinner sCurrency;
|
private Spinner sCurrency;
|
||||||
|
|
||||||
|
private List<String> dismissedTransactions = new ArrayList<>();
|
||||||
|
|
||||||
|
public void resetDismissedTransactions() {
|
||||||
|
dismissedTransactions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -116,9 +123,44 @@ public class WalletFragment extends Fragment
|
|||||||
|
|
||||||
RecyclerView recyclerView = view.findViewById(R.id.list);
|
RecyclerView recyclerView = view.findViewById(R.id.list);
|
||||||
|
|
||||||
this.adapter = new TransactionInfoAdapter(getActivity(), this);
|
adapter = new TransactionInfoAdapter(getActivity(), this);
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
|
SwipeableRecyclerViewTouchListener swipeTouchListener =
|
||||||
|
new SwipeableRecyclerViewTouchListener(recyclerView,
|
||||||
|
new SwipeableRecyclerViewTouchListener.SwipeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean canSwipeLeft(int position) {
|
||||||
|
return activityCallback.isStreetMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canSwipeRight(int position) {
|
||||||
|
return activityCallback.isStreetMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
|
||||||
|
for (int position : reverseSortedPositions) {
|
||||||
|
dismissedTransactions.add(adapter.getItem(position).hash);
|
||||||
|
adapter.removeItem(position);
|
||||||
|
}
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
|
||||||
|
for (int position : reverseSortedPositions) {
|
||||||
|
dismissedTransactions.add(adapter.getItem(position).hash);
|
||||||
|
adapter.removeItem(position);
|
||||||
|
}
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
recyclerView.addOnItemTouchListener(swipeTouchListener);
|
||||||
|
|
||||||
|
|
||||||
bSend.setOnClickListener(new View.OnClickListener() {
|
bSend.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -294,7 +336,9 @@ public class WalletFragment extends Fragment
|
|||||||
Timber.d("StreetHeight=%d", streetHeight);
|
Timber.d("StreetHeight=%d", streetHeight);
|
||||||
for (TransactionInfo info : wallet.getHistory().getAll()) {
|
for (TransactionInfo info : wallet.getHistory().getAll()) {
|
||||||
Timber.d("TxHeight=%d", info.blockheight);
|
Timber.d("TxHeight=%d", info.blockheight);
|
||||||
if (info.isPending || (info.blockheight >= streetHeight)) list.add(info);
|
if ((info.isPending || (info.blockheight >= streetHeight))
|
||||||
|
&& !dismissedTransactions.contains(info.hash))
|
||||||
|
list.add(info);
|
||||||
}
|
}
|
||||||
adapter.setInfos(list);
|
adapter.setInfos(list);
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
|
@@ -21,7 +21,10 @@ import android.net.Uri;
|
|||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
import com.m2049r.xmrwallet.util.BitcoinAddressValidator;
|
||||||
import com.m2049r.xmrwallet.util.OpenAliasHelper;
|
import com.m2049r.xmrwallet.util.OpenAliasHelper;
|
||||||
|
import com.m2049r.xmrwallet.util.PaymentProtocolHelper;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -37,8 +40,10 @@ public class BarcodeData {
|
|||||||
public static final String OA_XMR_ASSET = "xmr";
|
public static final String OA_XMR_ASSET = "xmr";
|
||||||
public static final String OA_BTC_ASSET = "btc";
|
public static final String OA_BTC_ASSET = "btc";
|
||||||
|
|
||||||
static final String BTC_SCHEME = "bitcoin:";
|
static final String BTC_SCHEME = "bitcoin";
|
||||||
|
static final String BTC_DESCRIPTION = "message";
|
||||||
static final String BTC_AMOUNT = "amount";
|
static final String BTC_AMOUNT = "amount";
|
||||||
|
static final String BTC_BIP70_PARM = "r";
|
||||||
|
|
||||||
public enum Asset {
|
public enum Asset {
|
||||||
XMR, BTC
|
XMR, BTC
|
||||||
@@ -47,56 +52,55 @@ public class BarcodeData {
|
|||||||
public enum Security {
|
public enum Security {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
OA_NO_DNSSEC,
|
OA_NO_DNSSEC,
|
||||||
OA_DNSSEC
|
OA_DNSSEC,
|
||||||
|
BIP70
|
||||||
}
|
}
|
||||||
|
|
||||||
public Asset asset = null;
|
final public Asset asset;
|
||||||
public String addressName = null;
|
final public String address;
|
||||||
public String address = null;
|
final public String addressName;
|
||||||
public String paymentId = null;
|
final public String paymentId;
|
||||||
public String amount = null;
|
final public String amount;
|
||||||
public String description = null;
|
final public String description;
|
||||||
public Security security = Security.NORMAL;
|
final public Security security;
|
||||||
|
final public String bip70;
|
||||||
public BarcodeData(String uri) {
|
|
||||||
this.asset = asset;
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BarcodeData(Asset asset, String address) {
|
public BarcodeData(Asset asset, String address) {
|
||||||
this.asset = asset;
|
this(asset, address, null, null, null, null, Security.NORMAL);
|
||||||
this.address = address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BarcodeData(Asset asset, String address, String amount) {
|
public BarcodeData(Asset asset, String address, String amount) {
|
||||||
this.asset = asset;
|
this(asset, address, null, null, null, amount, Security.NORMAL);
|
||||||
this.address = address;
|
}
|
||||||
this.amount = amount;
|
|
||||||
|
public BarcodeData(Asset asset, String address, String amount, String description, Security security) {
|
||||||
|
this(asset, address, null, null, description, amount, security);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BarcodeData(Asset asset, String address, String paymentId, String amount) {
|
public BarcodeData(Asset asset, String address, String paymentId, String amount) {
|
||||||
this.asset = asset;
|
this(asset, address, null, paymentId, null, amount, Security.NORMAL);
|
||||||
this.address = address;
|
|
||||||
this.paymentId = paymentId;
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BarcodeData(Asset asset, String address, String paymentId, String description, String amount) {
|
public BarcodeData(Asset asset, String address, String paymentId, String description, String amount) {
|
||||||
|
this(asset, address, null, paymentId, description, amount, Security.NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BarcodeData(Asset asset, String address, String addressName, String paymentId, String description, String amount, Security security) {
|
||||||
|
this(asset, address, addressName, null, paymentId, description, amount, security);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BarcodeData(Asset asset, String address, String addressName, String bip70, String paymentId, String description, String amount, Security security) {
|
||||||
this.asset = asset;
|
this.asset = asset;
|
||||||
this.address = address;
|
this.address = address;
|
||||||
|
this.bip70 = bip70;
|
||||||
|
this.addressName = addressName;
|
||||||
this.paymentId = paymentId;
|
this.paymentId = paymentId;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
|
||||||
|
|
||||||
public void setAddressName(String name) {
|
|
||||||
addressName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecurity(Security security) {
|
|
||||||
this.security = security;
|
this.security = security;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Uri getUri() {
|
public Uri getUri() {
|
||||||
return Uri.parse(getUriString());
|
return Uri.parse(getUriString());
|
||||||
}
|
}
|
||||||
@@ -134,13 +138,17 @@ public class BarcodeData {
|
|||||||
if (bcData == null) {
|
if (bcData == null) {
|
||||||
bcData = parseBitcoinUri(qrCode);
|
bcData = parseBitcoinUri(qrCode);
|
||||||
}
|
}
|
||||||
|
// check for btc payment uri (like bitpay)
|
||||||
|
if (bcData == null) {
|
||||||
|
bcData = parseBitcoinPaymentUrl(qrCode);
|
||||||
|
}
|
||||||
// check for naked btc address
|
// check for naked btc address
|
||||||
if (bcData == null) {
|
if (bcData == null) {
|
||||||
bcData = parseBitcoinNaked(qrCode);
|
bcData = parseBitcoinNaked(qrCode);
|
||||||
}
|
}
|
||||||
// check for OpenAlias
|
// check for OpenAlias
|
||||||
if (bcData == null) {
|
if (bcData == null) {
|
||||||
bcData = parseOpenAlias(qrCode);
|
bcData = parseOpenAlias(qrCode, false);
|
||||||
}
|
}
|
||||||
return bcData;
|
return bcData;
|
||||||
}
|
}
|
||||||
@@ -175,7 +183,11 @@ public class BarcodeData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
String address = monero.getPath();
|
String address = monero.getPath();
|
||||||
|
|
||||||
String paymentId = parms.get(XMR_PAYMENTID);
|
String paymentId = parms.get(XMR_PAYMENTID);
|
||||||
|
// deal with empty payment_id created by non-spec-conforming apps
|
||||||
|
if ((paymentId != null) && paymentId.isEmpty()) paymentId = null;
|
||||||
|
|
||||||
String description = parms.get(XMR_DESCRIPTION);
|
String description = parms.get(XMR_DESCRIPTION);
|
||||||
String amount = parms.get(XMR_AMOUNT);
|
String amount = parms.get(XMR_AMOUNT);
|
||||||
if (amount != null) {
|
if (amount != null) {
|
||||||
@@ -212,19 +224,28 @@ public class BarcodeData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bitcoin:mpQ84J43EURZHkCnXbyQ4PpNDLLBqdsMW2?amount=0.01
|
// bitcoin:mpQ84J43EURZHkCnXbyQ4PpNDLLBqdsMW2?amount=0.01
|
||||||
static public BarcodeData parseBitcoinUri(String uri) {
|
// bitcoin:?r=https://bitpay.com/i/xxx
|
||||||
Timber.d("parseBitcoinUri=%s", uri);
|
static public BarcodeData parseBitcoinUri(String uriString) {
|
||||||
|
Timber.d("parseBitcoinUri=%s", uriString);
|
||||||
|
|
||||||
if (uri == null) return null;
|
if (uriString == null) return null;
|
||||||
|
URI uri;
|
||||||
|
try {
|
||||||
|
uri = new URI(uriString);
|
||||||
|
} catch (URISyntaxException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!uri.isOpaque() ||
|
||||||
|
!uri.getScheme().equals(BTC_SCHEME)) return null;
|
||||||
|
|
||||||
if (!uri.startsWith(BTC_SCHEME)) return null;
|
String[] parts = uri.getRawSchemeSpecificPart().split("[?]");
|
||||||
|
if ((parts.length <= 0) || (parts.length > 2)) {
|
||||||
String noScheme = uri.substring(BTC_SCHEME.length());
|
Timber.d("invalid number of parts %d", parts.length);
|
||||||
Uri bitcoin = Uri.parse(noScheme);
|
return null;
|
||||||
|
}
|
||||||
Map<String, String> parms = new HashMap<>();
|
Map<String, String> parms = new HashMap<>();
|
||||||
String query = bitcoin.getQuery();
|
if (parts.length == 2) {
|
||||||
if (query != null) {
|
String[] args = parts[1].split("&");
|
||||||
String[] args = query.split("&");
|
|
||||||
for (String arg : args) {
|
for (String arg : args) {
|
||||||
String[] namevalue = arg.split("=");
|
String[] namevalue = arg.split("=");
|
||||||
if (namevalue.length == 0) {
|
if (namevalue.length == 0) {
|
||||||
@@ -234,9 +255,26 @@ public class BarcodeData {
|
|||||||
namevalue.length > 1 ? Uri.decode(namevalue[1]) : "");
|
namevalue.length > 1 ? Uri.decode(namevalue[1]) : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String address = bitcoin.getPath();
|
String description = parms.get(BTC_DESCRIPTION);
|
||||||
|
String address = parts[0]; // no need to decode as there can bo no special characters
|
||||||
|
if (address.isEmpty()) { // possibly a BIP72 uri
|
||||||
|
String bip70 = parms.get(BTC_BIP70_PARM);
|
||||||
|
if (bip70 == null) {
|
||||||
|
Timber.d("no address and can't find pp url");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!PaymentProtocolHelper.isHttp(bip70)) {
|
||||||
|
Timber.d("[%s] is not http url", bip70);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new BarcodeData(BarcodeData.Asset.BTC, null, null, bip70, null, description, null, Security.NORMAL);
|
||||||
|
}
|
||||||
|
if (!BitcoinAddressValidator.validate(address)) {
|
||||||
|
Timber.d("BTC address (%s) invalid", address);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
String amount = parms.get(BTC_AMOUNT);
|
String amount = parms.get(BTC_AMOUNT);
|
||||||
if (amount != null) {
|
if ((amount != null) && (!amount.isEmpty())) {
|
||||||
try {
|
try {
|
||||||
Double.parseDouble(amount);
|
Double.parseDouble(amount);
|
||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
@@ -244,11 +282,22 @@ public class BarcodeData {
|
|||||||
return null; // we have an amount but its not a number!
|
return null; // we have an amount but its not a number!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!BitcoinAddressValidator.validate(address)) {
|
return new BarcodeData(BarcodeData.Asset.BTC, address, null, description, amount);
|
||||||
Timber.d("address invalid");
|
}
|
||||||
|
|
||||||
|
// https://bitpay.com/invoice?id=xxx
|
||||||
|
// https://bitpay.com/i/KbMdd4EhnLXSbpWGKsaeo6
|
||||||
|
static public BarcodeData parseBitcoinPaymentUrl(String url) {
|
||||||
|
Timber.d("parseBitcoinUri=%s", url);
|
||||||
|
|
||||||
|
if (url == null) return null;
|
||||||
|
|
||||||
|
if (!PaymentProtocolHelper.isHttp(url)) {
|
||||||
|
Timber.d("[%s] is not http url", url);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new BarcodeData(BarcodeData.Asset.BTC, address, amount);
|
|
||||||
|
return new BarcodeData(Asset.BTC, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public BarcodeData parseBitcoinNaked(String address) {
|
static public BarcodeData parseBitcoinNaked(String address) {
|
||||||
@@ -264,7 +313,7 @@ public class BarcodeData {
|
|||||||
return new BarcodeData(BarcodeData.Asset.BTC, address);
|
return new BarcodeData(BarcodeData.Asset.BTC, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public BarcodeData parseOpenAlias(String oaString) {
|
static public BarcodeData parseOpenAlias(String oaString, boolean dnssec) {
|
||||||
Timber.d("parseOpenAlias=%s", oaString);
|
Timber.d("parseOpenAlias=%s", oaString);
|
||||||
if (oaString == null) return null;
|
if (oaString == null) return null;
|
||||||
|
|
||||||
@@ -316,8 +365,8 @@ public class BarcodeData {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
BarcodeData bc = new BarcodeData(asset, address, paymentId, description, amount);
|
Security sec = dnssec ? BarcodeData.Security.OA_DNSSEC : BarcodeData.Security.OA_NO_DNSSEC;
|
||||||
bc.setAddressName(addressName);
|
|
||||||
return bc;
|
return new BarcodeData(asset, address, addressName, paymentId, description, amount, sec);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -22,6 +22,7 @@ import com.burgstaller.okhttp.digest.CachingAuthenticator;
|
|||||||
import com.burgstaller.okhttp.digest.Credentials;
|
import com.burgstaller.okhttp.digest.Credentials;
|
||||||
import com.burgstaller.okhttp.digest.DigestAuthenticator;
|
import com.burgstaller.okhttp.digest.DigestAuthenticator;
|
||||||
import com.m2049r.levin.scanner.Dispatcher;
|
import com.m2049r.levin.scanner.Dispatcher;
|
||||||
|
import com.m2049r.levin.scanner.LevinPeer;
|
||||||
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -99,21 +100,18 @@ public class NodeInfo extends Node {
|
|||||||
super(nodeString);
|
super(nodeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeInfo(InetSocketAddress socketAddress) {
|
public NodeInfo(LevinPeer levinPeer) {
|
||||||
super(socketAddress);
|
super(levinPeer.getSocketAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeInfo(InetSocketAddress address) {
|
||||||
|
super(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeInfo() {
|
public NodeInfo() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeInfo(InetSocketAddress peerAddress, long height, int majorVersion, double respTime) {
|
|
||||||
super(peerAddress);
|
|
||||||
this.height = height;
|
|
||||||
this.majorVersion = majorVersion;
|
|
||||||
this.responseTime = respTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getHeight() {
|
public long getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
@@ -20,9 +20,6 @@ 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 {
|
||||||
|
@@ -18,12 +18,11 @@ package com.m2049r.xmrwallet.data;
|
|||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
|
||||||
|
|
||||||
public class TxDataBtc extends TxData {
|
public class TxDataBtc extends TxData {
|
||||||
|
|
||||||
private String xmrtoUuid;
|
private String xmrtoUuid;
|
||||||
private String btcAddress;
|
private String btcAddress;
|
||||||
|
private String bip70;
|
||||||
private double btcAmount;
|
private double btcAmount;
|
||||||
|
|
||||||
public TxDataBtc() {
|
public TxDataBtc() {
|
||||||
@@ -50,6 +49,14 @@ public class TxDataBtc extends TxData {
|
|||||||
this.btcAddress = btcAddress;
|
this.btcAddress = btcAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBip70() {
|
||||||
|
return bip70;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBip70(String bip70) {
|
||||||
|
this.bip70 = bip70;
|
||||||
|
}
|
||||||
|
|
||||||
public double getBtcAmount() {
|
public double getBtcAmount() {
|
||||||
return btcAmount;
|
return btcAmount;
|
||||||
}
|
}
|
||||||
@@ -63,6 +70,7 @@ public class TxDataBtc extends TxData {
|
|||||||
super.writeToParcel(out, flags);
|
super.writeToParcel(out, flags);
|
||||||
out.writeString(xmrtoUuid);
|
out.writeString(xmrtoUuid);
|
||||||
out.writeString(btcAddress);
|
out.writeString(btcAddress);
|
||||||
|
out.writeString(bip70);
|
||||||
out.writeDouble(btcAmount);
|
out.writeDouble(btcAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,16 +89,19 @@ public class TxDataBtc extends TxData {
|
|||||||
super(in);
|
super(in);
|
||||||
xmrtoUuid = in.readString();
|
xmrtoUuid = in.readString();
|
||||||
btcAddress = in.readString();
|
btcAddress = in.readString();
|
||||||
|
bip70 = in.readString();
|
||||||
btcAmount = in.readDouble();
|
btcAmount = in.readDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(",xmrtoUuid:");
|
sb.append(",xmrtoUuid:");
|
||||||
sb.append(xmrtoUuid);
|
sb.append(xmrtoUuid);
|
||||||
sb.append(",btcAddress:");
|
sb.append(",btcAddress:");
|
||||||
sb.append(btcAddress);
|
sb.append(btcAddress);
|
||||||
|
sb.append(",bip70:");
|
||||||
|
sb.append(bip70);
|
||||||
sb.append(",btcAmount:");
|
sb.append(",btcAmount:");
|
||||||
sb.append(btcAmount);
|
sb.append(btcAmount);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.xmrwallet.util;
|
package com.m2049r.xmrwallet.data;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.xmrto.api.QueryOrderStatus;
|
import com.m2049r.xmrwallet.xmrto.api.QueryOrderStatus;
|
||||||
|
|
@@ -67,7 +67,7 @@ public class HelpFragment extends DialogFragment {
|
|||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setView(view);
|
builder.setView(view);
|
||||||
builder.setNegativeButton(R.string.about_close,
|
builder.setNegativeButton(R.string.help_ok,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -120,6 +120,15 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setBip70Mode() {
|
||||||
|
TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData();
|
||||||
|
if (txDataBtc.getBip70() != null) {
|
||||||
|
numberPad.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
numberPad.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double maxBtc = 0;
|
double maxBtc = 0;
|
||||||
double minBtc = 0;
|
double minBtc = 0;
|
||||||
|
|
||||||
@@ -141,12 +150,13 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
|
|||||||
tvFunds.setText(getString(R.string.send_available,
|
tvFunds.setText(getString(R.string.send_available,
|
||||||
getString(R.string.unknown_amount)));
|
getString(R.string.unknown_amount)));
|
||||||
}
|
}
|
||||||
if ((evAmount.getAmount() == null) || evAmount.getAmount().isEmpty()) {
|
final BarcodeData data = sendListener.popBarcodeData();
|
||||||
final BarcodeData data = sendListener.popBarcodeData();
|
if (data != null) {
|
||||||
if ((data != null) && (data.amount != null)) {
|
if (data.amount != null) {
|
||||||
evAmount.setAmount(data.amount);
|
evAmount.setAmount(data.amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setBip70Mode();
|
||||||
callXmrTo();
|
callXmrTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -524,8 +524,8 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
xmrtoStatus = null;
|
xmrtoStatus = null;
|
||||||
showProgress(1, getString(R.string.label_send_progress_xmrto_create));
|
showProgress(1, getString(R.string.label_send_progress_xmrto_create));
|
||||||
TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData();
|
TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData();
|
||||||
double btcAmount = txDataBtc.getBtcAmount();
|
|
||||||
getXmrToApi().createOrder(btcAmount, txDataBtc.getBtcAddress(), new XmrToCallback<CreateOrder>() {
|
XmrToCallback<CreateOrder> callback = new XmrToCallback<CreateOrder>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(CreateOrder createOrder) {
|
public void onSuccess(CreateOrder createOrder) {
|
||||||
if (!isResumed) return;
|
if (!isResumed) return;
|
||||||
@@ -545,7 +545,13 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
}
|
}
|
||||||
processCreateOrderError(ex);
|
processCreateOrderError(ex);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (txDataBtc.getBip70() != null) {
|
||||||
|
getXmrToApi().createOrder(txDataBtc.getBip70(), callback);
|
||||||
|
} else {
|
||||||
|
getXmrToApi().createOrder(txDataBtc.getBtcAmount(), txDataBtc.getBtcAddress(), callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryOrderStatus xmrtoStatus = null;
|
private QueryOrderStatus xmrtoStatus = null;
|
||||||
@@ -666,7 +672,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
|||||||
|
|
||||||
private XmrToApi xmrToApi = null;
|
private XmrToApi xmrToApi = null;
|
||||||
|
|
||||||
private final XmrToApi getXmrToApi() {
|
private XmrToApi getXmrToApi() {
|
||||||
if (xmrToApi == null) {
|
if (xmrToApi == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (xmrToApi == null) {
|
if (xmrToApi == null) {
|
||||||
|
@@ -36,7 +36,7 @@ import com.m2049r.xmrwallet.data.TxData;
|
|||||||
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.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.UserNotes;
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
@@ -214,11 +214,16 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
|
|||||||
if (pendingTransaction != null) {
|
if (pendingTransaction != null) {
|
||||||
llConfirmSend.setVisibility(View.VISIBLE);
|
llConfirmSend.setVisibility(View.VISIBLE);
|
||||||
bSend.setEnabled(true);
|
bSend.setEnabled(true);
|
||||||
tvTxAmount.setText(Wallet.getDisplayAmount(pendingTransaction.getAmount()));
|
|
||||||
tvTxFee.setText(Wallet.getDisplayAmount(pendingTransaction.getFee()));
|
tvTxFee.setText(Wallet.getDisplayAmount(pendingTransaction.getFee()));
|
||||||
//tvTxDust.setText(Wallet.getDisplayAmount(pendingTransaction.getDust()));
|
if (getActivityCallback().isStreetMode()
|
||||||
tvTxTotal.setText(Wallet.getDisplayAmount(
|
&& (sendListener.getTxData().getAmount() == Wallet.SWEEP_ALL)) {
|
||||||
pendingTransaction.getFee() + pendingTransaction.getAmount()));
|
tvTxAmount.setText(getString(R.string.street_sweep_amount));
|
||||||
|
tvTxTotal.setText(getString(R.string.street_sweep_amount));
|
||||||
|
} else {
|
||||||
|
tvTxAmount.setText(Wallet.getDisplayAmount(pendingTransaction.getAmount()));
|
||||||
|
tvTxTotal.setText(Wallet.getDisplayAmount(
|
||||||
|
pendingTransaction.getFee() + pendingTransaction.getAmount()));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
llConfirmSend.setVisibility(View.GONE);
|
llConfirmSend.setVisibility(View.GONE);
|
||||||
bSend.setEnabled(false);
|
bSend.setEnabled(false);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user