Compare commits
7 Commits
aeon-0.1.0
...
aeon-0.1.2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
67f24673b1 | ||
![]() |
1b9aac7526 | ||
![]() |
b68c425bae | ||
![]() |
cf58072c6c | ||
![]() |
6960347014 | ||
![]() |
cc5a8969d6 | ||
![]() |
c0ebf6c318 |
43
README.md
@@ -1,34 +1,24 @@
|
|||||||
# Monerujo
|
# MonerujoAE
|
||||||
Another Android Monero Wallet for Monero
|
The Android AEON Wallet
|
||||||
**(not
|
|
||||||
Monero Classic,
|
|
||||||
Monero-Classic,
|
|
||||||
Monero Zero,
|
|
||||||
Monero Original,
|
|
||||||
Monero C,
|
|
||||||
Monero V)**
|
|
||||||
|
|
||||||
### QUICKSTART
|
### QUICKSTART
|
||||||
- Download the APK for the most current release [here](https://github.com/monerujo-io/aeonwallet/releases) and install it
|
- Download the APK for the most current release [here](https://github.com/monerujo-io/aeonwallet/releases) and install it
|
||||||
- Alternatively add our F-Droid repo https://f-droid.monerujo.io/fdroid/repo with fingerpint ```A8 2C 68 E1 4A F0 AA 6A 2E C2 0E 6B 27 2E FF 25 E5 A0 38 F3 F6 58 84 31 6E 0F 5E 0D 91 E7 B7 13``` to your F-Droid client
|
- Alternatively add our F-Droid repo https://aeon.monerujo.io/fdroid/repo with fingerpint ```F8 20 2E E7 A8 D0 2D 07 AF B1 3D 5A 14 F2 9F 39 04 8C 4D 2D B3 87 76 11 03 5E F9 EA 20 6A 55 5D``` to your F-Droid client
|
||||||
- Run the App and select "Generate Wallet" to create a new wallet or recover a wallet
|
- Run the App and select "Generate Wallet" to create a new wallet or recover a wallet
|
||||||
- Advanced users can copy over synced wallet files (all files) onto sdcard in directory Monerujo (created first time App is started)
|
- Advanced users can copy over synced wallet files (all files) onto sdcard in directory ```aeonwallet``` (created first time App is started)
|
||||||
- See the [FAQ](doc/FAQ.md)
|
- See the [FAQ](doc/FAQ.md)
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
Help us translate Monerujo! You can find instructions [On Taiga](https://taiga.getmonero.org/project/erciccione-monero-localization/wiki/monerujo), and if you need help/support, open an issue or contact the Localization Workgroup. You can find us on the freenode channel `#monero-translations`, also relayed on [MatterMost](https://mattermost.getmonero.org/monero/channels/monero-translations), and matrix/riot.
|
Help us translate Monerujo! You can find instructions [On Taiga](https://taiga.getmonero.org/project/erciccione-monero-localization/wiki/monerujo), and if you need help/support, open an issue or contact the Localization Workgroup. You can find us on the freenode channel `#monero-translations`, also relayed on [MatterMost](https://mattermost.getmonero.org/monero/channels/monero-translations), and matrix/riot.
|
||||||
|
|
||||||
### Disclaimer
|
### Disclaimer
|
||||||
You may lose all your Moneroj if you use this App. Be cautious when spending on the mainnet.
|
You may lose all your AEON if you use this App.
|
||||||
|
|
||||||
### Random Notes
|
### Random Notes
|
||||||
- Based off monero v0.11.1.0
|
- Based off aeon v0.12.0
|
||||||
- currently only android32 (runs on 64-bit as well)
|
- works on the stagenet & mainnet
|
||||||
- works on the testnet & mainnet
|
|
||||||
- sync is slow due to 32-bit architecture
|
|
||||||
- use your own daemon - it's easy
|
- use your own daemon - it's easy
|
||||||
- screen stays on until first sync is complete
|
- screen stays on until first sync is complete
|
||||||
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
|
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- see taiga.getmonero.org & issues on github
|
- see taiga.getmonero.org & issues on github
|
||||||
@@ -36,23 +26,14 @@ You may lose all your Moneroj if you use this App. Be cautious when spending on
|
|||||||
### Issues / Pitfalls
|
### Issues / Pitfalls
|
||||||
- Users of Zenfone MAX & Zenfone 2 Laser (possibly others) **MUST** use the armeabi-v7a APK as the arm64-v8a build uses hardware AES
|
- Users of Zenfone MAX & Zenfone 2 Laser (possibly others) **MUST** use the armeabi-v7a APK as the arm64-v8a build uses hardware AES
|
||||||
functionality these models don't have.
|
functionality these models don't have.
|
||||||
- You should backup your wallet files in the "monerujo" folder periodically.
|
- You should backup your wallet files in the "aeonwallet" folder periodically.
|
||||||
- Also note, that on some devices the backups will only be visible on a PC over USB after a reboot of the device (it's an Android bug/feature)
|
- Also note, that on some devices the backups will only be visible on a PC over USB after a reboot of the device (it's an Android bug/feature)
|
||||||
- Created wallets on a private testnet are unusable because the restore height is set to that
|
- Created wallets on a private testnet are unusable because the restore height is set to that
|
||||||
of the "real" testnet. After creating a new wallet, make a **new** one by recovering from the seed.
|
of the "real" stagenet. After creating a new wallet, make a **new** one by recovering from the seed.
|
||||||
The official monero client shows the same behaviour.
|
The official client shows the same behaviour.
|
||||||
|
|
||||||
### HOW TO BUILD
|
### HOW TO BUILD
|
||||||
No need to build. Binaries are included:
|
Check out [the instructions](doc/BUILDING-external-libs.md)
|
||||||
|
|
||||||
- openssl-1.0.2l
|
|
||||||
- monero-v0.12
|
|
||||||
- boost_1_58_0
|
|
||||||
|
|
||||||
If you want to build them yourself (recommended) check out [the instructions](doc/BUILDING-external-libs.md)
|
|
||||||
|
|
||||||
Then, fire up Android Studio and build the APK.
|
|
||||||
|
|
||||||
### Donations
|
### Donations
|
||||||
- Address: 4AdkPJoxn7JCvAby9szgnt93MSEwdnxdhaASxbTBm6x5dCwmsDep2UYN4FhStDn5i11nsJbpU7oj59ahg8gXb1Mg3viqCuk
|
- Address: WmsfCJfmd6QQ84Rfb2mD1y7ryBzvTiQ8MMngmgRjxDMCCkeuChA9B9ZRNZyQyjgH1zdQMBXeQB9vZhUwPHmLGhyo2nMoE2ARv
|
||||||
- Viewkey: b1aff2a12191723da0afbe75516f94dd8b068215f6e847d8da57aca5f1f98e0c
|
|
||||||
|
@@ -7,8 +7,8 @@ android {
|
|||||||
applicationId "com.m2049r.aeonwallet"
|
applicationId "com.m2049r.aeonwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 10
|
versionCode 12
|
||||||
versionName "0.1.0 'Rebase ALPHA'"
|
versionName "0.1.2 'Rebase RC2'"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 67 KiB |
@@ -494,11 +494,11 @@ public class LoginActivity extends SecureActivity
|
|||||||
break;
|
break;
|
||||||
case NetworkType_Testnet:
|
case NetworkType_Testnet:
|
||||||
toolbar.setSubtitle(getString(R.string.connect_testnet));
|
toolbar.setSubtitle(getString(R.string.connect_testnet));
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
toolbar.setBackgroundResource(R.color.give);
|
||||||
break;
|
break;
|
||||||
case NetworkType_Stagenet:
|
case NetworkType_Stagenet:
|
||||||
toolbar.setSubtitle(getString(R.string.connect_stagenet));
|
toolbar.setSubtitle(getString(R.string.connect_stagenet));
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
toolbar.setBackgroundResource(R.color.give);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("NetworkType unknown: " + WalletManager.getInstance().getNetworkType());
|
throw new IllegalStateException("NetworkType unknown: " + WalletManager.getInstance().getNetworkType());
|
||||||
|
@@ -270,10 +270,10 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|||||||
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
||||||
break;
|
break;
|
||||||
case NetworkType_Testnet:
|
case NetworkType_Testnet:
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
toolbar.setBackgroundResource(R.color.give);
|
||||||
break;
|
break;
|
||||||
case NetworkType_Stagenet:
|
case NetworkType_Stagenet:
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
toolbar.setBackgroundResource(R.color.give);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
|
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
|
||||||
|
@@ -43,9 +43,7 @@ import com.m2049r.aeonwallet.model.Wallet;
|
|||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
||||||
import com.m2049r.aeonwallet.service.exchange.kraken.ExchangeApiImpl;
|
|
||||||
import com.m2049r.aeonwallet.util.Helper;
|
import com.m2049r.aeonwallet.util.Helper;
|
||||||
import com.m2049r.aeonwallet.util.OkHttpClientSingleton;
|
|
||||||
import com.m2049r.aeonwallet.widget.Toolbar;
|
import com.m2049r.aeonwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
@@ -101,7 +99,9 @@ public class WalletFragment extends Fragment
|
|||||||
ivSynced = (ImageView) view.findViewById(R.id.ivSynced);
|
ivSynced = (ImageView) view.findViewById(R.id.ivSynced);
|
||||||
|
|
||||||
sCurrency = (Spinner) view.findViewById(R.id.sCurrency);
|
sCurrency = (Spinner) view.findViewById(R.id.sCurrency);
|
||||||
sCurrency.setAdapter(ArrayAdapter.createFromResource(getContext(), R.array.currency, R.layout.item_spinner_balance));
|
ArrayAdapter currencyAdapter = ArrayAdapter.createFromResource(getContext(), R.array.currency, R.layout.item_spinner_balance);
|
||||||
|
currencyAdapter.setDropDownViewResource(R.layout.item_spinner_dropdown_item);
|
||||||
|
sCurrency.setAdapter(currencyAdapter);
|
||||||
|
|
||||||
bSend = (Button) view.findViewById(R.id.bSend);
|
bSend = (Button) view.findViewById(R.id.bSend);
|
||||||
bReceive = (Button) view.findViewById(R.id.bReceive);
|
bReceive = (Button) view.findViewById(R.id.bReceive);
|
||||||
@@ -150,7 +150,7 @@ public class WalletFragment extends Fragment
|
|||||||
// at this point selection is XMR in case of error
|
// at this point selection is XMR in case of error
|
||||||
String displayB;
|
String displayB;
|
||||||
double amountA = Double.parseDouble(Wallet.getDisplayAmount(unlockedBalance)); // crash if this fails!
|
double amountA = Double.parseDouble(Wallet.getDisplayAmount(unlockedBalance)); // crash if this fails!
|
||||||
if (!"XMR".equals(balanceCurrency)) { // not XMR
|
if (!Helper.CRYPTO.equals(balanceCurrency)) { // not XMR
|
||||||
double amountB = amountA * balanceRate;
|
double amountB = amountA * balanceRate;
|
||||||
displayB = Helper.getFormattedAmount(amountB, false);
|
displayB = Helper.getFormattedAmount(amountB, false);
|
||||||
} else { // XMR
|
} else { // XMR
|
||||||
@@ -159,10 +159,10 @@ public class WalletFragment extends Fragment
|
|||||||
tvBalance.setText(displayB);
|
tvBalance.setText(displayB);
|
||||||
}
|
}
|
||||||
|
|
||||||
String balanceCurrency = "XMR";
|
String balanceCurrency = Helper.CRYPTO;
|
||||||
double balanceRate = 1.0;
|
double balanceRate = 1.0;
|
||||||
|
|
||||||
private final ExchangeApi exchangeApi = new ExchangeApiImpl(OkHttpClientSingleton.getOkHttpClient());
|
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
|
||||||
|
|
||||||
void refreshBalance() {
|
void refreshBalance() {
|
||||||
if (sCurrency.getSelectedItemPosition() == 0) { // XMR
|
if (sCurrency.getSelectedItemPosition() == 0) { // XMR
|
||||||
@@ -170,9 +170,10 @@ public class WalletFragment extends Fragment
|
|||||||
tvBalance.setText(Helper.getFormattedAmount(amountXmr, true));
|
tvBalance.setText(Helper.getFormattedAmount(amountXmr, true));
|
||||||
} else { // not XMR
|
} else { // not XMR
|
||||||
String currency = (String) sCurrency.getSelectedItem();
|
String currency = (String) sCurrency.getSelectedItem();
|
||||||
|
Timber.d(currency);
|
||||||
if (!currency.equals(balanceCurrency) || (balanceRate <= 0)) {
|
if (!currency.equals(balanceCurrency) || (balanceRate <= 0)) {
|
||||||
showExchanging();
|
showExchanging();
|
||||||
exchangeApi.queryExchangeRate("XMR", currency,
|
exchangeApi.queryExchangeRate(Helper.CRYPTO, currency,
|
||||||
new ExchangeCallback() {
|
new ExchangeCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final ExchangeRate exchangeRate) {
|
public void onSuccess(final ExchangeRate exchangeRate) {
|
||||||
@@ -228,10 +229,10 @@ public class WalletFragment extends Fragment
|
|||||||
|
|
||||||
public void exchange(final ExchangeRate exchangeRate) {
|
public void exchange(final ExchangeRate exchangeRate) {
|
||||||
hideExchanging();
|
hideExchanging();
|
||||||
if (!"XMR".equals(exchangeRate.getBaseCurrency())) {
|
if (!Helper.CRYPTO.equals(exchangeRate.getBaseCurrency())) {
|
||||||
Timber.e("Not XMR");
|
Timber.e("Not XMR");
|
||||||
sCurrency.setSelection(0, true);
|
sCurrency.setSelection(0, true);
|
||||||
balanceCurrency = "XMR";
|
balanceCurrency = Helper.CRYPTO;
|
||||||
balanceRate = 1.0;
|
balanceRate = 1.0;
|
||||||
} else {
|
} else {
|
||||||
int spinnerPosition = ((ArrayAdapter) sCurrency.getAdapter()).getPosition(exchangeRate.getQuoteCurrency());
|
int spinnerPosition = ((ArrayAdapter) sCurrency.getAdapter()).getPosition(exchangeRate.getQuoteCurrency());
|
||||||
|
@@ -96,10 +96,6 @@ public class SendFragment extends Fragment
|
|||||||
|
|
||||||
private Button bDone;
|
private Button bDone;
|
||||||
|
|
||||||
private View llXmrToEnabled;
|
|
||||||
private View ibXmrToInfoClose;
|
|
||||||
|
|
||||||
|
|
||||||
static private int MAX_FALLBACK = Integer.MAX_VALUE;
|
static private int MAX_FALLBACK = Integer.MAX_VALUE;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -510,22 +506,4 @@ public class SendFragment extends Fragment
|
|||||||
inflater.inflate(R.menu.send_menu, menu);
|
inflater.inflate(R.menu.send_menu, menu);
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
// xmr.to info box
|
|
||||||
private static final String PREF_SHOW_XMRTO_ENABLED = "info_xmrto_enabled_send";
|
|
||||||
|
|
||||||
boolean showXmrtoEnabled = true;
|
|
||||||
|
|
||||||
void loadPrefs() {
|
|
||||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
|
||||||
showXmrtoEnabled = sharedPref.getBoolean(PREF_SHOW_XMRTO_ENABLED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveXmrToPrefs() {
|
|
||||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
|
||||||
SharedPreferences.Editor editor = sharedPref.edit();
|
|
||||||
editor.putBoolean(PREF_SHOW_XMRTO_ENABLED, showXmrtoEnabled);
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -103,7 +103,6 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||||
final ImageView ivTxType;
|
|
||||||
final TextView tvAmount;
|
final TextView tvAmount;
|
||||||
final TextView tvFee;
|
final TextView tvFee;
|
||||||
final TextView tvPaymentId;
|
final TextView tvPaymentId;
|
||||||
@@ -112,7 +111,6 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
|
|
||||||
ViewHolder(View itemView) {
|
ViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
ivTxType = (ImageView) itemView.findViewById(R.id.ivTxType);
|
|
||||||
tvAmount = (TextView) itemView.findViewById(R.id.tx_amount);
|
tvAmount = (TextView) itemView.findViewById(R.id.tx_amount);
|
||||||
tvFee = (TextView) itemView.findViewById(R.id.tx_fee);
|
tvFee = (TextView) itemView.findViewById(R.id.tx_fee);
|
||||||
tvPaymentId = (TextView) itemView.findViewById(R.id.tx_paymentid);
|
tvPaymentId = (TextView) itemView.findViewById(R.id.tx_paymentid);
|
||||||
@@ -131,11 +129,6 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
this.infoItem = infoItems.get(position);
|
this.infoItem = infoItems.get(position);
|
||||||
|
|
||||||
UserNotes userNotes = new UserNotes(infoItem.notes);
|
UserNotes userNotes = new UserNotes(infoItem.notes);
|
||||||
if (userNotes.xmrtoKey != null) {
|
|
||||||
ivTxType.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
ivTxType.setVisibility(View.GONE); // gives us more space for the amount
|
|
||||||
}
|
|
||||||
|
|
||||||
String displayAmount = Helper.getDisplayAmount(infoItem.amount, Helper.DISPLAY_DIGITS_INFO);
|
String displayAmount = Helper.getDisplayAmount(infoItem.amount, Helper.DISPLAY_DIGITS_INFO);
|
||||||
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {
|
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017 m2049r et al.
|
* Copyright (c) 2017-2018 m2049r et al.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.aeonwallet.service.exchange.kraken;
|
package com.m2049r.aeonwallet.service.exchange.coinmarketcap;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
@@ -23,6 +23,7 @@ import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
|||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeException;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeException;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
||||||
|
import com.m2049r.aeonwallet.util.Helper;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -37,6 +38,7 @@ import okhttp3.Request;
|
|||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
public class ExchangeApiImpl implements ExchangeApi {
|
public class ExchangeApiImpl implements ExchangeApi {
|
||||||
|
static final String CRYPTO_ID = "1026";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final OkHttpClient okHttpClient;
|
private final OkHttpClient okHttpClient;
|
||||||
@@ -52,7 +54,7 @@ public class ExchangeApiImpl implements ExchangeApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) {
|
public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) {
|
||||||
this(okHttpClient, HttpUrl.parse("https://api.kraken.com/0/public/Ticker"));
|
this(okHttpClient, HttpUrl.parse("https://api.coinmarketcap.com/v2/ticker/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,12 +69,12 @@ public class ExchangeApiImpl implements ExchangeApi {
|
|||||||
boolean inverse = false;
|
boolean inverse = false;
|
||||||
String fiat = null;
|
String fiat = null;
|
||||||
|
|
||||||
if (baseCurrency.equals("XMR")) {
|
if (baseCurrency.equals(Helper.CRYPTO)) {
|
||||||
fiat = quoteCurrency;
|
fiat = quoteCurrency;
|
||||||
inverse = false;
|
inverse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quoteCurrency.equals("XMR")) {
|
if (quoteCurrency.equals(Helper.CRYPTO)) {
|
||||||
fiat = baseCurrency;
|
fiat = baseCurrency;
|
||||||
inverse = true;
|
inverse = true;
|
||||||
}
|
}
|
||||||
@@ -85,7 +87,8 @@ public class ExchangeApiImpl implements ExchangeApi {
|
|||||||
final boolean swapAssets = inverse;
|
final boolean swapAssets = inverse;
|
||||||
|
|
||||||
final HttpUrl url = baseUrl.newBuilder()
|
final HttpUrl url = baseUrl.newBuilder()
|
||||||
.addQueryParameter("pair", "XMR" + fiat)
|
.addEncodedPathSegments(CRYPTO_ID + "/")
|
||||||
|
.addQueryParameter("convert", fiat)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final Request httpRequest = createHttpRequest(url);
|
final Request httpRequest = createHttpRequest(url);
|
||||||
@@ -101,12 +104,12 @@ public class ExchangeApiImpl implements ExchangeApi {
|
|||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
try {
|
try {
|
||||||
final JSONObject json = new JSONObject(response.body().string());
|
final JSONObject json = new JSONObject(response.body().string());
|
||||||
final JSONArray jsonError = json.getJSONArray("error");
|
final JSONObject metadata = json.getJSONObject("metadata");
|
||||||
if (jsonError.length() > 0) {
|
if (!metadata.isNull("error")) {
|
||||||
final String errorMsg = jsonError.getString(0);
|
final String errorMsg = metadata.getString("error");
|
||||||
callback.onError(new ExchangeException(response.code(), errorMsg));
|
callback.onError(new ExchangeException(response.code(), (String) errorMsg));
|
||||||
} else {
|
} else {
|
||||||
final JSONObject jsonResult = json.getJSONObject("result");
|
final JSONObject jsonResult = json.getJSONObject("data");
|
||||||
reportSuccess(jsonResult, swapAssets, callback);
|
reportSuccess(jsonResult, swapAssets, callback);
|
||||||
}
|
}
|
||||||
} catch (JSONException ex) {
|
} catch (JSONException ex) {
|
||||||
@@ -130,7 +133,6 @@ public class ExchangeApiImpl implements ExchangeApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Request createHttpRequest(final HttpUrl url) {
|
private Request createHttpRequest(final HttpUrl url) {
|
||||||
return new Request.Builder()
|
return new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017 m2049r et al.
|
* Copyright (c) 2017-2018 m2049r et al.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.m2049r.aeonwallet.service.exchange.kraken;
|
package com.m2049r.aeonwallet.service.exchange.coinmarketcap;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@@ -37,7 +38,7 @@ class ExchangeRateImpl implements ExchangeRate {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getServiceName() {
|
public String getServiceName() {
|
||||||
return "kraken.com";
|
return "coinmarketcap.com";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -64,29 +65,21 @@ class ExchangeRateImpl implements ExchangeRate {
|
|||||||
|
|
||||||
ExchangeRateImpl(final JSONObject jsonObject, final boolean swapAssets) throws JSONException, ExchangeException {
|
ExchangeRateImpl(final JSONObject jsonObject, final boolean swapAssets) throws JSONException, ExchangeException {
|
||||||
try {
|
try {
|
||||||
final String key = jsonObject.keys().next(); // we expect only one
|
final String baseC = jsonObject.getString("symbol");
|
||||||
Pattern pattern = Pattern.compile("^X(.*?)Z(.*?)$");
|
final JSONObject quotes = jsonObject.getJSONObject("quotes");
|
||||||
Matcher matcher = pattern.matcher(key);
|
final Iterator<String> keys = quotes.keys();
|
||||||
if (matcher.find()) {
|
String key = null;
|
||||||
this.baseCurrency = swapAssets ? matcher.group(2) : matcher.group(1);
|
// get key which is not USD unless it is the only one
|
||||||
this.quoteCurrency = swapAssets ? matcher.group(1) : matcher.group(2);
|
while (keys.hasNext()) {
|
||||||
} else {
|
key = keys.next();
|
||||||
throw new ExchangeException("no pair returned!");
|
if (!key.equals("USD")) break;
|
||||||
}
|
|
||||||
|
|
||||||
JSONObject pair = jsonObject.getJSONObject(key);
|
|
||||||
JSONArray close = pair.getJSONArray("c");
|
|
||||||
String closePrice = close.getString(0);
|
|
||||||
if (closePrice != null) {
|
|
||||||
try {
|
|
||||||
double rate = Double.parseDouble(closePrice);
|
|
||||||
this.rate = swapAssets ? (1 / rate) : rate;
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
throw new ExchangeException(ex.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new ExchangeException("no close price returned!");
|
|
||||||
}
|
}
|
||||||
|
final String quoteC = key;
|
||||||
|
baseCurrency = swapAssets ? quoteC : baseC;
|
||||||
|
quoteCurrency = swapAssets ? baseC : quoteC;
|
||||||
|
JSONObject quote = quotes.getJSONObject(key);
|
||||||
|
double price = quote.getDouble("price");
|
||||||
|
this.rate = swapAssets ? (1d / price) : price;
|
||||||
} catch (NoSuchElementException ex) {
|
} catch (NoSuchElementException ex) {
|
||||||
throw new ExchangeException(ex.getLocalizedMessage());
|
throw new ExchangeException(ex.getLocalizedMessage());
|
||||||
}
|
}
|
@@ -56,6 +56,7 @@ import com.m2049r.aeonwallet.R;
|
|||||||
import com.m2049r.aeonwallet.model.NetworkType;
|
import com.m2049r.aeonwallet.model.NetworkType;
|
||||||
import com.m2049r.aeonwallet.model.Wallet;
|
import com.m2049r.aeonwallet.model.Wallet;
|
||||||
import com.m2049r.aeonwallet.model.WalletManager;
|
import com.m2049r.aeonwallet.model.WalletManager;
|
||||||
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -72,6 +73,8 @@ import okhttp3.HttpUrl;
|
|||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class Helper {
|
public class Helper {
|
||||||
|
static public final String CRYPTO = "AEON";
|
||||||
|
|
||||||
static private final String WALLET_DIR = "aeonwallet" + (BuildConfig.DEBUG ? "-debug" : "");
|
static private final String WALLET_DIR = "aeonwallet" + (BuildConfig.DEBUG ? "-debug" : "");
|
||||||
static private final String HOME_DIR = "aeon" + (BuildConfig.DEBUG ? "-debug" : "");
|
static private final String HOME_DIR = "aeon" + (BuildConfig.DEBUG ? "-debug" : "");
|
||||||
|
|
||||||
@@ -285,15 +288,6 @@ public class Helper {
|
|||||||
return ShakeAnimation;
|
return ShakeAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public HttpUrl getXmrToBaseUrl() {
|
|
||||||
if ((WalletManager.getInstance() == null)
|
|
||||||
|| (WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet)) {
|
|
||||||
return HttpUrl.parse("https://test.xmr.to/api/v2/xmr2btc/");
|
|
||||||
} else {
|
|
||||||
return HttpUrl.parse("https://xmr.to/api/v2/xmr2btc/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static char[] HexArray = "0123456789ABCDEF".toCharArray();
|
private final static char[] HexArray = "0123456789ABCDEF".toCharArray();
|
||||||
|
|
||||||
public static String bytesToHex(byte[] data) {
|
public static String bytesToHex(byte[] data) {
|
||||||
@@ -341,13 +335,11 @@ public class Helper {
|
|||||||
// or the password used to derive the CrAzYpass for the wallet
|
// or the password used to derive the CrAzYpass for the wallet
|
||||||
static public String getWalletPassword(Context context, String walletName, String password) {
|
static public String getWalletPassword(Context context, String walletName, String password) {
|
||||||
String walletPath = new File(getWalletRoot(context), walletName + ".keys").getAbsolutePath();
|
String walletPath = new File(getWalletRoot(context), walletName + ".keys").getAbsolutePath();
|
||||||
Timber.e("A %s/%s/", walletPath, password);
|
|
||||||
|
|
||||||
// try with entered password (which could be a legacy password or a CrAzYpass)
|
// try with entered password (which could be a legacy password or a CrAzYpass)
|
||||||
if (WalletManager.getInstance().verifyWalletPassword(walletPath, password, true)) {
|
if (WalletManager.getInstance().verifyWalletPassword(walletPath, password, true)) {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
Timber.e("B");
|
|
||||||
|
|
||||||
// maybe this is a malformed CrAzYpass?
|
// maybe this is a malformed CrAzYpass?
|
||||||
String possibleCrazyPass = CrazyPassEncoder.reformat(password);
|
String possibleCrazyPass = CrazyPassEncoder.reformat(password);
|
||||||
@@ -356,15 +348,12 @@ public class Helper {
|
|||||||
return possibleCrazyPass;
|
return possibleCrazyPass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Timber.e("C");
|
|
||||||
|
|
||||||
// generate & try with CrAzYpass
|
// generate & try with CrAzYpass
|
||||||
String crazyPass = KeyStoreHelper.getCrazyPass(context, password);
|
String crazyPass = KeyStoreHelper.getCrazyPass(context, password);
|
||||||
Timber.e("D /%s/",crazyPass);
|
|
||||||
if (WalletManager.getInstance().verifyWalletPassword(walletPath, crazyPass, true)) {
|
if (WalletManager.getInstance().verifyWalletPassword(walletPath, crazyPass, true)) {
|
||||||
return crazyPass;
|
return crazyPass;
|
||||||
}
|
}
|
||||||
Timber.e("E");
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -516,4 +505,9 @@ public class Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public ExchangeApi getExchangeApi() {
|
||||||
|
return new com.m2049r.aeonwallet.service.exchange.coinmarketcap.ExchangeApiImpl(OkHttpClientSingleton.getOkHttpClient());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,8 +37,6 @@ public class Notice {
|
|||||||
private static final String PREFS_NAME = "notice";
|
private static final String PREFS_NAME = "notice";
|
||||||
private static List<Notice> notices = null;
|
private static List<Notice> notices = null;
|
||||||
|
|
||||||
private static final String NOTICE_SHOW_XMRTO_ENABLED_LOGIN = "notice_xmrto_enabled_login";
|
|
||||||
private static final String NOTICE_SHOW_XMRTO_ENABLED_SEND = "notice_xmrto_enabled_send";
|
|
||||||
private static final String NOTICE_SHOW_CRAZYPASS = "notice_crazypass_enabled_login";
|
private static final String NOTICE_SHOW_CRAZYPASS = "notice_crazypass_enabled_login";
|
||||||
|
|
||||||
private static void init() {
|
private static void init() {
|
||||||
|
@@ -22,25 +22,13 @@ import java.util.regex.Pattern;
|
|||||||
public class UserNotes {
|
public class UserNotes {
|
||||||
public String txNotes = "";
|
public String txNotes = "";
|
||||||
public String note = "";
|
public String note = "";
|
||||||
public String xmrtoKey = null;
|
|
||||||
public String xmrtoAmount = null; // could be a double - but we are not doing any calculations
|
|
||||||
public String xmrtoDestination = null;
|
|
||||||
|
|
||||||
public UserNotes(final String txNotes) {
|
public UserNotes(final String txNotes) {
|
||||||
if (txNotes == null) {
|
if (txNotes == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.txNotes = txNotes;
|
this.txNotes = txNotes;
|
||||||
Pattern p = Pattern.compile("^\\{(xmrto-\\w{6}),([0-9.]*)BTC,(\\w*)\\} ?(.*)");
|
note = txNotes;
|
||||||
Matcher m = p.matcher(txNotes);
|
|
||||||
if (m.find()) {
|
|
||||||
xmrtoKey = m.group(1);
|
|
||||||
xmrtoAmount = m.group(2);
|
|
||||||
xmrtoDestination = m.group(3);
|
|
||||||
note = m.group(4);
|
|
||||||
} else {
|
|
||||||
note = txNotes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNote(String newNote) {
|
public void setNote(String newNote) {
|
||||||
@@ -53,21 +41,6 @@ public class UserNotes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String buildTxNote() {
|
private String buildTxNote() {
|
||||||
StringBuffer sb = new StringBuffer();
|
return note;
|
||||||
if (xmrtoKey != null) {
|
|
||||||
if ((xmrtoAmount == null) || (xmrtoDestination == null))
|
|
||||||
throw new IllegalArgumentException("Broken notes");
|
|
||||||
sb.append("{");
|
|
||||||
sb.append(xmrtoKey);
|
|
||||||
sb.append(",");
|
|
||||||
sb.append(xmrtoAmount);
|
|
||||||
sb.append("BTC,");
|
|
||||||
sb.append(xmrtoDestination);
|
|
||||||
sb.append("}");
|
|
||||||
if ((note != null) && (!note.isEmpty()))
|
|
||||||
sb.append(" ");
|
|
||||||
}
|
|
||||||
sb.append(note);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -36,9 +36,7 @@ import com.m2049r.aeonwallet.model.Wallet;
|
|||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
||||||
import com.m2049r.aeonwallet.service.exchange.kraken.ExchangeApiImpl;
|
|
||||||
import com.m2049r.aeonwallet.util.Helper;
|
import com.m2049r.aeonwallet.util.Helper;
|
||||||
import com.m2049r.aeonwallet.util.OkHttpClientSingleton;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -250,7 +248,7 @@ public class ExchangeTextView extends LinearLayout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ExchangeApi exchangeApi = new ExchangeApiImpl(OkHttpClientSingleton.getOkHttpClient());
|
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
|
||||||
|
|
||||||
void startExchange() {
|
void startExchange() {
|
||||||
showProgress();
|
showProgress();
|
||||||
|
@@ -30,6 +30,7 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
@@ -41,9 +42,7 @@ import com.m2049r.aeonwallet.model.Wallet;
|
|||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
|
||||||
import com.m2049r.aeonwallet.service.exchange.kraken.ExchangeApiImpl;
|
|
||||||
import com.m2049r.aeonwallet.util.Helper;
|
import com.m2049r.aeonwallet.util.Helper;
|
||||||
import com.m2049r.aeonwallet.util.OkHttpClientSingleton;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -166,7 +165,11 @@ public class ExchangeView extends LinearLayout
|
|||||||
etAmount = (TextInputLayout) findViewById(R.id.etAmount);
|
etAmount = (TextInputLayout) findViewById(R.id.etAmount);
|
||||||
tvAmountB = (TextView) findViewById(R.id.tvAmountB);
|
tvAmountB = (TextView) findViewById(R.id.tvAmountB);
|
||||||
sCurrencyA = (Spinner) findViewById(R.id.sCurrencyA);
|
sCurrencyA = (Spinner) findViewById(R.id.sCurrencyA);
|
||||||
|
ArrayAdapter adapter = ArrayAdapter.createFromResource(getContext(), R.array.currency, R.layout.item_spinner);
|
||||||
|
adapter.setDropDownViewResource(R.layout.item_spinner_dropdown_item);
|
||||||
|
sCurrencyA.setAdapter(adapter);
|
||||||
sCurrencyB = (Spinner) findViewById(R.id.sCurrencyB);
|
sCurrencyB = (Spinner) findViewById(R.id.sCurrencyB);
|
||||||
|
sCurrencyB.setAdapter(adapter);
|
||||||
evExchange = (ImageView) findViewById(R.id.evExchange);
|
evExchange = (ImageView) findViewById(R.id.evExchange);
|
||||||
pbExchange = (ProgressBar) findViewById(R.id.pbExchange);
|
pbExchange = (ProgressBar) findViewById(R.id.pbExchange);
|
||||||
|
|
||||||
@@ -310,12 +313,13 @@ public class ExchangeView extends LinearLayout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ExchangeApi exchangeApi = new ExchangeApiImpl(OkHttpClientSingleton.getOkHttpClient());
|
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
|
||||||
|
|
||||||
void startExchange() {
|
void startExchange() {
|
||||||
showProgress();
|
showProgress();
|
||||||
String currencyA = (String) sCurrencyA.getSelectedItem();
|
String currencyA = (String) sCurrencyA.getSelectedItem();
|
||||||
String currencyB = (String) sCurrencyB.getSelectedItem();
|
String currencyB = (String) sCurrencyB.getSelectedItem();
|
||||||
|
|
||||||
exchangeApi.queryExchangeRate(currencyA, currencyB,
|
exchangeApi.queryExchangeRate(currencyA, currencyB,
|
||||||
new ExchangeCallback() {
|
new ExchangeCallback() {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 m2049r
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.m2049r.aeonwallet.widget;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.m2049r.aeonwallet.R;
|
|
||||||
|
|
||||||
public class SendProgressView extends LinearLayout {
|
|
||||||
|
|
||||||
public SendProgressView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
initializeViews(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SendProgressView(Context context,
|
|
||||||
AttributeSet attrs,
|
|
||||||
int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
initializeViews(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeViews(Context context) {
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context
|
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
inflater.inflate(R.layout.view_send_progress, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
View pbProgress;
|
|
||||||
View llMessage;
|
|
||||||
TextView tvCode;
|
|
||||||
TextView tvMessage;
|
|
||||||
TextView tvSolution;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onFinishInflate() {
|
|
||||||
super.onFinishInflate();
|
|
||||||
pbProgress = findViewById(R.id.pbProgress);
|
|
||||||
llMessage = findViewById(R.id.llMessage);
|
|
||||||
tvCode = (TextView) findViewById(R.id.tvCode);
|
|
||||||
tvMessage = (TextView) findViewById(R.id.tvMessage);
|
|
||||||
tvSolution = (TextView) findViewById(R.id.tvSolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showProgress(String progressText) {
|
|
||||||
pbProgress.setVisibility(VISIBLE);
|
|
||||||
tvCode.setVisibility(INVISIBLE);
|
|
||||||
tvMessage.setText(progressText);
|
|
||||||
llMessage.setVisibility(VISIBLE);
|
|
||||||
tvSolution.setVisibility(INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hideProgress() {
|
|
||||||
pbProgress.setVisibility(INVISIBLE);
|
|
||||||
llMessage.setVisibility(INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showMessage(String code, String message, String solution) {
|
|
||||||
tvCode.setText(code);
|
|
||||||
tvMessage.setText(message);
|
|
||||||
tvSolution.setText(solution);
|
|
||||||
tvCode.setVisibility(VISIBLE);
|
|
||||||
llMessage.setVisibility(VISIBLE);
|
|
||||||
tvSolution.setVisibility(VISIBLE);
|
|
||||||
pbProgress.setVisibility(INVISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -3,7 +3,7 @@
|
|||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
<gradient
|
<gradient
|
||||||
android:angle="45"
|
android:angle="45"
|
||||||
android:endColor="@color/gradientOrange"
|
android:endColor="@color/gradientPink"
|
||||||
android:startColor="@color/gradientPink"
|
android:startColor="@color/gradientOrange"
|
||||||
android:type="linear" />
|
android:type="linear" />
|
||||||
</shape>
|
</shape>
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
android:shape="oval">
|
android:shape="oval">
|
||||||
<gradient
|
<gradient
|
||||||
android:angle="45"
|
android:angle="45"
|
||||||
android:endColor="@color/gradientOrange"
|
android:endColor="@color/gradientPink"
|
||||||
android:startColor="@color/gradientPink"
|
android:startColor="@color/gradientOrange"
|
||||||
android:type="linear" />
|
android:type="linear" />
|
||||||
</shape>
|
</shape>
|
@@ -57,6 +57,7 @@
|
|||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:entries="@array/currency"
|
android:entries="@array/currency"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:minWidth="96dp"
|
||||||
android:paddingBottom="2dp"
|
android:paddingBottom="2dp"
|
||||||
android:paddingEnd="4dp"
|
android:paddingEnd="4dp"
|
||||||
android:paddingStart="4dp"
|
android:paddingStart="4dp"
|
||||||
|
11
app/src/main/res/layout/item_spinner.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@android:id/text1"
|
||||||
|
style="?android:attr/spinnerItemStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:gravity="center"
|
||||||
|
android:singleLine="true"
|
||||||
|
tools:text="AEON" />
|
11
app/src/main/res/layout/item_spinner_dropdown_item.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@android:id/text1"
|
||||||
|
style="?android:attr/spinnerDropDownItemStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:minWidth="72dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAlignment="center" />
|
@@ -20,38 +20,23 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_weight="9"
|
android:layout_weight="9"
|
||||||
android:orientation="horizontal">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<TextView
|
||||||
android:id="@+id/ivTxType"
|
android:id="@+id/tx_amount"
|
||||||
android:layout_width="16dp"
|
style="@style/MoneroText.PosAmount"
|
||||||
android:layout_height="16dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:src="@drawable/ic_xmrto_32dp"
|
|
||||||
android:visibility="visible" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:gravity="end"
|
||||||
android:orientation="vertical">
|
tools:text="+ 999.999999" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tx_amount"
|
android:id="@+id/tx_fee"
|
||||||
style="@style/MoneroText.PosAmount"
|
style="@style/MoneroText.PosFee"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
tools:text="+ 999.999999" />
|
tools:text="Fee 0.06817" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tx_fee"
|
|
||||||
style="@style/MoneroText.PosFee"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="end"
|
|
||||||
tools:text="Fee 0.06817" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
tools:showIn="LinearLayout"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
tools:showIn="LinearLayout">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -12,12 +12,12 @@
|
|||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
android:id="@+id/sCurrencyA"
|
android:id="@+id/sCurrencyA"
|
||||||
android:layout_width="64dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:entries="@array/currency"
|
android:entries="@array/currency"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textAlignment="center" />
|
android:minWidth="72dp" />
|
||||||
|
|
||||||
<com.m2049r.aeonwallet.widget.CTextInputLayout
|
<com.m2049r.aeonwallet.widget.CTextInputLayout
|
||||||
android:id="@+id/etAmount"
|
android:id="@+id/etAmount"
|
||||||
@@ -49,19 +49,18 @@
|
|||||||
<Spinner
|
<Spinner
|
||||||
android:id="@+id/sCurrencyB"
|
android:id="@+id/sCurrencyB"
|
||||||
style="@style/MoneroSpinnerGray"
|
style="@style/MoneroSpinnerGray"
|
||||||
android:layout_width="64sp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:entries="@array/currency"
|
android:entries="@array/currency"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingBottom="8dp"
|
android:minWidth="72dp"
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:textAlignment="center" />
|
android:textAlignment="center" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvAmountB"
|
android:id="@+id/tvAmountB"
|
||||||
style="@style/MoneroText"
|
style="@style/MoneroText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center|start"
|
android:layout_gravity="center|start"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
|
@@ -1,47 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:showIn="LinearLayout">
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/pbProgress"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:indeterminate="true"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/llMessage"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="visible">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvCode"
|
|
||||||
style="@style/MoneroText.Confirm.Label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
tools:text="XMRTO-ERROR-001" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvMessage"
|
|
||||||
style="@style/MoneroText.Confirm"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
tools:text="internal services not available" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvSolution"
|
|
||||||
style="@style/MoneroText.Confirm.Label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
tools:text="Touch to retry" />
|
|
||||||
</LinearLayout>
|
|
||||||
</merge>
|
|
||||||
|
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@@ -29,15 +29,10 @@
|
|||||||
von Transaktionen lokal gesammelt und verarbeitet und verschlüsselt in das Monero-Netzwerk übertragen.
|
von Transaktionen lokal gesammelt und verarbeitet und verschlüsselt in das Monero-Netzwerk übertragen.
|
||||||
</p>
|
</p>
|
||||||
<p>Andere persönliche Daten werden von der App nicht gesammelt.</p>
|
<p>Andere persönliche Daten werden von der App nicht gesammelt.</p>
|
||||||
<p>Wenn du den USD/EUR Umrechner (optional) nutzt fragt Monerujo
|
<p>Wenn du den Umrechner (optional) nutzt fragt Monerujo
|
||||||
den aktuellen Kurs über die öffentliche Schnittstelle von kraken.com ab.
|
den aktuellen Kurs über die öffentliche Schnittstelle von coinmarketcap.com ab.
|
||||||
Siehe dir ihre Datenschutzerklärung unter https://www.kraken.com/legal/privacy für
|
Siehe dir ihre Datenschutzerklärung unter https://coinmarketcap.com/privacy für
|
||||||
Details darüber an, wie Daten in deinen Anfragen gesammelt werden (insbesondere der
|
Details darüber an, wie Daten in deinen Anfragen gesammelt werden.</p>
|
||||||
Abschnitt "Information We Collect Automatically").</p>
|
|
||||||
<p>Wenn du die App zum Bezahlen an BTC-Adressen verwendest, verwendest du den Dienst XMR.TO.
|
|
||||||
Weitere Informationen findest du in den Datenschutzerklärung unter https://xmr.to/.
|
|
||||||
Monerujo schickt dem Anbieter die BTC Zieladresse und den Betrag.
|
|
||||||
Deine IP-Adresse kann dabei aufgezeichnet werden.</p>
|
|
||||||
<h2>App-Berechtigungen</h2>
|
<h2>App-Berechtigungen</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>INTERNET : Verbinde zum Monero Netzwerk über eine Monero Daemon Node</li>
|
<li>INTERNET : Verbinde zum Monero Netzwerk über eine Monero Daemon Node</li>
|
||||||
|
@@ -160,8 +160,6 @@
|
|||||||
<p>Dies ist die öffentliche Adresse des Wallets, an die du Moneroj sendest. Du kannst sie aus der Zwischenablage kopieren,
|
<p>Dies ist die öffentliche Adresse des Wallets, an die du Moneroj sendest. Du kannst sie aus der Zwischenablage kopieren,
|
||||||
einen QR-Code scannen oder sie manuell eingeben. Vergewissere dich, dass es die richtige Adresse ist um
|
einen QR-Code scannen oder sie manuell eingeben. Vergewissere dich, dass es die richtige Adresse ist um
|
||||||
sicherzustellen die Moneroj nicht irrtümlich an eine falsche Adresse zu senden.</p>
|
sicherzustellen die Moneroj nicht irrtümlich an eine falsche Adresse zu senden.</p>
|
||||||
<p>Zusätzlich zum Senden von XMR kannst du auch BTC mittels des XMR.TO Service versenden (siehe https://xmr.to
|
|
||||||
für Details). Siehe den Abschnitt über das Versenden von BTC unten.</p>
|
|
||||||
<h2>Zahlungs-ID</h2>
|
<h2>Zahlungs-ID</h2>
|
||||||
<p>Du kannst eine Zahlungs-ID benutzen um den Grund einer Transaktion zwischen zwei Parteien zu identifizieren. Dies ist optional
|
<p>Du kannst eine Zahlungs-ID benutzen um den Grund einer Transaktion zwischen zwei Parteien zu identifizieren. Dies ist optional
|
||||||
und nicht öffentlich einsehbar. Zum Beispiel kann ein Unternehmen damit Zahlungen und Verkäufe miteinander verbinden.<p>
|
und nicht öffentlich einsehbar. Zum Beispiel kann ein Unternehmen damit Zahlungen und Verkäufe miteinander verbinden.<p>
|
||||||
@@ -176,29 +174,6 @@
|
|||||||
niedrigere Transaktionsgebühr. Bitte bedenke, dass eine Transaktion mit einer niedrigen Priorität unter Umständen
|
niedrigere Transaktionsgebühr. Bitte bedenke, dass eine Transaktion mit einer niedrigen Priorität unter Umständen
|
||||||
eine Weile benötigt bis sie auf der Blockchain verarbeitet wird. Die Standard-Priorität
|
eine Weile benötigt bis sie auf der Blockchain verarbeitet wird. Die Standard-Priorität
|
||||||
ist \"Mittel\".</p>
|
ist \"Mittel\".</p>
|
||||||
<h1>BTC Senden</h1>
|
|
||||||
<h2>XMR.TO</h2>
|
|
||||||
<p>XMR.TO ist ein Drittanbieter-Service welcher als Wechselservice von Monero zu Bitcoin fungiert.
|
|
||||||
Wir nutzen die XMR.TO Schnittstelle um Bitcoin Zahlungen in Monerujo zu integrieren. Bitte schaue dir
|
|
||||||
https://xmr.to an und entscheide selbst, ob du diesen Service nutzen willst. Das Monerujo
|
|
||||||
Team gehört nicht zu XMR.TO und kann keinen Support für ihren Service bieten</p>
|
|
||||||
<h2>XMR.TO Wechselkurs<h2>
|
|
||||||
<p>Auf dem \"Menge\" Bildschirm siehst du die aktuellen Werte des XMR.TO Service. Diese beinhalten den aktuellen Tauschkurs
|
|
||||||
sowie die oberen und unteren BTC-Limits. Bitte bedenke, dass dieser Kurs zu diesem Zeitpunkt nicht garantiert ist.
|
|
||||||
Außerdem siehst du den Wert bis zu dem eine BTC-Zahlung sofort ausgeführt wird
|
|
||||||
ohne auf XMR-Bestätigungen warten zu müssen (siehe die XMR.TO FAQ für mehr Details).
|
|
||||||
XMR.TO erhebt keine zusätzlichen Gebühren - wie cool ist das denn?</p>
|
|
||||||
<h2>XMR.TO Auftrag<h2>
|
|
||||||
<p>Auf dem \"Bestätigen\" Bildschirm siehst du das genaue XMR.TO-Angebot. Dieses Angebot gilt
|
|
||||||
für eine bestimmte Zeit - du siehst einen Countdown auf dem \"Ausgeben\" Button. Der Wechselkurs kann
|
|
||||||
sich von den vorherigen Angaben unterscheiden.</p>
|
|
||||||
<h2>Geheimer XMR.TO Schlüssel<h2>
|
|
||||||
<p>Da Monerujo nur den Monero-Teil deiner Transaktion verarbeitet kann dein geheimer XMR.TO Schlüssel
|
|
||||||
dazu benutzt werden den Bitcoin-Teil deines Auftrags auf der XMR.TO-Homepage zu verfolgen.</p>
|
|
||||||
<p>Dieser geheime Schlüssel ist für 24h nach Start der Transaktion gültig!</p>
|
|
||||||
<h2>XMR.TO Countdown!</h2>
|
|
||||||
<p>Wenn der Countdown 0 erreicht musst du ein neues Angebot von XMR.TO anfordern indem du zum vorherigen Schritt
|
|
||||||
zurückkehrst und wieder zum \"Bestätigen\"-Bildschirm zurückkommst.</p>
|
|
||||||
]]></string>
|
]]></string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -29,11 +29,10 @@
|
|||||||
Monero de forma cifrada.
|
Monero de forma cifrada.
|
||||||
</p>
|
</p>
|
||||||
<p>Otros datos personales no son recopilados por la app.</p>
|
<p>Otros datos personales no son recopilados por la app.</p>
|
||||||
<p>Si utiliza la funcionalidad de cambio USD/EUR (opcional), monerujo obtiene la tasa
|
<p>Si utiliza la funcionalidad de cambio (opcional), monerujo obtiene la tasa
|
||||||
de cambio a través de la API pública de kraken.com.
|
de cambio a través de la API pública de coinmarketcap.com.
|
||||||
Vea su política de privadad en https://www.kraken.com/legal/privacy para conocer más
|
Vea su política de privadad en https://coinmarketcap.com/privacy para conocer más
|
||||||
detalles acerca de como se recopilan los datos de sus peticiones (especialmente la sección
|
detalles acerca de como se recopilan los datos de sus peticiones.</p>
|
||||||
"Innformation We Collect Automatically").</p>
|
|
||||||
<h2>Permisos de la App</h2>
|
<h2>Permisos de la App</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>INTERNET : Conectar a la red de Monero a través de un Daemon Nodo de Monero</li>
|
<li>INTERNET : Conectar a la red de Monero a través de un Daemon Nodo de Monero</li>
|
||||||
|