From 669516c60b96aa083f576ff9bf17df520bf591dc Mon Sep 17 00:00:00 2001 From: m2049r Date: Thu, 6 May 2021 00:03:39 +0200 Subject: [PATCH 01/15] add USE_FINGERPRINT again (#766) and update sdk --- app/build.gradle | 6 +++--- app/src/main/AndroidManifest.xml | 5 +++-- build.gradle | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index edc2847..df633e0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,14 +2,14 @@ apply plugin: 'com.android.application' android { compileSdkVersion 30 - buildToolsVersion '29.0.3' + buildToolsVersion '30.0.3' ndkVersion '17.2.4988734' defaultConfig { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1005 - versionName "2.0.5 'Puginarug'" + versionCode 1006 + versionName "2.0.6 'Puginarug'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e17df51..4902ec0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + @@ -11,11 +12,11 @@ @@ -34,7 +35,7 @@ android:configChanges="orientation|keyboardHidden|uiMode" android:label="@string/wallet_activity_name" android:launchMode="singleTask" - android:screenOrientation="behind"/> + android:screenOrientation="behind" /> Date: Wed, 19 May 2021 22:20:47 +0200 Subject: [PATCH 02/15] fix migration of devices with permission timeouts --- app/build.gradle | 4 ++-- .../java/com/m2049r/xmrwallet/util/LegacyStorageHelper.java | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index df633e0..138c42f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1006 - versionName "2.0.6 'Puginarug'" + versionCode 1007 + versionName "2.0.7 'Puginarug'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/LegacyStorageHelper.java b/app/src/main/java/com/m2049r/xmrwallet/util/LegacyStorageHelper.java index 68a1f6b..20ea61c 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/util/LegacyStorageHelper.java +++ b/app/src/main/java/com/m2049r/xmrwallet/util/LegacyStorageHelper.java @@ -31,8 +31,7 @@ public class LegacyStorageHelper { try { if (isStorageMigrated(context)) return; if (!hasReadPermission(context)) { - // nothing to migrate, so don't try again - setStorageMigrated(context); + // can't migrate - don't remember this, as the user may turn on permissions later return; } final File oldRoot = getWalletRoot(); From c4958f6c542420b15fd6b05419a6c2cd95828431 Mon Sep 17 00:00:00 2001 From: m2049r Date: Fri, 21 May 2021 08:45:45 +0200 Subject: [PATCH 03/15] use settleAmount (#768) --- .../send/SendAddressWizardFragment.java | 2 +- .../send/SendBtcAmountWizardFragment.java | 1 - .../send/SendBtcConfirmWizardFragment.java | 42 ++++--------------- .../sideshift/network/RequestQuoteImpl.java | 10 ++--- .../sideshift/network/SideShiftApiImpl.java | 4 +- .../SideShiftApiRequestQuoteTest.java | 18 ++++---- 6 files changed, 26 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java index 38feb6a..56a12e3 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java @@ -349,7 +349,7 @@ public class SendAddressWizardFragment extends SendWizardFragment { private boolean checkAddress() { boolean ok = checkAddressNoError(); - if (!ok) { + if (possibleCryptos.isEmpty()) { etAddress.setError(getString(R.string.send_address_invalid)); } else { etAddress.setError(null); diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java index 0a90c2a..8f1616f 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java @@ -90,7 +90,6 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment { return view; } - @Override public boolean onValidateFields() { Timber.i(maxBtc + "/" + minBtc); diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java index b552854..94d2e8e 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java @@ -359,40 +359,22 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements } private RequestQuote xmrtoQuote = null; - private int stageARetries = 0; - private final int RETRIES = 3; - private double stageAPrice = 0; private void processStageA(final RequestQuote requestQuote) { Timber.d("processCreateOrder %s", requestQuote.getId()); TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData(); - // verify the BTC amount is correct (price can change and we can only specify XMR amount) + // verify the BTC amount is correct if (requestQuote.getBtcAmount() != txDataBtc.getBtcAmount()) { - if (--stageARetries <= 0) { - Timber.d("Failed to get quote"); - getView().post(() -> - showStageError(ShiftError.Error.SERVICE.toString(), - getString(R.string.shift_noquote), - getString(R.string.shift_checkamount))); - return; // just stop for now - } - if (stageAPrice == requestQuote.getPrice()) { - // same price but different BTC amount - something else is wrong (e.g. too many decimals) - Timber.d("Price unchanged"); - getView().post(() -> - showStageError(ShiftError.Error.SERVICE.toString(), - getString(R.string.shift_noquote), - getString(R.string.shift_checkamount))); - return; // just stop for now - } - stageAPrice = requestQuote.getPrice(); - // recalc XMR and try again - txDataBtc.setAmount(txDataBtc.getBtcAmount() / requestQuote.getPrice()); - getView().post(this::stageAOneShot); - return; // stageA will run in the main thread + Timber.d("Failed to get quote"); + getView().post(() -> showStageError(ShiftError.Error.SERVICE.toString(), + getString(R.string.shift_noquote), + getString(R.string.shift_checkamount))); + return; // just stop for now } xmrtoQuote = requestQuote; + txDataBtc.setAmount(xmrtoQuote.getXmrAmount()); getView().post(() -> { + // show data from the actual quote as that is what is used to NumberFormat df = NumberFormat.getInstance(Locale.US); df.setMaximumFractionDigits(12); final String btcAmount = df.format(xmrtoQuote.getBtcAmount()); @@ -438,18 +420,12 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements } private void stageA() { - stageARetries = RETRIES; - stageAOneShot(); - } - - private void stageAOneShot() { if (!isResumed) return; Timber.d("Request Quote"); xmrtoQuote = null; xmrtoOrder = null; showProgress(1, getString(R.string.label_send_progress_xmrto_create)); TxDataBtc txDataBtc = (TxDataBtc) sendListener.getTxData(); - stageAPrice = 0; ShiftCallback callback = new ShiftCallback() { @Override @@ -473,7 +449,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements } }; - getXmrToApi().requestQuote(txDataBtc.getAmountAsDouble(), callback); + getXmrToApi().requestQuote(txDataBtc.getBtcAmount(), callback); } private CreateOrder xmrtoOrder = null; diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java index 6a1b802..c87465e 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java @@ -74,10 +74,10 @@ class RequestQuoteImpl implements RequestQuote { price = jsonObject.getDouble("rate"); } - public static void call(@NonNull final ShiftApiCall api, final double xmrAmount, + public static void call(@NonNull final ShiftApiCall api, final double btcAmount, @NonNull final ShiftCallback callback) { try { - final JSONObject request = createRequest(xmrAmount); + final JSONObject request = createRequest(btcAmount); api.call("quotes", request, new NetworkCallback() { @Override public void onSuccess(JSONObject jsonObject) { @@ -104,13 +104,13 @@ class RequestQuoteImpl implements RequestQuote { * @param xmrAmount how much XMR to shift to BTC */ - static JSONObject createRequest(final double xmrAmount) throws JSONException { + static JSONObject createRequest(final double btcAmount) throws JSONException { final JSONObject jsonObject = new JSONObject(); jsonObject.put("depositMethod", "xmr"); jsonObject.put("settleMethod", ServiceHelper.ASSET); // #sideshift is silly and likes numbers as strings - String amount = AmountFormatter.format(xmrAmount); - jsonObject.put("depositAmount", amount); + String amount = AmountFormatter.format(btcAmount); + jsonObject.put("settleAmount", amount); return jsonObject; } diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java index 6cec574..b27ae60 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java @@ -64,8 +64,8 @@ public class SideShiftApiImpl implements SideShiftApi, ShiftApiCall { } @Override - public void requestQuote(final double xmrAmount, @NonNull final ShiftCallback callback) { - RequestQuoteImpl.call(this, xmrAmount, callback); + public void requestQuote(final double btcAmount, @NonNull final ShiftCallback callback) { + RequestQuoteImpl.call(this, btcAmount, callback); } @Override diff --git a/app/src/test/java/com/m2049r/xmrwallet/service/shift/sideshift/SideShiftApiRequestQuoteTest.java b/app/src/test/java/com/m2049r/xmrwallet/service/shift/sideshift/SideShiftApiRequestQuoteTest.java index e6980a8..d5a112e 100644 --- a/app/src/test/java/com/m2049r/xmrwallet/service/shift/sideshift/SideShiftApiRequestQuoteTest.java +++ b/app/src/test/java/com/m2049r/xmrwallet/service/shift/sideshift/SideShiftApiRequestQuoteTest.java @@ -95,7 +95,7 @@ public class SideShiftApiRequestQuoteTest { @Test public void requestQuote_shouldContainValidBody() throws InterruptedException { - final String validBody = "{\"depositAmount\":\"1.01\",\"settleMethod\":\"btc\",\"depositMethod\":\"xmr\"}"; + final String validBody = "{\"settleAmount\":\"1.01\",\"settleMethod\":\"btc\",\"depositMethod\":\"xmr\"}"; xmrToApi.requestQuote(1.01, mockXmrToCallback); RecordedRequest request = mockWebServer.takeRequest(); @@ -106,18 +106,18 @@ public class SideShiftApiRequestQuoteTest { @Test public void requestQuote_wasSuccessfulShouldRespondWithQuote() throws TimeoutException { - final double xmrAmount = 1.01; + final double btcAmount = 1.01; final double rate = 0.00397838; final String uuid = "66fc0749-f320-4361-b0fb-7873576cba67"; MockResponse jsonMockResponse = new MockResponse().setBody( - createMockRequestQuoteResponse(xmrAmount, rate, uuid)); + createMockRequestQuoteResponse(btcAmount, rate, uuid)); mockWebServer.enqueue(jsonMockResponse); - xmrToApi.requestQuote(xmrAmount, new ShiftCallback() { + xmrToApi.requestQuote(btcAmount, new ShiftCallback() { @Override public void onSuccess(final RequestQuote quote) { - waiter.assertEquals(quote.getBtcAmount(), xmrAmount * rate); - waiter.assertEquals(quote.getXmrAmount(), xmrAmount); + waiter.assertEquals(quote.getXmrAmount(), btcAmount / rate); + waiter.assertEquals(quote.getBtcAmount(), btcAmount); waiter.assertEquals(quote.getId(), uuid); waiter.resume(); } @@ -181,17 +181,17 @@ public class SideShiftApiRequestQuoteTest { waiter.await(); } - private String createMockRequestQuoteResponse(final double xmrAmount, final double rate, + private String createMockRequestQuoteResponse(final double btcAmount, final double rate, final String uuid) { return "{\n" + "\"createdAt\":\"2021-02-04T13:09:14.484Z\",\n" + - "\"depositAmount\":\"" + xmrAmount + "\",\n" + + "\"settleAmount\":\"" + btcAmount + "\",\n" + "\"depositMethod\":\"xmr\",\n" + "\"expiresAt\":\"2021-02-04T13:24:14.484Z\",\n" + "\"id\":\"" + uuid + "\",\n" + "\"rate\":\"" + rate + "\",\n" + - "\"settleAmount\":\"" + (xmrAmount * rate) + "\",\n" + + "\"depositAmount\":\"" + (btcAmount / rate) + "\",\n" + "\"settleMethod\":\"btc\"\n" + "}"; } From aa768596a441535202f75367e074f437feaa9baf Mon Sep 17 00:00:00 2001 From: m2049r Date: Fri, 21 May 2021 08:49:13 +0200 Subject: [PATCH 04/15] bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 138c42f..9a8a6f4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1007 - versionName "2.0.7 'Puginarug'" + versionCode 1008 + versionName "2.0.8 'Puginarug'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { From 54e54b2a8a4f6457ddb9e99875a6d82bb1c13912 Mon Sep 17 00:00:00 2001 From: paxriel Date: Wed, 4 Aug 2021 16:37:31 +0800 Subject: [PATCH 05/15] Fixed boost JFrog repo (#772) --- external-libs/android32.Dockerfile | 2 +- external-libs/android32_x86.Dockerfile | 2 +- external-libs/android64.Dockerfile | 2 +- external-libs/android64_x86.Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/external-libs/android32.Dockerfile b/external-libs/android32.Dockerfile index 68e1804..93e60ee 100644 --- a/external-libs/android32.Dockerfile +++ b/external-libs/android32.Dockerfile @@ -50,7 +50,7 @@ ARG BOOST_VERSION=1_70_0 ARG BOOST_VERSION_DOT=1.70.0 ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 RUN set -x \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ && rm -f boost_${BOOST_VERSION}.tar.bz2 \ diff --git a/external-libs/android32_x86.Dockerfile b/external-libs/android32_x86.Dockerfile index 7ba7bcf..7e763ac 100644 --- a/external-libs/android32_x86.Dockerfile +++ b/external-libs/android32_x86.Dockerfile @@ -50,7 +50,7 @@ ARG BOOST_VERSION=1_70_0 ARG BOOST_VERSION_DOT=1.70.0 ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 RUN set -x \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ && rm -f boost_${BOOST_VERSION}.tar.bz2 \ diff --git a/external-libs/android64.Dockerfile b/external-libs/android64.Dockerfile index dac9ac7..530b545 100644 --- a/external-libs/android64.Dockerfile +++ b/external-libs/android64.Dockerfile @@ -50,7 +50,7 @@ ARG BOOST_VERSION=1_70_0 ARG BOOST_VERSION_DOT=1.70.0 ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 RUN set -x \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ && rm -f boost_${BOOST_VERSION}.tar.bz2 \ diff --git a/external-libs/android64_x86.Dockerfile b/external-libs/android64_x86.Dockerfile index 0bd6d55..8a58010 100644 --- a/external-libs/android64_x86.Dockerfile +++ b/external-libs/android64_x86.Dockerfile @@ -50,7 +50,7 @@ ARG BOOST_VERSION=1_70_0 ARG BOOST_VERSION_DOT=1.70.0 ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 RUN set -x \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ && rm -f boost_${BOOST_VERSION}.tar.bz2 \ From 002dfd5d5842215239b36b6950030441d3c33f60 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sat, 7 Aug 2021 11:04:18 +0200 Subject: [PATCH 06/15] rewrite Wallet.isSynchronized() (#774) --- app/src/main/cpp/monerujo.cpp | 2 +- .../com/m2049r/xmrwallet/WalletActivity.java | 1 - .../java/com/m2049r/xmrwallet/model/Wallet.java | 17 ++++++++++++----- .../m2049r/xmrwallet/service/WalletService.java | 15 +++++++-------- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/app/src/main/cpp/monerujo.cpp b/app/src/main/cpp/monerujo.cpp index 77231f2..1c46099 100644 --- a/app/src/main/cpp/monerujo.cpp +++ b/app/src/main/cpp/monerujo.cpp @@ -914,7 +914,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_refreshAsync(JNIEnv *env, jobject instanc //virtual void rescanBlockchainAsync() = 0; JNIEXPORT void JNICALL -Java_com_m2049r_xmrwallet_model_Wallet_rescanBlockchainAsync(JNIEnv *env, jobject instance) { +Java_com_m2049r_xmrwallet_model_Wallet_rescanBlockchainAsyncJ(JNIEnv *env, jobject instance) { Bitmonero::Wallet *wallet = getHandle(env, instance); wallet->rescanBlockchainAsync(); } diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java index a35ced4..caff0f0 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java @@ -578,7 +578,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste try { final WalletFragment walletFragment = getWalletFragment(); if (wallet.isSynchronized()) { - Timber.d("onRefreshed() synced"); releaseWakeLock(RELEASE_WAKE_LOCK_DELAY); // the idea is to stay awake until synced if (!synced) { // first sync onProgress(-1); diff --git a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java index 103a50a..6653418 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java +++ b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java @@ -273,12 +273,14 @@ public class Wallet { public native long getDaemonBlockChainTargetHeight(); - public native boolean isSynchronizedJ(); + boolean synced = false; public boolean isSynchronized() { - final long daemonHeight = getDaemonBlockChainHeight(); - if (daemonHeight == 0) return false; - return isSynchronizedJ() && (getBlockChainHeight() == daemonHeight); + return synced; + } + + public void setSynchronized() { + this.synced = true; } public static native String getDisplayAmount(long amount); @@ -309,7 +311,12 @@ public class Wallet { public native void refreshAsync(); - public native void rescanBlockchainAsync(); + public native void rescanBlockchainAsyncJ(); + + public void rescanBlockchainAsync() { + synced = false; + rescanBlockchainAsyncJ(); + } //TODO virtual void setAutoRefreshInterval(int millis) = 0; //TODO virtual int autoRefreshInterval() const = 0; diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java index 9598a4b..4d1a3d3 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java @@ -112,7 +112,7 @@ public class WalletService extends Service { int lastTxCount = 0; public void newBlock(long height) { - Wallet wallet = getWallet(); + final Wallet wallet = getWallet(); if (wallet == null) throw new IllegalStateException("No wallet!"); // don't flood with an update for every block ... if (lastBlockTime < System.currentTimeMillis() - 2000) { @@ -145,17 +145,16 @@ public class WalletService extends Service { updated = true; } - public void refreshed() { + public void refreshed() { // this means it's synced Timber.d("refreshed()"); - Wallet wallet = getWallet(); + final Wallet wallet = getWallet(); if (wallet == null) throw new IllegalStateException("No wallet!"); + wallet.setSynchronized(); if (updated) { + updateDaemonState(wallet, wallet.getBlockChainHeight()); + wallet.getHistory().refreshWithNotes(wallet); if (observer != null) { - updateDaemonState(wallet, 0); - wallet.getHistory().refreshWithNotes(wallet); - if (observer != null) { - updated = !observer.onRefreshed(wallet, true); - } + updated = !observer.onRefreshed(wallet, true); } } } From 9cd8a75dc623904f34e39ebb436c8953b90a3c5b Mon Sep 17 00:00:00 2001 From: m2049r Date: Sat, 7 Aug 2021 11:17:13 +0200 Subject: [PATCH 07/15] confirmations indicator (#775) --- .../com/m2049r/xmrwallet/WalletFragment.java | 12 +++-- .../layout/TransactionInfoAdapter.java | 39 ++++++++++++++- .../xmrwallet/service/WalletService.java | 35 ++++++-------- app/src/main/res/layout/item_transaction.xml | 47 +++++++++++++++---- build.gradle | 2 +- 5 files changed, 100 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java index 3bd60ec..c1e53cd 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java @@ -58,7 +58,6 @@ import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Objects; import timber.log.Timber; @@ -128,7 +127,7 @@ public class WalletFragment extends Fragment currencies.add(Helper.BASE_CRYPTO); if (Helper.SHOW_EXCHANGERATES) currencies.addAll(Arrays.asList(getResources().getStringArray(R.array.currency))); - ArrayAdapter spinnerAdapter = new ArrayAdapter<>(Objects.requireNonNull(getContext()), R.layout.item_spinner_balance, currencies); + ArrayAdapter spinnerAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner_balance, currencies); spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); sCurrency.setAdapter(spinnerAdapter); @@ -346,13 +345,18 @@ public class WalletFragment extends Fragment // if account index has changed scroll to top? private int accountIndex = 0; - public void onRefreshed(final Wallet wallet, final boolean full) { + public void onRefreshed(final Wallet wallet, boolean full) { Timber.d("onRefreshed(%b)", full); + if (adapter.needsTransactionUpdateOnNewBlock()) { + wallet.getHistory().refresh(); + full = true; + } if (full) { List list = new ArrayList<>(); final long streetHeight = activityCallback.getStreetModeHeight(); Timber.d("StreetHeight=%d", streetHeight); + wallet.getHistory().refresh(); for (TransactionInfo info : wallet.getHistory().getAll()) { Timber.d("TxHeight=%d, Label=%s", info.blockheight, info.subaddressLabel); if ((info.isPending || (info.blockheight >= streetHeight)) @@ -561,7 +565,7 @@ public class WalletFragment extends Fragment //TODO figure out why gunther disappears on return from send although he is still set if (enable) { if (streetGunther == null) - streetGunther = ContextCompat.getDrawable(Objects.requireNonNull(getContext()), R.drawable.ic_gunther_streetmode); + streetGunther = ContextCompat.getDrawable(requireContext(), R.drawable.ic_gunther_streetmode); ivStreetGunther.setImageDrawable(streetGunther); } else ivStreetGunther.setImageDrawable(null); diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java index cb21a92..835c3a1 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java @@ -30,6 +30,7 @@ import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.progressindicator.CircularProgressIndicator; import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.data.Crypto; import com.m2049r.xmrwallet.data.UserNotes; @@ -48,7 +49,9 @@ import java.util.TimeZone; import timber.log.Timber; public class TransactionInfoAdapter extends RecyclerView.Adapter { - private final SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + private final static int MAX_CONFIRMATIONS = 10; + + private final static SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm"); private final int outboundColour; private final int inboundColour; @@ -77,6 +80,10 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter 0) && (infoItems.get(0).confirmations < MAX_CONFIRMATIONS); + } + private static class TransactionInfoDiff extends DiffCallback { public TransactionInfoDiff(List oldList, List newList) { @@ -95,6 +102,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter lastTxCount) { - // update the transaction list only if we have more than before - lastTxCount = txCount; - fullRefresh = true; - } + Timber.d("newBlock() @ %d with observer %s", height, observer); + if (observer != null) { + boolean fullRefresh = false; + updateDaemonState(wallet, wallet.isSynchronized() ? height : 0); + if (!wallet.isSynchronized()) { + updated = true; + // we want to see our transactions as they come in + wallet.getHistory().refresh(); + int txCount = wallet.getHistory().getCount(); + if (txCount > lastTxCount) { + // update the transaction list only if we have more than before + lastTxCount = txCount; + fullRefresh = true; } - if (observer != null) - observer.onRefreshed(wallet, fullRefresh); } + if (observer != null) + observer.onRefreshed(wallet, fullRefresh); } } diff --git a/app/src/main/res/layout/item_transaction.xml b/app/src/main/res/layout/item_transaction.xml index 00d66df..c9e55d7 100644 --- a/app/src/main/res/layout/item_transaction.xml +++ b/app/src/main/res/layout/item_transaction.xml @@ -1,5 +1,6 @@ - + + + + + + + + diff --git a/build.gradle b/build.gradle index c22dc87..4406443 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.0' + classpath 'com.android.tools.build:gradle:4.2.2' } } From d801a50962ba7c344589d73460bb357bb0d8cf87 Mon Sep 17 00:00:00 2001 From: phwright <65078648+phwright@users.noreply.github.com> Date: Sat, 7 Aug 2021 12:19:24 +0300 Subject: [PATCH 08/15] Arabic Translation (#767) * Arabic Translation --- app/src/main/res/values-ar/about.xml | 48 +++ app/src/main/res/values-ar/help.xml | 215 ++++++++++++ app/src/main/res/values-ar/strings.xml | 437 +++++++++++++++++++++++++ 3 files changed, 700 insertions(+) create mode 100644 app/src/main/res/values-ar/about.xml create mode 100644 app/src/main/res/values-ar/help.xml create mode 100644 app/src/main/res/values-ar/strings.xml diff --git a/app/src/main/res/values-ar/about.xml b/app/src/main/res/values-ar/about.xml new file mode 100644 index 0000000..1d6b13f --- /dev/null +++ b/app/src/main/res/values-ar/about.xml @@ -0,0 +1,48 @@ + + + أغلق + أنا مونيرويو + النسخة %1$s (%2$d) + + الاعتمادات +
+ m2049r, baltsar777, anhdres, keejef, + rehrar, EarlOfEgo, ErCiccione et al. +

+ monerujo.io + ]]>
+ + سياسة الخصوصية +

