mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-05 09:58:42 +02:00
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cd6f646b63 | ||
![]() |
aa530caa28 | ||
![]() |
5df43f1274 | ||
![]() |
3b0cb3ffdb | ||
![]() |
300551dbe4 | ||
![]() |
942519adb7 | ||
![]() |
0652a8ba14 | ||
![]() |
04d0bd2ffb | ||
![]() |
8473e66c69 | ||
![]() |
2218ff615c | ||
![]() |
54b55b9f8f | ||
![]() |
5abf84f62b | ||
![]() |
6ff75d221f | ||
![]() |
c90f107c3c | ||
![]() |
a3db18032e | ||
![]() |
9db2c10679 | ||
![]() |
eab85c7f0a | ||
![]() |
6bf3229e77 | ||
![]() |
9f4f626acb | ||
![]() |
434dab55ba | ||
![]() |
59cc6b1864 | ||
![]() |
a6e9d0e77c | ||
![]() |
17df7c3faf | ||
![]() |
bf1829f775 | ||
![]() |
bc4aa0f772 |
@@ -3,7 +3,7 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/code
|
||||
docker:
|
||||
- image: cimg/android:2022.03-ndk
|
||||
- image: cimg/android:2023.12-ndk
|
||||
environment:
|
||||
JVM_OPTS: -Xmx3200m
|
||||
steps:
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,3 +16,5 @@
|
||||
/app/prodStagenet
|
||||
/app/.cxx
|
||||
/monerujo.id
|
||||
/external-libs/VERSION
|
||||
/external-libs/include/wallet2_api.h
|
||||
|
@@ -1,15 +1,15 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion '33.0.2'
|
||||
ndkVersion '17.2.4988734'
|
||||
defaultConfig {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
buildToolsVersion = '34.0.0'
|
||||
compileSdk 34
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
versionCode 3130
|
||||
versionName "3.1.3 'Fluorine Fermi'"
|
||||
targetSdkVersion 33
|
||||
versionCode 3311
|
||||
versionName "3.3.11 'Argentina'"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
@@ -112,6 +112,17 @@ android {
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
namespace 'com.m2049r.xmrwallet'
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests {
|
||||
all {
|
||||
jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static def getId(name) {
|
||||
@@ -123,39 +134,38 @@ static def getId(name) {
|
||||
dependencies {
|
||||
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
|
||||
|
||||
implementation 'androidx.core:core:1.10.0'
|
||||
implementation 'androidx.core:core:1.12.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.2'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
implementation 'androidx.preference:preference:1.2.1'
|
||||
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
|
||||
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||
implementation "com.squareup.okhttp3:okhttp:4.9.3"
|
||||
implementation "io.github.rburgst:okhttp-digest:2.6"
|
||||
implementation "com.squareup.okhttp3:okhttp:4.12.0"
|
||||
implementation "io.github.rburgst:okhttp-digest:3.1.0"
|
||||
implementation "com.jakewharton.timber:timber:5.0.1"
|
||||
|
||||
implementation 'info.guardianproject.netcipher:netcipher:2.1.0'
|
||||
//implementation 'info.guardianproject.netcipher:netcipher-okhttp3:2.1.0'
|
||||
implementation fileTree(dir: 'libs/classes', include: ['*.jar'])
|
||||
implementation 'com.nulab-inc:zxcvbn:1.5.2'
|
||||
implementation 'com.nulab-inc:zxcvbn:1.8.2'
|
||||
|
||||
implementation 'dnsjava:dnsjava:2.1.9'
|
||||
implementation 'org.jitsi:dnssecjava:1.2.0'
|
||||
implementation 'org.slf4j:slf4j-nop:1.7.36'
|
||||
implementation 'dnsjava:dnsjava:3.5.3'
|
||||
implementation 'org.slf4j:slf4j-nop:2.0.11'
|
||||
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
||||
|
||||
//noinspection GradleDependency
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation "org.mockito:mockito-all:1.10.19"
|
||||
testImplementation "com.squareup.okhttp3:mockwebserver:4.9.3"
|
||||
testImplementation 'org.json:json:20211205'
|
||||
testImplementation "com.squareup.okhttp3:mockwebserver:4.12.0"
|
||||
testImplementation 'org.json:json:20231013'
|
||||
testImplementation 'net.jodah:concurrentunit:0.4.6'
|
||||
|
||||
compileOnly 'org.projectlombok:lombok:1.18.22'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
||||
compileOnly 'org.projectlombok:lombok:1.18.30'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.30'
|
||||
}
|
||||
|
@@ -1,6 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@ import androidx.fragment.app.Fragment;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.m2049r.xmrwallet.model.NetworkType;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.FingerprintHelper;
|
||||
@@ -344,21 +345,23 @@ public class GenerateFragment extends Fragment {
|
||||
|
||||
String restoreHeight = etWalletRestoreHeight.getEditText().getText().toString().trim();
|
||||
if (restoreHeight.isEmpty()) return -1;
|
||||
try {
|
||||
// is it a date?
|
||||
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
|
||||
parser.setLenient(false);
|
||||
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
|
||||
} catch (ParseException ignored) {
|
||||
}
|
||||
if ((height < 0) && (restoreHeight.length() == 8))
|
||||
if (WalletManager.getInstance().getNetworkType() == NetworkType.NetworkType_Mainnet) {
|
||||
try {
|
||||
// is it a date without dashes?
|
||||
SimpleDateFormat parser = new SimpleDateFormat("yyyyMMdd");
|
||||
// is it a date?
|
||||
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
|
||||
parser.setLenient(false);
|
||||
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
|
||||
} catch (ParseException ignored) {
|
||||
}
|
||||
if ((height < 0) && (restoreHeight.length() == 8))
|
||||
try {
|
||||
// is it a date without dashes?
|
||||
SimpleDateFormat parser = new SimpleDateFormat("yyyyMMdd");
|
||||
parser.setLenient(false);
|
||||
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
|
||||
} catch (ParseException ignored) {
|
||||
}
|
||||
}
|
||||
if (height < 0)
|
||||
try {
|
||||
// or is it a height?
|
||||
|
@@ -658,11 +658,11 @@ public class LoginActivity extends BaseActivity
|
||||
break;
|
||||
case NetworkType_Testnet:
|
||||
toolbar.setSubtitle(getString(R.string.connect_testnet));
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, androidx.appcompat.R.attr.colorPrimaryDark));
|
||||
break;
|
||||
case NetworkType_Stagenet:
|
||||
toolbar.setSubtitle(getString(R.string.connect_stagenet));
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, androidx.appcompat.R.attr.colorPrimaryDark));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("NetworkType unknown: " + net);
|
||||
|
@@ -79,6 +79,7 @@ public class TxFragment extends Fragment {
|
||||
private TextView tvTxPaymentId;
|
||||
private TextView tvTxBlockheight;
|
||||
private TextView tvTxAmount;
|
||||
private TextView tvTxPocketChangeAmount;
|
||||
private TextView tvTxFee;
|
||||
private TextView tvTxTransfers;
|
||||
private TextView etTxNotes;
|
||||
@@ -116,6 +117,7 @@ public class TxFragment extends Fragment {
|
||||
tvTxPaymentId = view.findViewById(R.id.tvTxPaymentId);
|
||||
tvTxBlockheight = view.findViewById(R.id.tvTxBlockheight);
|
||||
tvTxAmount = view.findViewById(R.id.tvTxAmount);
|
||||
tvTxPocketChangeAmount = view.findViewById(R.id.tvTxPocketChangeAmount);
|
||||
tvTxFee = view.findViewById(R.id.tvTxFee);
|
||||
tvTxTransfers = view.findViewById(R.id.tvTxTransfers);
|
||||
etTxNotes = view.findViewById(R.id.etTxNotes);
|
||||
@@ -249,8 +251,10 @@ public class TxFragment extends Fragment {
|
||||
}
|
||||
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
|
||||
|
||||
long realAmount = info.amount;
|
||||
tvTxAmount.setText(sign + Wallet.getDisplayAmount(realAmount));
|
||||
tvTxAmount.setText(sign + Wallet.getDisplayAmount(info.amount));
|
||||
final long pcAmount = info.getPocketChangeAmount();
|
||||
tvTxPocketChangeAmount.setVisibility(pcAmount > 0 ? View.VISIBLE : View.GONE);
|
||||
tvTxPocketChangeAmount.setText(getString(R.string.pocketchange_tx_detail, Wallet.getDisplayAmount(pcAmount)));
|
||||
|
||||
if ((info.fee > 0)) {
|
||||
String fee = Wallet.getDisplayAmount(info.fee);
|
||||
|
@@ -52,8 +52,8 @@ import com.m2049r.xmrwallet.data.BarcodeData;
|
||||
import com.m2049r.xmrwallet.data.Subaddress;
|
||||
import com.m2049r.xmrwallet.data.TxData;
|
||||
import com.m2049r.xmrwallet.data.UserNotes;
|
||||
import com.m2049r.xmrwallet.dialog.CreditsFragment;
|
||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||
import com.m2049r.xmrwallet.dialog.PocketChangeFragment;
|
||||
import com.m2049r.xmrwallet.fragment.send.SendAddressWizardFragment;
|
||||
import com.m2049r.xmrwallet.fragment.send.SendFragment;
|
||||
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
||||
@@ -82,7 +82,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
||||
WalletFragment.DrawerLocker,
|
||||
NavigationView.OnNavigationItemSelectedListener,
|
||||
SubaddressFragment.Listener,
|
||||
SubaddressInfoFragment.Listener {
|
||||
SubaddressInfoFragment.Listener,
|
||||
PocketChangeFragment.Listener {
|
||||
|
||||
public static final String REQUEST_ID = "id";
|
||||
public static final String REQUEST_PW = "pw";
|
||||
@@ -285,8 +286,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
||||
onWalletRescan();
|
||||
} else if (itemId == R.id.action_info) {
|
||||
onWalletDetails();
|
||||
} else if (itemId == R.id.action_credits) {
|
||||
CreditsFragment.display(getSupportFragmentManager());
|
||||
} else if (itemId == R.id.action_share) {
|
||||
onShareTxInfo();
|
||||
} else if (itemId == R.id.action_help_tx_info) {
|
||||
@@ -301,6 +300,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_send);
|
||||
} else if (itemId == R.id.action_rename) {
|
||||
onAccountRename();
|
||||
} else if (itemId == R.id.action_pocketchange) {
|
||||
PocketChangeFragment.display(getSupportFragmentManager(), getWallet().getPocketChangeSetting());
|
||||
} else if (itemId == R.id.action_subaddresses) {
|
||||
showSubaddresses(true);
|
||||
} else if (itemId == R.id.action_streetmode) {
|
||||
@@ -422,7 +423,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
||||
break;
|
||||
case NetworkType_Stagenet:
|
||||
case NetworkType_Testnet:
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, androidx.appcompat.R.attr.colorPrimaryDark));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
|
||||
@@ -646,6 +647,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
||||
haveWallet = true;
|
||||
invalidateOptionsMenu();
|
||||
|
||||
loadPocketChangeSettings();
|
||||
|
||||
if (requestStreetMode) onEnableStreetMode();
|
||||
|
||||
final WalletFragment walletFragment = getWalletFragment();
|
||||
@@ -1104,6 +1107,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
||||
|
||||
public void setAccountIndex(int accountIndex) {
|
||||
getWallet().setAccountIndex(accountIndex);
|
||||
loadPocketChangeSettings();
|
||||
selectedSubaddressIndex = 0;
|
||||
}
|
||||
|
||||
@@ -1214,4 +1218,19 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
||||
b.putInt("subaddressIndex", subaddressIndex);
|
||||
replaceFragmentWithTransition(view, new SubaddressInfoFragment(), null, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPocketChange(Wallet.PocketChangeSetting setting) {
|
||||
SharedPreferences.Editor editor = getPrefs().edit();
|
||||
editor.putString(getWallet().getAddress() + "_PC", setting.toPrefString());
|
||||
editor.apply();
|
||||
getWallet().setPocketChangeSetting(setting);
|
||||
}
|
||||
|
||||
|
||||
public void loadPocketChangeSettings() {
|
||||
final String settings = getPrefs().getString(getWallet().getAddress() + "_PC", "0");
|
||||
getWallet().setPocketChangeSetting(Wallet.PocketChangeSetting.from(settings));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -112,7 +112,7 @@ public class WalletFragment extends Fragment
|
||||
flExchange = view.findViewById(R.id.flExchange);
|
||||
((ProgressBar) view.findViewById(R.id.pbExchange)).getIndeterminateDrawable().
|
||||
setColorFilter(
|
||||
ThemeHelper.getThemedColor(getContext(), R.attr.colorPrimaryVariant),
|
||||
ThemeHelper.getThemedColor(getContext(), com.google.android.material.R.attr.colorPrimaryVariant),
|
||||
android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||
|
||||
tvProgress = view.findViewById(R.id.tvProgress);
|
||||
|
@@ -22,18 +22,24 @@ import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStateManagerControl;
|
||||
|
||||
import com.m2049r.xmrwallet.model.NetworkType;
|
||||
import com.m2049r.xmrwallet.util.LocaleHelper;
|
||||
import com.m2049r.xmrwallet.util.NetCipherHelper;
|
||||
import com.m2049r.xmrwallet.util.NightmodeHelper;
|
||||
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class XmrWalletApplication extends Application {
|
||||
|
||||
@Override
|
||||
@OptIn(markerClass = FragmentStateManagerControl.class)
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
FragmentManager.enableNewStateManager(false);
|
||||
|
@@ -29,10 +29,12 @@ public enum DefaultNodes {
|
||||
HASHVAULT("nodes.hashvault.pro:18081"),
|
||||
MONEROWORLD("node.moneroworld.com:18089"),
|
||||
XMRTW("opennode.xmr-tw.org:18089"),
|
||||
ds_jetzt("monero.ds-jetzt.de:18089"),
|
||||
MONERUJO_ONION("monerujods7mbghwe6cobdr6ujih6c22zu5rl7zshmizz2udf7v7fsad.onion:18081/mainnet/monerujo.onion"),
|
||||
Criminales78("56wl7y2ebhamkkiza4b7il4mrzwtyvpdym7bm2bkg3jrei2je646k3qd.onion:18089/mainnet/Criminales78.onion"),
|
||||
xmrfail("mxcd4577fldb3ppzy7obmmhnu3tf57gbcbd4qhwr2kxyjj2qi3dnbfqd.onion:18081/mainnet/xmrfail.onion"),
|
||||
boldsuck("6dsdenp6vjkvqzy4wzsnzn6wixkdzihx3khiumyzieauxuxslmcaeiad.onion:18081/mainnet/boldsuck.onion");
|
||||
boldsuck("6dsdenp6vjkvqzy4wzsnzn6wixkdzihx3khiumyzieauxuxslmcaeiad.onion:18081/mainnet/boldsuck.onion"),
|
||||
ds_jetzt_onion("qvlr4w7yhnjrdg3txa72jwtpnjn4ezsrivzvocbnvpfbdo342fahhoad.onion:18089/mainnet/ds-jetzt.onion");
|
||||
|
||||
@Getter
|
||||
private final String uri;
|
||||
|
@@ -270,7 +270,7 @@ public class NodeInfo extends Node {
|
||||
(hostAddress.isOnion() ? " .onion " : ""), " " + info));
|
||||
view.setText(text);
|
||||
if (isError)
|
||||
view.setTextColor(ThemeHelper.getThemedColor(ctx, R.attr.colorError));
|
||||
view.setTextColor(ThemeHelper.getThemedColor(ctx, androidx.appcompat.R.attr.colorError));
|
||||
else
|
||||
view.setTextColor(ThemeHelper.getThemedColor(ctx, android.R.attr.textColorSecondary));
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -41,10 +41,6 @@ public class TxDataBtc extends TxData {
|
||||
super();
|
||||
}
|
||||
|
||||
public TxDataBtc(TxDataBtc txDataBtc) {
|
||||
super(txDataBtc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
super.writeToParcel(out, flags);
|
||||
|
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2023 m2049r
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet.dialog;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.slider.Slider;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import com.m2049r.xmrwallet.R;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
public class PocketChangeFragment extends DialogFragment implements Slider.OnChangeListener {
|
||||
static final String TAG = "PocketChangeFragment";
|
||||
static final String ENABLED = "enabled";
|
||||
static final String TICK = "tick";
|
||||
|
||||
public static PocketChangeFragment newInstance(boolean enabled, int tick) {
|
||||
PocketChangeFragment fragment = new PocketChangeFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(ENABLED, enabled ? 1 : 0);
|
||||
bundle.putInt(TICK, tick);
|
||||
fragment.setArguments(bundle);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static void display(FragmentManager fm, @NonNull Wallet.PocketChangeSetting setting) {
|
||||
FragmentTransaction ft = fm.beginTransaction();
|
||||
Fragment prev = fm.findFragmentByTag(TAG);
|
||||
if (prev != null) {
|
||||
ft.remove(prev);
|
||||
}
|
||||
PocketChangeFragment.newInstance(setting.isEnabled(), getTick(setting.getAmount())).show(ft, TAG);
|
||||
}
|
||||
|
||||
SwitchMaterial switchPocketChange;
|
||||
Slider slider;
|
||||
TextView tvProgressLabel;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_pocketchange_setting, null);
|
||||
boolean enabled = false;
|
||||
int progress = 0;
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments != null) {
|
||||
enabled = arguments.getInt(ENABLED) > 0;
|
||||
progress = arguments.getInt(TICK);
|
||||
}
|
||||
|
||||
final View llAmount = view.findViewById(R.id.llAmount);
|
||||
switchPocketChange = view.findViewById(R.id.switchPocketChange);
|
||||
switchPocketChange.setOnCheckedChangeListener((buttonView, isChecked) -> llAmount.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE));
|
||||
slider = view.findViewById(R.id.seekbar);
|
||||
slider.addOnChangeListener(this);
|
||||
switchPocketChange.setChecked(enabled);
|
||||
tvProgressLabel = view.findViewById(R.id.seekbar_value);
|
||||
slider.setValue(progress);
|
||||
llAmount.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
|
||||
onValueChange(slider, slider.getValue(), false);
|
||||
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity())
|
||||
.setView(view)
|
||||
.setPositiveButton(R.string.label_apply,
|
||||
(dialog, whichButton) -> {
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity instanceof Listener) {
|
||||
((Listener) activity).setPocketChange(Wallet.PocketChangeSetting.of(switchPocketChange.isChecked(), getAmount()));
|
||||
}
|
||||
}
|
||||
);
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private long getAmount() {
|
||||
return Wallet.getAmountFromDouble(getAmount((int) slider.getValue()));
|
||||
}
|
||||
|
||||
private static final double[] AMOUNTS = {0.1, 0.2, 0.3, 0.5, 0.8, 1.3};
|
||||
|
||||
private static double getAmount(int i) {
|
||||
return AMOUNTS[i];
|
||||
}
|
||||
|
||||
// find the closest amount we have
|
||||
private static int getTick(long amount) {
|
||||
int enabled = amount > 0 ? 1 : -1;
|
||||
amount = Math.abs(amount);
|
||||
double lastDiff = Double.MAX_VALUE;
|
||||
for (int i = 0; i < AMOUNTS.length; i++) {
|
||||
final double diff = Math.abs(Helper.ONE_XMR * AMOUNTS[i] - amount);
|
||||
if (lastDiff < diff) return i - 1;
|
||||
lastDiff = diff;
|
||||
}
|
||||
return enabled * (AMOUNTS.length - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {
|
||||
tvProgressLabel.setText(getString(R.string.pocketchange_amount, getAmount((int) value)));
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void setPocketChange(Wallet.PocketChangeSetting setting);
|
||||
}
|
||||
}
|
@@ -411,10 +411,10 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
||||
if (txData instanceof TxDataBtc) {
|
||||
((TxDataBtc) txData).setBtcAddress(etAddress.getEditText().getText().toString());
|
||||
((TxDataBtc) txData).setBtcSymbol(selectedCrypto.getSymbol());
|
||||
txData.setDestinationAddress(null);
|
||||
txData.setDestination(null);
|
||||
ServiceHelper.ASSET = selectedCrypto.getSymbol().toLowerCase();
|
||||
} else {
|
||||
txData.setDestinationAddress(etAddress.getEditText().getText().toString());
|
||||
txData.setDestination(etAddress.getEditText().getText().toString());
|
||||
ServiceHelper.ASSET = null;
|
||||
}
|
||||
txData.setUserNotes(new UserNotes(etNotes.getEditText().getText().toString()));
|
||||
|
@@ -23,6 +23,8 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import com.m2049r.xmrwallet.R;
|
||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||
import com.m2049r.xmrwallet.data.TxData;
|
||||
|
@@ -74,6 +74,9 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
||||
private View llConfirmSend;
|
||||
private Button bSend;
|
||||
private View pbProgressSend;
|
||||
private TextView tvTxChange;
|
||||
private View llPocketChange;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -92,6 +95,8 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
||||
|
||||
tvTxFee = view.findViewById(R.id.tvTxFee);
|
||||
tvTxTotal = view.findViewById(R.id.tvTxTotal);
|
||||
tvTxChange = view.findViewById(R.id.tvTxChange);
|
||||
llPocketChange = view.findViewById(R.id.llPocketChange);
|
||||
|
||||
llStageA = view.findViewById(R.id.llStageA);
|
||||
evStageA = view.findViewById(R.id.evStageA);
|
||||
@@ -217,6 +222,13 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
||||
tvTxFee.setText(Wallet.getDisplayAmount(pendingTransaction.getFee()));
|
||||
tvTxTotal.setText(Wallet.getDisplayAmount(
|
||||
pendingTransaction.getFee() + pendingTransaction.getAmount()));
|
||||
final long change = pendingTransaction.getPocketChange();
|
||||
if (change > 0) {
|
||||
llPocketChange.setVisibility(View.VISIBLE);
|
||||
tvTxChange.setText(Wallet.getDisplayAmount(change));
|
||||
} else {
|
||||
llPocketChange.setVisibility(View.GONE);
|
||||
}
|
||||
updateSendButton();
|
||||
});
|
||||
} else {
|
||||
@@ -348,7 +360,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
||||
}
|
||||
showProgress(3, getString(R.string.label_send_progress_create_tx));
|
||||
final TxData txData = sendListener.getTxData();
|
||||
txData.setDestinationAddress(xmrtoOrder.getXmrAddress());
|
||||
txData.setDestination(xmrtoOrder.getXmrAddress());
|
||||
txData.setAmount(xmrtoOrder.getXmrAmount());
|
||||
getActivityCallback().onPrepareSend(xmrtoOrder.getOrderId(), txData);
|
||||
}
|
||||
|
@@ -140,7 +140,7 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
isResumed = true;
|
||||
|
||||
btcData = (TxDataBtc) sendListener.getTxData();
|
||||
tvTxAddress.setText(btcData.getDestinationAddress());
|
||||
tvTxAddress.setText(btcData.getDestination());
|
||||
|
||||
final PendingTx committedTx = sendListener.getCommittedTx();
|
||||
if (committedTx != null) {
|
||||
|
@@ -64,12 +64,14 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
|
||||
private TextView tvTxAddress;
|
||||
private TextView tvTxNotes;
|
||||
private TextView tvTxAmount;
|
||||
private TextView tvTxChange;
|
||||
private TextView tvTxFee;
|
||||
private TextView tvTxTotal;
|
||||
private View llProgress;
|
||||
private View bSend;
|
||||
private View llConfirmSend;
|
||||
private View pbProgressSend;
|
||||
private View llPocketChange;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -83,12 +85,14 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
|
||||
tvTxAddress = view.findViewById(R.id.tvTxAddress);
|
||||
tvTxNotes = view.findViewById(R.id.tvTxNotes);
|
||||
tvTxAmount = view.findViewById(R.id.tvTxAmount);
|
||||
tvTxChange = view.findViewById(R.id.tvTxChange);
|
||||
tvTxFee = view.findViewById(R.id.tvTxFee);
|
||||
tvTxTotal = view.findViewById(R.id.tvTxTotal);
|
||||
|
||||
llProgress = view.findViewById(R.id.llProgress);
|
||||
pbProgressSend = view.findViewById(R.id.pbProgressSend);
|
||||
llConfirmSend = view.findViewById(R.id.llConfirmSend);
|
||||
llPocketChange = view.findViewById(R.id.llPocketChange);
|
||||
|
||||
bSend = view.findViewById(R.id.bSend);
|
||||
bSend.setEnabled(false);
|
||||
@@ -181,7 +185,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
|
||||
isResumed = true;
|
||||
|
||||
final TxData txData = sendListener.getTxData();
|
||||
tvTxAddress.setText(txData.getDestinationAddress());
|
||||
tvTxAddress.setText(txData.getDestination());
|
||||
UserNotes notes = sendListener.getTxData().getUserNotes();
|
||||
if ((notes != null) && (!notes.note.isEmpty())) {
|
||||
tvTxNotes.setText(notes.note);
|
||||
@@ -206,7 +210,14 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
|
||||
tvTxAmount.setText(getString(R.string.street_sweep_amount));
|
||||
tvTxTotal.setText(getString(R.string.street_sweep_amount));
|
||||
} else {
|
||||
tvTxAmount.setText(Wallet.getDisplayAmount(pendingTransaction.getAmount()));
|
||||
tvTxAmount.setText(Wallet.getDisplayAmount(pendingTransaction.getNetAmount()));
|
||||
final long change = pendingTransaction.getPocketChange();
|
||||
if (change > 0) {
|
||||
llPocketChange.setVisibility(View.VISIBLE);
|
||||
tvTxChange.setText(Wallet.getDisplayAmount(change));
|
||||
} else {
|
||||
llPocketChange.setVisibility(View.GONE);
|
||||
}
|
||||
tvTxTotal.setText(Wallet.getDisplayAmount(
|
||||
pendingTransaction.getFee() + pendingTransaction.getAmount()));
|
||||
}
|
||||
|
@@ -108,7 +108,7 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
|
||||
Helper.hideKeyboard(getActivity());
|
||||
|
||||
final TxData txData = sendListener.getTxData();
|
||||
tvTxAddress.setText(txData.getDestinationAddress());
|
||||
tvTxAddress.setText(txData.getDestination());
|
||||
|
||||
final PendingTx committedTx = sendListener.getCommittedTx();
|
||||
if (committedTx != null) {
|
||||
|
@@ -189,7 +189,6 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
}
|
||||
|
||||
private void showLock() {
|
||||
Timber.d("UNLOCK %d:%d", infoItem.unlockTime, infoItem.blockheight);
|
||||
if (infoItem.unlockTime == 0) {
|
||||
ivLock.setVisibility(View.GONE);
|
||||
return;
|
||||
@@ -220,7 +219,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
ivTxType.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
String displayAmount = Helper.getDisplayAmount(infoItem.amount, Helper.DISPLAY_DIGITS_INFO);
|
||||
String displayAmount = Helper.getDisplayAmount(infoItem.getNetAmount(), Helper.DISPLAY_DIGITS_INFO);
|
||||
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {
|
||||
tvAmount.setText(context.getString(R.string.tx_list_amount_negative, displayAmount));
|
||||
} else {
|
||||
|
39
app/src/main/java/com/m2049r/xmrwallet/model/Coins.java
Normal file
39
app/src/main/java/com/m2049r/xmrwallet/model/Coins.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2023 m2049r
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class Coins {
|
||||
static {
|
||||
System.loadLibrary("monerujo");
|
||||
}
|
||||
|
||||
private long handle;
|
||||
|
||||
public Coins(long handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public List<CoinsInfo> getAll(int accountIndex, boolean unspentOnly) {
|
||||
return refresh(accountIndex, unspentOnly);
|
||||
}
|
||||
|
||||
private native List<CoinsInfo> refresh(int accountIndex, boolean unspentOnly);
|
||||
}
|
38
app/src/main/java/com/m2049r/xmrwallet/model/CoinsInfo.java
Normal file
38
app/src/main/java/com/m2049r/xmrwallet/model/CoinsInfo.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2023 m2049r
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
// this is not the CoinsInfo from the API as that is owned by the Coins object
|
||||
// this is a POJO
|
||||
@Value
|
||||
public class CoinsInfo {
|
||||
int accountIndex;
|
||||
int addressIndex;
|
||||
long amount;
|
||||
long blockheight;
|
||||
String txHash;
|
||||
boolean spent;
|
||||
boolean frozen;
|
||||
long unlockTime;
|
||||
boolean unlocked;
|
||||
|
||||
public boolean isSpendable() {
|
||||
return !spent && unlocked;
|
||||
}
|
||||
}
|
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class PendingTransaction {
|
||||
static {
|
||||
System.loadLibrary("monerujo");
|
||||
@@ -63,8 +66,6 @@ public class PendingTransaction {
|
||||
Priority(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
@@ -95,4 +96,11 @@ public class PendingTransaction {
|
||||
|
||||
public native long getTxCount();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private long pocketChange;
|
||||
|
||||
public long getNetAmount() {
|
||||
return getAmount() - pocketChange;
|
||||
}
|
||||
}
|
||||
|
@@ -17,8 +17,10 @@
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
@@ -61,22 +63,14 @@ public class TransactionHistory {
|
||||
|
||||
private List<TransactionInfo> transactions = new ArrayList<>();
|
||||
|
||||
void refreshWithNotes(Wallet wallet) {
|
||||
public void refreshWithNotes(Wallet wallet) {
|
||||
refresh();
|
||||
loadNotes(wallet);
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
List<TransactionInfo> transactionInfos = refreshJ();
|
||||
Timber.d("refresh size=%d", transactionInfos.size());
|
||||
for (Iterator<TransactionInfo> iterator = transactionInfos.iterator(); iterator.hasNext(); ) {
|
||||
TransactionInfo info = iterator.next();
|
||||
if (info.accountIndex != accountIndex) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
transactions = transactionInfos;
|
||||
transactions = refreshJ(accountIndex);
|
||||
}
|
||||
|
||||
private native List<TransactionInfo> refreshJ();
|
||||
private native List<TransactionInfo> refreshJ(int accountIndex);
|
||||
}
|
||||
|
@@ -101,6 +101,23 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
this.unlockTime = unlockTime;
|
||||
this.subaddressLabel = subaddressLabel;
|
||||
this.transfers = transfers;
|
||||
calcNetAmount();
|
||||
}
|
||||
|
||||
@Getter
|
||||
private long netAmount;
|
||||
|
||||
public long getPocketChangeAmount() {
|
||||
return amount - netAmount;
|
||||
}
|
||||
|
||||
private void calcNetAmount() {
|
||||
netAmount = amount;
|
||||
if ((direction == TransactionInfo.Direction.Direction_Out) && (transfers != null)) {
|
||||
for (int i = 1; i < transfers.size(); i++) {
|
||||
netAmount -= transfers.get(i).amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConfirmed() {
|
||||
@@ -138,6 +155,7 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
out.writeString(txKey);
|
||||
out.writeString(notes);
|
||||
out.writeString(address);
|
||||
out.writeLong(netAmount);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TransactionInfo> CREATOR = new Parcelable.Creator<TransactionInfo>() {
|
||||
@@ -169,6 +187,7 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
txKey = in.readString();
|
||||
notes = in.readString();
|
||||
address = in.readString();
|
||||
netAmount = in.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -25,10 +25,13 @@ import com.m2049r.xmrwallet.data.TxData;
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.Value;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class Wallet {
|
||||
@@ -67,9 +70,7 @@ public class Wallet {
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return (getStatus() == StatusEnum.Status_Ok)
|
||||
&& ((getConnectionStatus() == null) ||
|
||||
(getConnectionStatus() == ConnectionStatus.ConnectionStatus_Connected));
|
||||
return (getStatus() == StatusEnum.Status_Ok) && ((getConnectionStatus() == null) || (getConnectionStatus() == ConnectionStatus.ConnectionStatus_Connected));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,23 +111,17 @@ public class Wallet {
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum Device {
|
||||
Device_Undefined(0, 0),
|
||||
Device_Software(50, 200),
|
||||
Device_Ledger(5, 20);
|
||||
Device_Undefined(0, 0), Device_Software(50, 200), Device_Ledger(5, 20);
|
||||
private final int accountLookahead;
|
||||
private final int subaddressLookahead;
|
||||
}
|
||||
|
||||
public enum StatusEnum {
|
||||
Status_Ok,
|
||||
Status_Error,
|
||||
Status_Critical
|
||||
Status_Ok, Status_Error, Status_Critical
|
||||
}
|
||||
|
||||
public enum ConnectionStatus {
|
||||
ConnectionStatus_Disconnected,
|
||||
ConnectionStatus_Connected,
|
||||
ConnectionStatus_WrongVersion
|
||||
ConnectionStatus_Disconnected, ConnectionStatus_Connected, ConnectionStatus_WrongVersion
|
||||
}
|
||||
|
||||
public native String getSeed(String offset);
|
||||
@@ -168,16 +163,14 @@ public class Wallet {
|
||||
private native String getAddressJ(int accountIndex, int addressIndex);
|
||||
|
||||
public Subaddress getSubaddressObject(int accountIndex, int subAddressIndex) {
|
||||
return new Subaddress(accountIndex, subAddressIndex,
|
||||
getSubaddress(subAddressIndex), getSubaddressLabel(subAddressIndex));
|
||||
return new Subaddress(accountIndex, subAddressIndex, getSubaddress(subAddressIndex), getSubaddressLabel(subAddressIndex));
|
||||
}
|
||||
|
||||
public Subaddress getSubaddressObject(int subAddressIndex) {
|
||||
Subaddress subaddress = getSubaddressObject(accountIndex, subAddressIndex);
|
||||
long amount = 0;
|
||||
for (TransactionInfo info : getHistory().getAll()) {
|
||||
if ((info.addressIndex == subAddressIndex)
|
||||
&& (info.direction == TransactionInfo.Direction.Direction_In)) {
|
||||
if ((info.addressIndex == subAddressIndex) && (info.direction == TransactionInfo.Direction.Direction_In)) {
|
||||
amount += info.amount;
|
||||
}
|
||||
}
|
||||
@@ -217,13 +210,10 @@ public class Wallet {
|
||||
|
||||
// virtual std::string keysFilename() const = 0;
|
||||
public boolean init(long upper_transaction_size_limit) {
|
||||
return initJ(WalletManager.getInstance().getDaemonAddress(), upper_transaction_size_limit,
|
||||
WalletManager.getInstance().getDaemonUsername(),
|
||||
WalletManager.getInstance().getDaemonPassword());
|
||||
return initJ(WalletManager.getInstance().getDaemonAddress(), upper_transaction_size_limit, WalletManager.getInstance().getDaemonUsername(), WalletManager.getInstance().getDaemonPassword());
|
||||
}
|
||||
|
||||
private native boolean initJ(String daemon_address, long upper_transaction_size_limit,
|
||||
String daemon_username, String daemon_password);
|
||||
private native boolean initJ(String daemon_address, long upper_transaction_size_limit, String daemon_username, String daemon_password);
|
||||
|
||||
// virtual bool createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const = 0;
|
||||
// virtual void setRefreshFromBlockHeight(uint64_t refresh_from_block_height) = 0;
|
||||
@@ -335,36 +325,23 @@ public class Wallet {
|
||||
}
|
||||
}
|
||||
|
||||
public PendingTransaction createTransaction(TxData txData) {
|
||||
return createTransaction(
|
||||
txData.getDestinationAddress(),
|
||||
txData.getAmount(),
|
||||
txData.getMixin(),
|
||||
txData.getPriority());
|
||||
}
|
||||
private native long createTransactionMultDest(String[] destinations, String payment_id, long[] amounts, int mixin_count, int priority, int accountIndex, int[] subaddresses);
|
||||
|
||||
public PendingTransaction createTransaction(String dst_addr,
|
||||
long amount, int mixin_count,
|
||||
PendingTransaction.Priority priority) {
|
||||
public PendingTransaction createTransaction(TxData txData) {
|
||||
disposePendingTransaction();
|
||||
int _priority = priority.getValue();
|
||||
long txHandle =
|
||||
(amount == SWEEP_ALL ?
|
||||
createSweepTransaction(dst_addr, "", mixin_count, _priority,
|
||||
accountIndex) :
|
||||
createTransactionJ(dst_addr, "", amount, mixin_count, _priority,
|
||||
accountIndex));
|
||||
int _priority = txData.getPriority().getValue();
|
||||
final boolean sweepAll = txData.getAmount() == SWEEP_ALL;
|
||||
Timber.d("TxData: %s", txData);
|
||||
long txHandle = (sweepAll ? createSweepTransaction(txData.getDestination(), "", txData.getMixin(), _priority, accountIndex) :
|
||||
createTransactionMultDest(txData.getDestinations(), "", txData.getAmounts(), txData.getMixin(), _priority, accountIndex, txData.getSubaddresses()));
|
||||
pendingTransaction = new PendingTransaction(txHandle);
|
||||
pendingTransaction.setPocketChange(txData.getPocketChangeAmount());
|
||||
return pendingTransaction;
|
||||
}
|
||||
|
||||
private native long createTransactionJ(String dst_addr, String payment_id,
|
||||
long amount, int mixin_count,
|
||||
int priority, int accountIndex);
|
||||
private native long createTransactionJ(String dst_addr, String payment_id, long amount, int mixin_count, int priority, int accountIndex);
|
||||
|
||||
private native long createSweepTransaction(String dst_addr, String payment_id,
|
||||
int mixin_count,
|
||||
int priority, int accountIndex);
|
||||
private native long createSweepTransaction(String dst_addr, String payment_id, int mixin_count, int priority, int accountIndex);
|
||||
|
||||
|
||||
public PendingTransaction createSweepUnmixableTransaction() {
|
||||
@@ -381,7 +358,13 @@ public class Wallet {
|
||||
|
||||
public native void disposeTransaction(PendingTransaction pendingTransaction);
|
||||
|
||||
//virtual bool exportKeyImages(const std::string &filename) = 0;
|
||||
public long estimateTransactionFee(TxData txData) {
|
||||
return estimateTransactionFee(txData.getDestinations(), txData.getAmounts(), txData.getPriority().getValue());
|
||||
}
|
||||
|
||||
private native long estimateTransactionFee(String[] destinations, long[] amounts, int priority);
|
||||
|
||||
//virtual bool exportKeyImages(const std::string &filename) = 0;
|
||||
//virtual bool importKeyImages(const std::string &filename) = 0;
|
||||
|
||||
|
||||
@@ -403,6 +386,22 @@ public class Wallet {
|
||||
}
|
||||
|
||||
//virtual AddressBook * addressBook() const = 0;
|
||||
|
||||
public List<CoinsInfo> getCoinsInfos(boolean unspentOnly) {
|
||||
return getCoins().getAll(accountIndex, unspentOnly);
|
||||
}
|
||||
|
||||
private Coins coins = null;
|
||||
|
||||
private Coins getCoins() {
|
||||
if (coins == null) {
|
||||
coins = new Coins(getCoinsJ());
|
||||
}
|
||||
return coins;
|
||||
}
|
||||
|
||||
private native long getCoinsJ();
|
||||
|
||||
//virtual void setListener(WalletListener *) = 0;
|
||||
|
||||
private native long setListenerJ(WalletListener listener);
|
||||
@@ -444,8 +443,7 @@ public class Wallet {
|
||||
if (label.equals(NEW_ACCOUNT_NAME)) {
|
||||
String address = getAddress(accountIndex);
|
||||
int len = address.length();
|
||||
label = address.substring(0, 6) +
|
||||
"\u2026" + address.substring(len - 6, len);
|
||||
label = address.substring(0, 6) + "\u2026" + address.substring(len - 6, len);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
@@ -504,4 +502,22 @@ public class Wallet {
|
||||
|
||||
private native int getDeviceTypeJ();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
PocketChangeSetting pocketChangeSetting = PocketChangeSetting.of(false, 0);
|
||||
|
||||
@Value(staticConstructor = "of")
|
||||
static public class PocketChangeSetting {
|
||||
boolean enabled;
|
||||
long amount;
|
||||
|
||||
public String toPrefString() {
|
||||
return Long.toString((enabled ? 1 : -1) * amount);
|
||||
}
|
||||
|
||||
static public PocketChangeSetting from(String prefString) {
|
||||
long value = Long.parseLong(prefString);
|
||||
return of(value > 0, Math.abs(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -93,7 +93,7 @@ public class WalletManager {
|
||||
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, getNetworkType().getValue());
|
||||
Wallet wallet = new Wallet(walletHandle);
|
||||
manageWallet(wallet);
|
||||
if (wallet.getStatus().isOk()) {
|
||||
if (wallet.getStatus().isOk() && (wallet.getNetworkType() == NetworkType.NetworkType_Mainnet)) {
|
||||
// (Re-)Estimate restore height based on what we know
|
||||
final long oldHeight = wallet.getRestoreHeight();
|
||||
// Go back 4 days if we don't have a precise restore height
|
||||
|
@@ -318,9 +318,10 @@ public class WalletService extends Service {
|
||||
|
||||
TxData txData = extras.getParcelable(REQUEST_CMD_TX_DATA);
|
||||
String txTag = extras.getString(REQUEST_CMD_TX_TAG);
|
||||
assert txData != null;
|
||||
txData.createPocketChange(myWallet);
|
||||
PendingTransaction pendingTransaction = myWallet.createTransaction(txData);
|
||||
PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||
Timber.d("transaction status %s", status);
|
||||
if (status != PendingTransaction.Status.Status_Ok) {
|
||||
Timber.w("Create Transaction failed: %s", pendingTransaction.getErrorString());
|
||||
}
|
||||
|
@@ -33,5 +33,6 @@ public interface ExchangeApi {
|
||||
void queryExchangeRate(@NonNull final String baseCurrency, @NonNull final String quoteCurrency,
|
||||
@NonNull final ExchangeCallback callback);
|
||||
|
||||
String getName();
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user