+ هذه الصفحة تخبرك بسياستنا بخصوص التجميع، الاستخدام، و الافصاح عن المعلومات الشخصيةالتي نستلمها من مستخدمي تطبيقنا (مونيرويو: محفظة مونيرو) +

+

باستخدامك هذا التطبيق أنت توافق تجميع و استخدام المعلومات وفقاً لهذه السياسة +

+

البيانات المجمعة

+

المعلومات الشخصية هي نوع من البيانات التي قد تعرف هوية شخص ما +

+

مفاتيح مونيرو و العناوين العامة مجمعة و معالجة من قبل التطبيق محليا لغرض معالجة المعاملات و هي ترسل الى شبكة مونيرو في حالة مشفرة +

+

لا يجمع التطبيق أي معلومات شخصية أخرى

+

إذا أنت تستخدم خدمة الصراف (اختياري)، مونيرويو يجلب سعر الصرف عبر api coinmarketcap.com. اطلع على سياسة الخصوصية الخاصة بهم على https://coinmarketcap.com/privacy لتفاصيل على كيف تجمع بياناتك التي في الطلب.

+

عندما تستعمل التطبيق لتدفع إلى عنوانين بيتكوين، فأنت تستعمل خدمة SideShift.ai. اطلع على سياسة الخصوصية الخاصة بهم على https://sideshift.ai للتفاصيل. يرسل مونيرويو عنوان بيتوين و المبلغ إليهم. سيأخذ أيضاً عنوان بروتوكول الإنترنت (ip) الخاص بك.

+

صلاحيات التطبيق

+
    +
  • الإنترنت: للإتصال بشبكة مونيرو عبر عقدة مونيرو
  • +
  • قرائة ملفات التخزين الخارجي: لقرائة ملفات المحفظة المخزنة على الجهاز
  • +
  • الكتابة إلى التخزين الخارجي: لكتابة ملفات المحفظة المخزنة على الجهاز
  • +
  • قفل الإيقاظ: لإبقاء الجهاز ياقظاً عند التزامن
  • +
  • الكاميرا: لمسح رموز الاستجابة السريعة (qr) لاستلام مونيرو
  • +
+

التغيرات لسياسة الخصوصية هذه

+

. يمكن أن نحدث سياسة الخصوصية هذه من حين إلى أخرى. سنقوم بتنبيهك لأاي تغيرات بنشر سياسة الخصوصية الجديدة في التطبيق و على الموقع (www.monerujo.io) + ننصحك أن تراجع هذه السياسة بشكل دوري لأاي تغيرات +

آخر تحديث لسياسة الخصوصية هذه كان في 10/11/2017 +

+

تواصل معنا

+

privacy@monerujo.io.إذا كان لديك أي سؤال عن سياستنا أو عن كيفية تجميع بياناتك و معالجتها، الرجاء إرسال بريد الكتروني إلى +

+ ]]>
+
diff --git a/app/src/main/res/values-ar/help.xml b/app/src/main/res/values-ar/help.xml new file mode 100644 index 0000000..3d69d57 --- /dev/null +++ b/app/src/main/res/values-ar/help.xml @@ -0,0 +1,215 @@ + + + أنشئ محفظة - جديدة +

إذا كنت تحتاج إلى عنوان مونيرو جديد!

+

أدخل اسم محفظة و كلمة سر فريدين. + كلمة المرور مستخدمة لتأمين بيانات محفظتك على الجهاز. استخدم كلمة سر قوية - و استخدام عبارة سر أفضل.

+

دون البذرة الذاكرية!

+

سترى في الشاشة التالية \"البذرة الذاكرية\" ذات 25 كلمة خاصة بك. هي كل ما تحتاجه لاسترجاع محفظتك لاحقاً و الحصول على وصول كامل لمالك. + إبقائها آمنة و خاصة مهم جداً، فهي تعطي أي أحد وصولاً كاملاً لمالك!

+

إذا نسيت كلمة مرور محفظتك يمكنك استرجاع محفظتك باستعمال بذرة الذاكرة.

+

ليس هناك طريقة لاسترجاع البذرة الذاكرية، إذا أضعتها ضاع مالك! + أيضاً، لا يمكن لبذرة الذاكرية أن تتغير و إذا ما سرقت أو انفضحت، + عليك أن تحول مالك إلى محفظة جديدة (مع بذرة ذاكرية جديدة). لذا من + الأفضل عمل نسخ احتياطية من بذرتك بكتابتها و تخزينها في أكثر من + مكان آمن

+ ]]>
+ + أنشئ محفظة - بذرة +

إذا لديك عنوان مونيرو و تريد استعادة المعاملات من سلسلة الكتل!

+

أدخل اسم محفظة و كلمة سر فريدين. + كلمة المرور مستخدمة لتأمين بيانات محفظتك على الجهاز. استخدم كلمة سر قوية - و استخدام عبارة سر أفضل.

+

أدخل بذرتك في حقل \"البذرة الذاكيرة\".

+

أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

+ ]]>
+ + أنشئ محفظة - لدجر +

إذا كنت تسترجع محفظتك من جهاز لدجر نانو اس.

+

مفاتيحك السرية لا تغادر جهاز لدجر، لذا تجتاج إلى توصيله كلما أردت الوصول لمحفظتك.

+

أدخل اسم محفظة و كلمة سر فريدين. كلمة المرور مستخدمة لتأمين بيانات محفظتك على جهاز الأندرويد. استخدم كلمة سر قوية - واستخدام عبارة سر أفضل.

+

أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

+ ]]>
+ + أنشئ محفظة - مفاتيح +

إذا كنت تسترجع محفظتك باستخدام مفاتيحك!

+

أدخل اسم محفظة و كلمة سر فريدين. كلمة المرور مستخدمة لتأمين بيانات محفظتك على جهاز الأندرويد. استخدم كلمة سر قوية - واستخدام عبارة سر أفضل.

+

أدخل عنوان مونيرو في حقل \"العنوان العام\" و عبئ \"مفتاح الرؤية\" و \"مفتاح الانفاق\".

+

أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

+ ]]>
+ + أنشئ محفظة - رؤية +

إذا كنت تريد مراقبة المعاملات القادمة إلى المحفظة!

+

أدخل اسم محفظة و كلمة سر فريدين. كلمة المرور مستخدمة لتأمين بيانات محفظتك على جهاز الأندرويد. استخدم كلمة سر قوية - واستخدام عبارة سر أفضل.

+

أدخل عنوان مونيرو ملكك في حقل "\عنوان عام"\ و املأ \مفتاح الرؤية"\".

+

أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

+ ]]>
+ + تفاصيل المحفظة +

العنوان العام

+ عنوانك العام بمثابة رقم حسابك البنكي يمكنك مشاركته مع أي أحد دون خوف من خسارة مونيرو الخاص بك. يرسل الناس المونيرو إلى محفظتك باستخدام هذا العنوان. +

البذرة الذاكرية

+ هي كل ما تحتاجه لاسترجاع محفظتك و الحصول على وصول كامل لمالك. إبقائها خاصة و آمنة مهم جداًَ، فهي تعطي لي أحد وصولاً كاملاً لمونيرواتك! إذا لم تكتبها في مكان آمن رجاءً افعل! +

كلمة مرور استرجاع ملفات المحفظة

+ تأكد من تدوين كلمة المرور هذه. ستحتاج إليها إذا أعدت ضبط جهازك أو ألغيت تثبيت التطبيق.
+

CrAzYpass

+ إذا كانت كلمة المرور المعروضة هنا هي أبجدية رقمية من 52 جزء في مجموعات من 4 - تهانينا! + ملفات محفظتك مؤمنة باستخدام مفتاح 256 بت مولد باستخدام خصائص أمان جهازك + أساساً على عبارة المرور التي خترتها (عند الإنشاء أو بتغييرها). هذا يجعلها صعبة جداً للاختراق!
+ هذه الميزة اجبارية لكل المحافظ الجديدة. +

كلمة السر القديمة

+ إذا ترى عبارة مرورك هنا، محفظتك ليسب بأمان استخدام CrAzYpass. لإصلاح هذا فقط اختار \"غير كلمة المرور\" من القائمة. بعد إدخالك عبارة مرور جديدة (ربما نفسها القديمة) سيولد التطبيق CrAzYpass لك و سيؤمن ملفات محفظتك به. اكتبه! +

CrAzYpass محافظ

+ إذا احبجت في أي وقت إلى إعادة تثبيت مونيرويو (بعد إعادة ضبط هاتفك أو التبديل إلى جهاز جديد مثلاً) أو إذا أردت استخدام ملفات المحفظة جهاز مختلف أو حاسوب، فيجب عليك استعمال كلمة المرور الاسترجاعية هذه للوصول إلى محفظتك مجدداً.
+ بإختيارك \"غير عبارة المرور\" من القاءمة، يمكنك اختيار عبارة مرور أخرى. انتبة أن هذا سيولد كلمة مرور استرجاعية جديدة. اكتبها! +

مفتاح الرؤية

+ يمكنك استخدام مفتاح الرؤية الخاص بك لمراقبة المعاملات القادمة لمحفظتك دون اعطاء إذن لإنفاق المال داخل محفظتك. +

مفتاح الإنفاق

+ مفتاح الانفاق الخاص بك يسمح لأي شحص بانفاق المونيرو المتعلق بمحفظتك، لذا لا تخبر أجداً بالمفتاح. أبقه آمناً كبذرة الذاكرية. + ]]>
+ + قائمة المحافظ +

العقدة

+

.مونيرويو يستخدم عقدة بعيدة للاتصال بشبكة مونيرو دون الحاجة إلى تنزيل و الاحتفاظ بنسخة كاملة من سلسة الكتل. يمكنك العثور على قائمة من العقد الشائعة أو تعلم كيف تشغل عقدة خاصة بك هنا https://moneroworld.com

+

يأتي مونيرويو مع بعض العقد البعيدة المحددة مسبقاً. مونيرويو يتذكر آخر خمس عقد مستخدمة.

+ +

المحافظ

+

هنا ترى محافظك. هن موجودات في مجلد monerujo في التخزين الداخلى لجهازك. + يمكنك استعمال تطبيق مستكشف ملفات لرؤيتهن. ينبغي عليك عمل نسخ احتياطية من هذا المجلد + على أسس منتظمة لتخزين خارج جهازك في حالة انفجاره أو سرقته

+

اختر محفظة لتفتحها أو المس زر \"+\" لإنشاء واحدة جديدة. أو اختر واحدة من عمليات المحفظة:

+

التفاصيل

+

أظهر تفاصيل المحفظة، البذرة و المفاتيح.

+

استلم

+

أنشئ رمز استجابة سريعة(qr code) لاستلام المونيرو.

+

أعد التسمية

+

أعد تسمية المحفظة. النسخ الاحتياطية لا تعاد التسمية.

+

نسخة احتياطية

+

أنشئ نسخة من المحفظة في مجلد backups داخل مجلد monerujo مستبدلة النسخ السابقة هناك.

+

أرشيف

+

أنشئ نسخة احتياطية ثم احذف المحفظة. النسخة تبقى في مجلد backups إذا لم تعد بحاجة إلى نسخك الاحتياطية ينبغي أن تحذفهم باستعمال متصفح ملفات أو تطبيق حذف آمن.

+ ]]>
+ + تفاصيل المعاملة +

الوجهة

+ هذا هو العنوان العام للمحفظة التي تريد إرسال مونيرو إليها. +

معرف الدفع

+ يمكنك استخدام معرف دفع لتعريف السبب لارسالك مونيرو بين طرفين. هذا اختياري + و خاص. فمثلاً يسمح لشركة بتسوية معاملتك مع غرض شريته. +

TX ID

+ هذا هو معرف معاملتك. يمكنك استخدامه لتعريف معاملتك المشوشة في مستكشف سلسلة كتل مونيرو مثل https://xmrchain.net/ +

TX KEY (مفتاح المعاملة)

+ هذا هو مفتاح معاملتك الخاص، أبقه آمناً فإظهاره إلى طرف ثالث يظهر أي توقيع في (حلقة/طوق/خاتم) هو الخاص بك، جاعلاً معاملاتك شفافة. +

كتلة

+ هذه هي الكتلة التي تحتوي معاملتك. + ]]>
+ + أرسل +

عنوان المستلم

+

هذا هو العنوان العام للمحفظة التي تريد إرسال مونيرو إليها، يمكنك نسخه من الحافظة + ، مسح رمز استجابة سريعة (QR) أو إدخاله يدوياً. تأكد من العنوان لضمان عدم الارسال إلى عنوان خطأ.

+

بالإضافة إلى عنوان مونيرو يمكنك استعمال +

    +
  • مفتوحة (OpenAlias) لXMR أو BTC
  • +
  • عنوان بيتكوين
  • + + يرجى ملاحظة أن إرسال BTC يتم من خلال خدمة Sideshift.ai (انظر https://sideshift.ai + للتفاصيل). راجع قسم إرسال BTC أدناه.

    +

    معرف الدفع

    +

    يمكنك استخدام معرف دفع لتعريف السبب لارسالك مونيرو بين طرفين. هذا اختياري + و خاص. فمثلاً يسمح لشركة بتسوية معاملتك مع غرض شريته

    +

    إرسال بيتكوين

    +

    SideShift.ai

    +

    Sideshift.ai خدمة طرف ثالث تعمل كصرافة من مونيرو إلى بيتكوين. نستخدم API Sideshift.ai لإدراج دفع بيتكوين في مونيرويو. رجاءاً اطلع على https://sideshift.ai و قرر لنفسك إذا ما كانت جدمة تريد استخدامها. فريق مونيرويو ليس مرتبطاً بSideshift.ai ولا يمكنه مساعدتك مع خدمتهم

    +

    SideShift.ai سعر صرف

    +

    في شاشة \"المبلغ\" ستعرض عليك الضوابط الحالية لخدمة Sideshift.ai + هذه الضوابط تتضمن سعر الصرف الحالي بالإضافة إلى حدود BTC الدنيا و العليا. لاحظ أن هذا السعر ليس مضموناً في هذه المرحلة

    +

    SideShift.ai طلب

    +

    في شاشة \"أكد\" سترى طلب Sideshift.ai الفعلي. هذا الطلب صحيح لفترة محدودة + قد تلاحظ عداًَ تنازلياً على زر \"spend\". قد يكون سعر الصرف مختلفاً عن السعر الدلالي في الشاشة السابقة

    +

    السري SideShift.ai مفتاح

    +

    لأن مونيرويو فقط يتعامل مع جزء مونيرو من معاملتك يمكن لمفتاح Sideshift.ai السري الخاص البك أن يستعل لتتبع جزء بيتكوين من طلبك على موقع Sideshift.ai

    +

    SideShift.ai عد تنازلي

    +

    عند وصول العد التنازلي إلى الصفر، تحتاج إلى الحصول على سعر جديد من Sideshift.ai بالرجوع إلى الخطوة السابقة ثم العودة إلى شاشة \"أكد\"

    + ]]> + + إرسال بيتكوين +

    SideShift.ai

    +

    Sideshift.ai خدمة طرف ثالث تعمل كصرافة من مونيرو إلى بيتكوين. نستخدم API Sideshift.ai لإدراج دفع بيتكوين في مونيرويو. رجاءاً اطلع على https://sideshift.ai و قرر لنفسك إذا ما كانت جدمة تريد استخدامها. فريق مونيرويو ليس مرتبطاً بSideshift.ai ولا يمكنه مساعدتك مع خدمتهم.

    +

    SideShift.ai سعر صرف

    +

    في شاشة \"المبلغ\" ستعرض عليك الضوابط الحالية لخدمة Sideshift.ai + هذه الضوابط تتضمن سعر الصرف الحالي بالإضافة إلى حدود BTC الدنيا و العليا. لاحظ أن هذا السعر ليس مضموناً في هذه المرحلة.

    +

    SideShift.ai طلب

    +

    في شاشة \"أكد\" سترى طلب Sideshift.ai الفعلي. هذا الطلب صحيح لفترة محدودة + قد تلاحظ عداًَ تنازلياً على زر \"spend\". قد يكون سعر الصرف مختلفاً عن السعر الدلالي في الشاشة السابقة.

    +

    السري SideShift.ai مفتاح

    +

    لأن مونيرويو فقط يتعامل مع جزء مونيرو من معاملتك يمكن لمفتاح Sideshift.ai السري الخاص البك أن يستعل لتتبع جزء بيتكوين من طلبك على موقع Sideshift.ai

    +

    التنازلي! SideShift.ai عد

    +

    عند وصول العد التنازلي إلى الصفر، تحتاج إلى الحصول على سعر جديد من Sideshift.ai بالرجوع إلى الخطوة السابقة ثم العودة إلى شاشة \"أكد\"

    + + المحفظة +

    وضع الشارع

    +

    + يمكنك تفعيل/تعطيل وضع الشارع في القائمة أو أيقونة رأس غونثر. في هذا الوضع، رصيدك لا يظهر على أي شاشة لذا يمكنك استخدام محفظتك بأمان في الشارع، القهوة، أو أي مكان عام. المعاملات السابقة أيضاً مخفية. ستعرض المعاملات الجديدة لترى أنك أرسلت/استلمت موينرو.

    +

    مسح

    + لأن مونيرو يحب إبقاء الأشياء خاصة، كل مرة تفتح محفظة موينيرويو علينا مسح سلسلة الكتل لنرى إذا ما أرسل مونيرة إلى محفظتك. أحياناً يستغرق فترةً لأنك لم تزامن منذ فترة طويلة. +

    الرصيد

    +

    النجدة! رصيد محفظتي اختفى أو هو غير مؤكد!
    + لا تفزع! عندما ترسل المال من محفظتك، بعض رصيدك سيظهر مؤقتاً كغير مؤكد. + يحصل نتيجةً لكيفية تبادل مونيرو على سلسلة الكتل و كيفية عمل الفكة. إقرأ أكثر عن الفكة على https://getmonero.org/resources/moneropedia/change.html +

    قائمة المعاملات

    +

    في محافظ الرؤية، فقط تعرض المعاملات القادمة.

    + ]]>
    + + العقد +

    المختصر المفيد

    +

    أعد تحميل قائمة العقد بالسحب للأسفل & bookmark 3–5 عقد لتسمح لمونيرويو أن يختار الأفضل لك!

    +

    ما هي العقد؟

    +

    مونيرويو يستخدم عقدة خارجية لالتواصل بشبكة مونيرو دون الحاجة لتنزيل نسخة كاملة من سلسلة الكتل .

    +

    قائمة العقد

    +

    إذا القائمة فارغة، يمكنك إما إضافة العقد يدوياً أو دع مونيرويو يمسح الشبكة لك. أو كلا الأمرين. إقرأ أكثر…

    +

    تعرض قائمة العقد كل العقد المعروفة حالياً. إضافةً، الطابع \ الختم الزمني لأحدث كتلة معروفة لكل عقدة يظهر + تحت اسم العقدة. تظهر أيقونة تمثل سلوك استجابة العقدة (يشير إلى مستوى الاتصال المتوقع) بجانب كل عقدة.

    +

    أي عقدة في القائمة يمكن أن تعلم لاستعمال لاحق. + العقد التي لم تعلم ستنسى.

    +

    سيختار مونيرويو العقدة المعلمة الأمثل كل مرة تستعمله. + يفعل هذا بالتأكد من ارتفاع الكتلة (ما هي حداثة العقدة؟) + إضافة إلى استجابتها (ما سرعة استجابة العقدة للطلبات؟).

    +

    هذه القائمة مفروزة حسب هذه الخصائص، فالعقدة العليا هي التي يختارها مونيرويو الآن. سيظهر الجزء السفلى عقد بطيئة جداً أو غير متوفرة.

    +

    أضف عقدة

    +

    عند لمس زر "أضف عقدة" في الأسفل، سيطلب منك إدخال تفاصيل العقدة في الحوار التالى. + "العنوان" هو اسم المضيف أو عنوان IP للعقدة - هذا المدخل الإلزامي الوحيد. + أدخل "المنفذ" إذا تشتغل العقدة في منفذ غير افتراضي )18089) + يمكنك أيضاً تسمية العقدة لتتمكن من التعرف عليها بسهولة في وقت لاحق. + بعض العقد تتطلب بيانات اعتماد لاستخدامهم. أدخل اسم المستخدم و كلمة المرور المزودين في الحقول المناسبة. الآن يمكنك "اختبار" هذه الاعدادات. + ستعرض "نتائج الاختبار" ارتفاع الكتلة، وقت الاستجابة، و عنوان IP المستعمل. + قد تكون النتيجة خطأً - عادة لأن اسم المصيف المزود لا يمكن الوصول إليه في وقت معقول أو أن بيانات الاعتماد غير صحيحة.أو أن اسم المضيف/المنفذ لا يشيران إلى عقدة مونيرو حقيقية! + عند اجتياز الاختبار (لا اخطاء) - يمكنك لمس "حسناً" لحفظ و تعليم هذه العقدة

    +

    ابحث عن العقد

    +

    إضافةً، يمكنك مسح الشبكة للعقد. مونيرويو سيبدأ مسح الشبكة للعقد البعيدة في منفذ 18098. يبدأ بيؤال العقد المعلمة عن أنداد آخرين في شبكة مونيرو ثم يستمر بسؤالهم عن أندادهم، وهكذا. إذا لا تملك عقد معلمة (أو لا يخبروننا عن أندادهم)، مونيرويو سيتجه مباشرةً إلى عقد بذور مونيرو ضمن مونيرو. سيتوقف المسح عند العثور على 10 عقد بعيدة.

    + ]]>
    + + استخدام رابط دفع +

    لقد بدأت مونيرويو باستخدام رابط دفق. لإرسال المال افعل التالي:

    +

    + 1. المحفظة التي تريد الانفاق منها
    + 2. انتظر حتى تزامن المحفظة وamp; يظهر زر "أعط"
    + 3. المس زر "أعط" +

    +

    .ستعبأ تفاصيل الدفع. تأكد منهم ثم أكمل كأي معاملة أخرى

    + ]]>
    + + فهمت! + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..f40beaf --- /dev/null +++ b/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,437 @@ + + + محفظة + + عن + سياسة الخصوصية + + شارك + ساعدني + استلم + أعد التسمية … + أرشف + انشئ نسخة احتياطية + غير كلمة المرور + + … أكمل الكتابة + … مه + هيا يمكنك القيام بأفضل من هذا! + تكاد تصل … + أجل، كالمحترفين! + + المحافظ + الاعتمادات + حسناً + إلغاء + أغلق + المس لالتفاصيل + + نجح الإرسال + تم + + المس لرمز استجابة سريعة (qr) + + دفع BTC مفعل، المس لمعلومات أكثر. + لدجر مفعل، المس لمعلومات أكثر. + + أدخلت عنوان بيتكوين.
    + سترسل XMR و سيستلم المستلم BTC باستخدام خدمة Sideshift.ai + ]]>
    + + Sideshift.ai طلب + + %1$s BTC + + التأكيد معلق + الدفع معلق + Sideshift.ai عطل (%1$s) + BTC أرسل + جار الاستعلام … + + يمكنك إرسال %1$s — %2$s BTC.
    + Sideshift.ai يعطيك سعر صرف %3$s BTC حالياً. + ]]>
    + مبالغ حتى %1$s BTC سترسل فوراً! + ]]> + + الرصيد: %2$s BTC (%1$s XMR) + + ✔ معرف الدفع مدمج + تجهيز عمليتك + + جار إنشاء طلب Sideshift.ai + استعلام طلب Sideshift.ai + جار تجهيز معاملة مونيرو + + استعلام ضوابط Sideshift.ai + + Sideshift.ai عطل + رمز: %1$d + + المس لإعادة المحوالة + علقنا هنا! + يبدو أن Sideshift.ai ليس متوفراً حالياً! + + %1$s BTC = %2$s XMR + (الصرف: %1$s BTC/XMR) + + قم بزيارة Sideshift.ai للدعم و التتبع + المفتاح السري\nSideshift.ai + السري Sideshift.ai مفتاح + عنوان الوجهة BTC + المبلغ + + معرف المعاملة + عنوان الوجهة + ملاحظات + + جار إنشاء النسخة الاحتياطية + جار الأرشفة + جار إعادة التسمية + جار تغيير كلمة المرور + + جار اختتام الأمور …\nقد يستغرق هذا برهةً! + + نجح النسخ الاحتياطي + فشل النسخ الاحتياطي! + فشلت الأرشفة! + فشلت إعادة التسمية! + فشل تغيير كلمة السر! + تم تغيير كلمة السر + + العقدة + جار تحميل المحفظة … + حفظت المحفظة + فشل حفظ المحفظة! + جار الاتصال … + فشل الاتصال بالعقدة!\nتأكد من اسم المستخدم/كلمة المرور + نسخة العقدة غير متوافقة - حدث رجاءً! + العقدة غير صحيحة!\nجرب عقدة أخرى. + لا يمكن الوصول للعقدة!\nحاول مجدداً أو جرب عقدة أخرى. + + منقطعة + + فشلت المعاملة: %1$d + + !انتظرت طويلاً يا صاحبي! + + …ما زلت مشغولاً بمحفظتك الأخيرة + + أعد التسمية %1$s + + كلمة مرور جديدة ل %1$s + أعد كلمة المرور ل %1$s + كلمة السر ل%1$s + يمكنك أيضاً فتح المحفظة باستعمال البصمة.\nرجاءً المس الحساس. + جار فتح المحفظة… + لم يتعرف على البصمة. حاول مجدداً. + كلمة السر خاطئة! + كلمة المرور المحفوظة غير صحيحة.\nرجاءً أدخل كلمة المرور يدوياً. + المحفظة غير موجودة! + !يجب ضبط العقدة! + المحفظة لا تطابق الشبكة المختارة + + (مشاهدة فقط) + + استلم + أعط + + + %1$s XMR غير مأكد + + خدمة مونيرويو + + تزامن؛ + الكتل التبقية + جار مسح: + + التخرين الخارجي غير قابل للكتابة! افزع! + نحتاج إلى صلاحيات التزين الخارجي فعلاً! + لا كاميرا = لا مسح لرموز الاستجابة السريعة (QR)! + + مفتاح الرؤية + العنوان العام + Sideshift.ai مفتاح + نسخ مفتاح الرؤية إلى الحافظة! + نسخ مفتاح Sideshift.ai إلى الناسخة! + نسخ عنوان المحفظة للحافظة! + نسخ معرف المعاملة إلى الحافظة! + النسخ معطل لأسباب أمنية! + + لا يمكن الحصول على سعر الصرف!\nاستعمل XMR/XMR أو حاول مجدداً + + أنشئ محفظة + اسم المحفظة + كلمة مرور المحفظة + اسمح لفتح المحفظة بالبصمة + التوثيق بالبصمة +

    عند تفعيل التوثيق بالبصمة، يمكنك رؤية رصيد المحفظة و استلام المال دون ادخال كلمة السر.

    +

    لكن لزيادة الأمان، مونيرويو سيتطلب منك أن تدخل كلمةالمرور عند رؤية تفاصيل المحفضة أو إرسال المال.

    + تحذير أمني + +

    مثلا، ينكن لشخص خبيث فتح محفظتك و أنت نائم.

    + هل أنت متأكد أنك تريد تفعيل هذه ال + ]]>
    + السر لا تتطابق + لا يمكن لعبارة المرور أن تكون فارغة + انشئ لي محفظة و خلصنا! + دونت بذرة الذاكرة + + أعطني اسماً + المحفظة موجودة! + لا يمكن البدء ب. + جار إنشاء المحفظة + أنشأت المحفظة + + أدخل رقماً أو تاريخاً (سسسس-شش-يي) + + المفاتيح + جديد + بذرة + رؤية + + العنوان العام + مفتاح الرؤية + مفاح الإنفاق + بذرة الذاكرة ذات 25 كلمة + استرجع الارتفاع أو التاريخ (سسسس-شش-يي) + + العنوان العام + مفتاح الرؤية + مفتاح الإنفاق + بذرة الذاكرة + ملفات المحفظة استرجع كلمة المرور + + أدخل مفتاحاً صحيحاً + أدخل عنواناً صحيحاً + أدخل بذرتك ذات 25 كلمة + + الملاحظات الخاصة (اختياري) + ولد + أنفق مونيرواتي الحبيبة + أرسل مونيرواتي الحبيبة (%1$s) + ليس رمز استجابة سريعة (QR) + ليس رمزاً حصيحاً + ليس عنواناً صحيحاً + عنوان OpenAlias ليس متوفر + آمن ✔ + حل OpenAlias… + OpenAlias دون DNSSEC - قد يكون العنوان منتحل + أرسل + الرصيد: %1$s XMR + العنوان + المبلغ + أكد + تم + + المبلغ + الرسوم (xmr) + الرسوم + المجموع (xmr) + المجموع + + %1$s XMR + +%1$s رسوم + + عطل إنشاء المعاملة + + - رسوم %1$s + (%1$s) + فشل + - %1$s + + %1$s + + الختم الزمني + TX ID + TX Key + الوجهة + الوجهة\n(BTC) + معرف الدفع + الكتلة + المبلغ + المبلغ\n(BTC) + الرسوم + التحويلات + ملاحظات + (اختياري) + تفاصيل المعاملة + + معلقة + فشلت + + المبلغ + وصف (اختياري) + لم يتمكن من فتح المحفظة! + + %1$s أقصى + 0 أدنى + XMR ليس رقماً + + ستظهر بيانات حساسة.\nتفحص خلف ظهرك! + أنا في أمان + أرجعني! + التفاصيل + + ستحذف المحفظة بعد القيام بنسخة إحتياطية! + نعم، افعل ذلك! + لا شكراً! + + أنشئ محفظة جديدة + استرجع محفظة رؤية-فقط + استرجع محفظة من المفاتيح الخاصة + استرجع محفظة من بذرة 25 كلمة + + أنشئ حساباً + أضيف حساب جديد #%1$d + الحساب # + + أرسل كل المال المؤكد في هذا الحساب! + العنوان الفرعي #%1$d + العنوان الفرعي العام #%1$d + + اللغة + استخدم لغة النظام + + استرجع من لدجر نانو اس + + جار التواصل مع اللدجر + التأكيد على اللدجر مطلوب! + استلام العناوين الفرعية + التأكد من صحة المفاتيح + القيام بحسابات مجنونة + تشفير الأشياء + رجاءً (إعادة) إيصال جهاز لدجر + + جار إنشاء الحساب + + %1$s اربط + %1$s فصل + + جار كتابة العلامة + فشلت كتابة العلامة + نجحت كتابة العلامة + العلامة لا تدعم NDEF! + العلامة تزود %1$dلأ بايتاً، لكننا نحتاج %2$ل! + لا أفهم العلامة! + لا أعرف ماذا تريد! + NFC متوفر! + + أظهر أسراري! + وضع الشارع + + Node-o-matiC مفعل، المس لمعلومات أكثر. + آخر كتلة تحدثت: %1$s + العقد + اسم العقدة (اختياري) + اسم المضيف + المنفظ + اسم المستخدم (اختياري) + كلمة المرور (اختياري) + لا يمكن حل المضيف + نحتاج لهذا! + يجب أن يكون رقماً + 1–65535 يجب أن يكون + أضف عقدة + المس لإعادة التحميل + %1$d عطل إطصال + عطل في الاتصال + فشل التوثيق + نتيجة الاختبار: + الارتفاع: %1$s (v%2$d), Ping: %3$.0fms, IP: %4$s + اختبار IP: %1$s … + رجاءً انتظر انتهاء المسح + المس لاختيار أو إضافة العقد + أضف العقد يدوياً أو اسحب للأسفل للمسح + جار مسح الشبكة… + علمت أفضل %1$d عقد تلقائياً + اختبر + + URI… جار حل معرف المصادر الموحد للدفع + لم نتمكن من حل معرف المصادر الموحد للدفع + ✔ حل معرف المصادر الموحد للدفع + المستلم + + Sideshift.ai غير متصل - حاول مجدداً لاحقاً + مبلغ BTC خارج الحدود + عنوان الدفع قديم أو غير صحيح + طلبات كثيرة جداً + + كل شيء! + + حول بذرة اللدجر + كلمات بذرة اللدجر + عبارة دخول اللدجر (متقدم) + بذرة اللدجر غير صحيحة! + إدخال بذرة اللدجر هنا خطر أمني كبير! + + استرجع الارتفاع + + ابدأ تطبيق مونيرو في %1$s + + أعد المسح! + + فهمت! + التالي + أنا جاهز! + + مرحباً بك في مونيرويو! + هذا التطبيق يسمح لك بإنشاء و استخدام محافظ مونيرو. يمكنك الاحتفاظ بالحبيب مونيرو فيهم. + أبق بذرتك آمنة + البذرة تمنح وصولاً كاملاً لمن يمتلكها.إذا ما أضعتها لا يمكننا مساعدتك في استرجاعها و ستخسر مونيرواتك الحبيبة. + أرسل بيتكوين + لدى مونيرويو دعم داخلي لSideshift.ai. فقط الصق أو امسح عنوان بيتكوين و سترسل بيتكون بانفاق مونيرو. + العقد، كما تشاء + العقد تصلك بشبكة مونيرو. اختر ما بين العقد العامة أو كن متمرداً سبرانياً و استخدم خاصتك. + أرسل بالبصمة + يمكنك الآن إرسال XMR فقط ببصمتك إذا فعلتها. لطلب كلمة المرور، فقط عطل الدخول بالبصمة. + + الوضع الليلي + + تلقائي + يوم + ليل + + لا شيء هنا\nالرجاء إنشاء أو استعادة محفظة + + أرجع العقد الافتراضية + الاسترجاع يتقدم بالفعل... + + الكتلة الأخيرة: منذ %1$d ثوان + الكتلة الخيرة: منذ %1$d ساعة + الكتلة الأخيرة: منذ %1$d ساعة + الكتلة الأخيرة: منذ %1$d أيام + + لا يمكن الحصول على سعر + تأكد من البلغ و حاول مجدداً + عنوان مبهم.
    + رجاء حدد النوع أعلاه. + ]]>
    + + رجاء أدخل أو امسح عنوان %1$s
    + سترسل XMR و سيتلقى المستلم %2$s باستعمال خدمة SideShift.ai + ]]>
    + + رجاء أدخل أو امسح عنوان مونيرو + ]]> + + العناوين الفرعية + اسم العنوان الفرعي + عناوين غير مستعملة كثيرة - استعمل بعضها لتتمكن من إنشاء المزيد! + حسابات غير مستعملة كثيرة - استعمل بعضها لتتمكن من إنشاء المزيد! + المعاملات لهذا العنوان الفرعي: + لا معاملات لهذا العنوان الفرعي بعد + اختر عنواناً فرعياً + المس طويلاً للتفاصيل + + استورد محفظة + فشل الاستيراد + + أعد ضبط المحفظة! + ستتم إعادة ضبط هذه المحفظة ، وفقدان جميع البيانات خارج السلسلة (مثل الملاحظات ، وأسماء الحسابات والعناوين الفرعية ، ومفاتيح المعاملات الخاصة ، ...)! استخدم هذا فقط إذا كانت هذه المحفظة تالفة و لا تحمل! +
    From 303b3aa354a993fa05f73850176023b305288c21 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sat, 7 Aug 2021 11:58:54 +0200 Subject: [PATCH 09/15] dont update on every single block (#776) --- .../xmrwallet/service/WalletService.java | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java index b048755..876c944 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java @@ -108,28 +108,33 @@ public class WalletService extends Service { Timber.d("unconfirmedMoneyReceived() %d @ %s", amount, txId); } - int lastTxCount = 0; + private long lastBlockTime = 0; + private int lastTxCount = 0; public void newBlock(long height) { final Wallet wallet = getWallet(); if (wallet == null) throw new IllegalStateException("No wallet!"); - Timber.d("newBlock() @ %d with observer %s", height, observer); - if (observer != null) { - boolean fullRefresh = false; - updateDaemonState(wallet, wallet.isSynchronized() ? height : 0); - if (!wallet.isSynchronized()) { - updated = true; - // we want to see our transactions as they come in - wallet.getHistory().refresh(); - int txCount = wallet.getHistory().getCount(); - if (txCount > lastTxCount) { - // update the transaction list only if we have more than before - lastTxCount = txCount; - fullRefresh = true; + // don't flood with an update for every block ... + if (lastBlockTime < System.currentTimeMillis() - 2000) { + lastBlockTime = System.currentTimeMillis(); + Timber.d("newBlock() @ %d with observer %s", height, observer); + if (observer != null) { + boolean fullRefresh = false; + updateDaemonState(wallet, wallet.isSynchronized() ? height : 0); + if (!wallet.isSynchronized()) { + updated = true; + // we want to see our transactions as they come in + wallet.getHistory().refresh(); + int txCount = wallet.getHistory().getCount(); + if (txCount > lastTxCount) { + // update the transaction list only if we have more than before + lastTxCount = txCount; + fullRefresh = true; + } } + if (observer != null) + observer.onRefreshed(wallet, fullRefresh); } - if (observer != null) - observer.onRefreshed(wallet, fullRefresh); } } From 9ed92e51175338d958e910d600a34f0a0178d483 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sat, 7 Aug 2021 12:31:08 +0200 Subject: [PATCH 10/15] remove defunct strings in arabic --- app/src/main/res/values-ar/strings.xml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index f40beaf..6952765 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -9,7 +9,6 @@ ساعدني استلم أعد التسمية … - أرشف انشئ نسخة احتياطية غير كلمة المرور @@ -53,9 +52,6 @@ يمكنك إرسال %1$s — %2$s BTC.
    Sideshift.ai يعطيك سعر صرف %3$s BTC حالياً. ]]>
    - مبالغ حتى %1$s BTC سترسل فوراً! - ]]> الرصيد: %2$s BTC (%1$s XMR) @@ -97,7 +93,6 @@ نجح النسخ الاحتياطي فشل النسخ الاحتياطي! - فشلت الأرشفة! فشلت إعادة التسمية! فشل تغيير كلمة السر! تم تغيير كلمة السر @@ -248,11 +243,9 @@ TX ID TX Key الوجهة - الوجهة\n(BTC) معرف الدفع الكتلة المبلغ - المبلغ\n(BTC) الرسوم التحويلات ملاحظات @@ -275,10 +268,6 @@ أرجعني! التفاصيل - ستحذف المحفظة بعد القيام بنسخة إحتياطية! - نعم، افعل ذلك! - لا شكراً! - أنشئ محفظة جديدة استرجع محفظة رؤية-فقط استرجع محفظة من المفاتيح الخاصة @@ -349,16 +338,8 @@ علمت أفضل %1$d عقد تلقائياً اختبر - URI… جار حل معرف المصادر الموحد للدفع - لم نتمكن من حل معرف المصادر الموحد للدفع - ✔ حل معرف المصادر الموحد للدفع المستلم - Sideshift.ai غير متصل - حاول مجدداً لاحقاً - مبلغ BTC خارج الحدود - عنوان الدفع قديم أو غير صحيح - طلبات كثيرة جداً - كل شيء! حول بذرة اللدجر From e82b471c149084043ecd637bc5bbe1e1bd164d58 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Sep 2021 21:23:12 +0200 Subject: [PATCH 11/15] adaptaions for monero v0.17.2.3 (#781) --- app/CMakeLists.txt | 5 ++++ build.gradle | 2 +- external-libs/VERSION | 2 +- external-libs/include/wallet2_api.h | 36 ++++++++++++++++++++++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 80e07f7..a8b93d3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -171,6 +171,10 @@ add_library(wallet-crypto STATIC IMPORTED) set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION ${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet-crypto.a) +add_library(cryptonote_format_utils_basic STATIC IMPORTED) +set_target_properties(cryptonote_format_utils_basic PROPERTIES IMPORTED_LOCATION + ${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_format_utils_basic.a) + ############# # System ############# @@ -193,6 +197,7 @@ target_link_libraries( monerujo wallet cryptonote_core cryptonote_basic + cryptonote_format_utils_basic mnemonics ringct ringct_basic diff --git a/build.gradle b/build.gradle index 4406443..322ebf1 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.0.2' } } diff --git a/external-libs/VERSION b/external-libs/VERSION index 8823154..4aebddc 100644 --- a/external-libs/VERSION +++ b/external-libs/VERSION @@ -1 +1 @@ -MONERUJO_monero master with monero release-v0.17.2.0-monerujo +MONERUJO_monero feature_v17.2.3 with monero release-v0.17.2.3-monerujo diff --git a/external-libs/include/wallet2_api.h b/external-libs/include/wallet2_api.h index 999823f..0b8be83 100644 --- a/external-libs/include/wallet2_api.h +++ b/external-libs/include/wallet2_api.h @@ -182,9 +182,11 @@ struct TransactionInfo virtual int direction() const = 0; virtual bool isPending() const = 0; virtual bool isFailed() const = 0; + virtual bool isCoinbase() const = 0; virtual uint64_t amount() const = 0; virtual uint64_t fee() const = 0; virtual uint64_t blockHeight() const = 0; + virtual std::string description() const = 0; virtual std::set subaddrIndex() const = 0; virtual uint32_t subaddrAccount() const = 0; virtual std::string label() const = 0; @@ -208,6 +210,7 @@ struct TransactionHistory virtual TransactionInfo * transaction(const std::string &id) const = 0; virtual std::vector getAll() const = 0; virtual void refresh() = 0; + virtual void setTxNote(const std::string &txid, const std::string ¬e) = 0; }; /** @@ -250,6 +253,7 @@ struct AddressBook virtual std::vector getAll() const = 0; virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0; virtual bool deleteRow(std::size_t rowId) = 0; + virtual bool setDescription(std::size_t index, const std::string &description) = 0; virtual void refresh() = 0; virtual std::string errorString() const = 0; virtual int errorCode() const = 0; @@ -442,7 +446,7 @@ struct Wallet }; virtual ~Wallet() = 0; - virtual std::string seed() const = 0; + virtual std::string seed(const std::string& seed_offset = "") const = 0; virtual std::string getSeedLanguage() const = 0; virtual void setSeedLanguage(const std::string &arg) = 0; //! returns wallet status (Status_Ok | Status_Error) @@ -452,6 +456,7 @@ struct Wallet //! returns both error and error string atomically. suggested to use in instead of status() and errorString() virtual void statusWithErrorString(int& status, std::string& errorString) const = 0; virtual bool setPassword(const std::string &password) = 0; + virtual const std::string& getPassword() const = 0; virtual bool setDevicePin(const std::string &pin) { (void)pin; return false; }; virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; }; virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0; @@ -622,6 +627,12 @@ struct Wallet */ virtual bool watchOnly() const = 0; + /** + * @brief isDeterministic - checks if wallet keys are deterministic + * @return - true if deterministic + */ + virtual bool isDeterministic() const = 0; + /** * @brief blockChainHeight - returns current blockchain height * @return @@ -897,9 +908,10 @@ struct Wallet /*! * \brief exportKeyImages - exports key images to file * \param filename + * \param all - export all key images or only those that have not yet been exported * \return - true on success */ - virtual bool exportKeyImages(const std::string &filename) = 0; + virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0; /*! * \brief importKeyImages - imports key images from file @@ -908,6 +920,19 @@ struct Wallet */ virtual bool importKeyImages(const std::string &filename) = 0; + /*! + * \brief importOutputs - exports outputs to file + * \param filename + * \return - true on success + */ + virtual bool exportOutputs(const std::string &filename, bool all = false) = 0; + + /*! + * \brief importOutputs - imports outputs from file + * \param filename + * \return - true on success + */ + virtual bool importOutputs(const std::string &filename) = 0; virtual TransactionHistory * history() = 0; virtual AddressBook * addressBook() = 0; @@ -995,6 +1020,7 @@ struct Wallet virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const = 0; virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector &unknown_parameters, std::string &error) = 0; + virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const = 0; virtual std::string getDefaultDataDir() const = 0; @@ -1003,6 +1029,12 @@ struct Wallet * \return true on success */ virtual bool rescanSpent() = 0; + + /* + * \brief setOffline - toggle set offline on/off + * \param offline - true/false + */ + virtual void setOffline(bool offline) = 0; //! blackballs a set of outputs virtual bool blackballOutputs(const std::vector &outputs, bool add) = 0; diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3c4101c..29e4134 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 148faa00e48eb21945c13138d87b0af52ac43844 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Sep 2021 21:24:53 +0200 Subject: [PATCH 12/15] minor fixes for confirmations indicator (#782) --- .../xmrwallet/layout/TransactionInfoAdapter.java | 10 ++++------ .../com/m2049r/xmrwallet/model/TransactionInfo.java | 6 ++++++ app/src/main/res/layout/item_transaction.xml | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java index 835c3a1..da21880 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java @@ -49,8 +49,6 @@ import java.util.TimeZone; import timber.log.Timber; public class TransactionInfoAdapter extends RecyclerView.Adapter { - private final static int MAX_CONFIRMATIONS = 10; - private final static SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm"); private final int outboundColour; @@ -81,7 +79,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter 0) && (infoItems.get(0).confirmations < MAX_CONFIRMATIONS); + return (infoItems.size() > 0) && !infoItems.get(0).isConfirmed(); } private static class TransactionInfoDiff extends DiffCallback { @@ -169,7 +167,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter { + public static final int CONFIRMATION = 10; // blocks + @RequiredArgsConstructor public enum Direction { Direction_In(0), @@ -98,6 +100,10 @@ public class TransactionInfo implements Parcelable, Comparable this.transfers = transfers; } + public boolean isConfirmed() { + return confirmations >= CONFIRMATION; + } + public String getDisplayLabel() { if (subaddressLabel.isEmpty() || (Subaddress.DEFAULT_LABEL_FORMATTER.matcher(subaddressLabel).matches())) return ("#" + addressIndex); diff --git a/app/src/main/res/layout/item_transaction.xml b/app/src/main/res/layout/item_transaction.xml index c9e55d7..e210701 100644 --- a/app/src/main/res/layout/item_transaction.xml +++ b/app/src/main/res/layout/item_transaction.xml @@ -48,7 +48,7 @@ Date: Sun, 5 Sep 2021 21:42:55 +0200 Subject: [PATCH 13/15] bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9a8a6f4..0117341 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1008 - versionName "2.0.8 'Puginarug'" + versionCode 1100 + versionName "2.1.0 'Vertant'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { From 84ec1ef418e4c2f852e01a792579c2f97133e738 Mon Sep 17 00:00:00 2001 From: m2049r Date: Wed, 8 Sep 2021 13:52:23 +0200 Subject: [PATCH 14/15] load notes on refresh (#783) --- .../com/m2049r/xmrwallet/WalletFragment.java | 4 ++-- .../xmrwallet/layout/TransactionInfoAdapter.java | 2 +- .../xmrwallet/model/TransactionHistory.java | 16 ++++------------ .../java/com/m2049r/xmrwallet/model/Wallet.java | 6 +++++- .../m2049r/xmrwallet/service/WalletService.java | 4 ++-- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java index c1e53cd..35a9398 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java @@ -349,14 +349,14 @@ public class WalletFragment extends Fragment Timber.d("onRefreshed(%b)", full); if (adapter.needsTransactionUpdateOnNewBlock()) { - wallet.getHistory().refresh(); + wallet.refreshHistory(); full = true; } if (full) { List list = new ArrayList<>(); final long streetHeight = activityCallback.getStreetModeHeight(); Timber.d("StreetHeight=%d", streetHeight); - wallet.getHistory().refresh(); + wallet.refreshHistory(); for (TransactionInfo info : wallet.getHistory().getAll()) { Timber.d("TxHeight=%d, Label=%s", info.blockheight, info.subaddressLabel); if ((info.isPending || (info.blockheight >= streetHeight)) diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java index da21880..f7c4f93 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java @@ -100,7 +100,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter transactions = new ArrayList<>(); - public void refreshWithNotes(Wallet wallet) { + void refreshWithNotes(Wallet wallet) { refresh(); loadNotes(wallet); } -// public void refresh() { -// transactions = refreshJ(); -// } - - public void refresh() { + private void refresh() { List transactionInfos = refreshJ(); - Timber.d("refreshed %d", transactionInfos.size()); + Timber.d("refresh size=%d", transactionInfos.size()); for (Iterator iterator = transactionInfos.iterator(); iterator.hasNext(); ) { TransactionInfo info = iterator.next(); if (info.accountIndex != accountIndex) { iterator.remove(); - Timber.d("removed %s", info.hash); - } else { - Timber.d("kept %s", info.hash); } } transactions = transactionInfos; } private native List refreshJ(); - } diff --git a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java index 6653418..47df8e0 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java +++ b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java @@ -398,6 +398,10 @@ public class Wallet { private native long getHistoryJ(); + public void refreshHistory() { + getHistory().refreshWithNotes(this); + } + //virtual AddressBook * addressBook() const = 0; //virtual void setListener(WalletListener *) = 0; @@ -462,7 +466,7 @@ public class Wallet { public void setSubaddressLabel(int addressIndex, String label) { setSubaddressLabel(accountIndex, addressIndex, label); - getHistory().refreshWithNotes(this); + refreshHistory(); } public native void setSubaddressLabel(int accountIndex, int addressIndex, String label); diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java index 876c944..65bf9ef 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java @@ -124,7 +124,7 @@ public class WalletService extends Service { if (!wallet.isSynchronized()) { updated = true; // we want to see our transactions as they come in - wallet.getHistory().refresh(); + wallet.refreshHistory(); int txCount = wallet.getHistory().getCount(); if (txCount > lastTxCount) { // update the transaction list only if we have more than before @@ -152,7 +152,7 @@ public class WalletService extends Service { wallet.setSynchronized(); if (updated) { updateDaemonState(wallet, wallet.getBlockChainHeight()); - wallet.getHistory().refreshWithNotes(wallet); + wallet.refreshHistory(); if (observer != null) { updated = !observer.onRefreshed(wallet, true); } From ac70ba84248887853677cb958547ea23ddc1a054 Mon Sep 17 00:00:00 2001 From: m2049r Date: Wed, 8 Sep 2021 13:53:57 +0200 Subject: [PATCH 15/15] bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0117341..8d0a747 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1100 - versionName "2.1.0 'Vertant'" + versionCode 1101 + versionName "2.1.1 'Vertant'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake {