1
mirror of https://github.com/m2049r/xmrwallet synced 2025-09-04 17:28:42 +02:00

Compare commits

..

7 Commits

Author SHA1 Message Date
m2049r
67f24673b1 new version 2018-06-09 14:03:30 +02:00
m2049r
1b9aac7526 Fix spinners (#5) 2018-06-09 12:54:49 +02:00
m2049r
b68c425bae update gradle version 2018-06-08 22:46:41 +02:00
m2049r
cf58072c6c new verion 0.1.1 2018-06-07 19:56:45 +02:00
m2049r
6960347014 tweak colours (#4) 2018-06-07 19:05:17 +02:00
m2049r
cc5a8969d6 Use coinmarketcap for exchange rates (#3) 2018-06-07 18:45:44 +02:00
m2049r
c0ebf6c318 Remove xmr.to refrences (#2) 2018-06-07 18:29:43 +02:00
53 changed files with 284 additions and 1391 deletions

View File

@@ -1,34 +1,24 @@
# Monerujo
Another Android Monero Wallet for Monero
**(not
Monero Classic,
Monero-Classic,
Monero Zero,
Monero Original,
Monero C,
Monero V)**
# MonerujoAE
The Android AEON Wallet
### QUICKSTART
- 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
- 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)
## 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.
### 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
- Based off monero v0.11.1.0
- currently only android32 (runs on 64-bit as well)
- works on the testnet & mainnet
- sync is slow due to 32-bit architecture
- Based off aeon v0.12.0
- works on the stagenet & mainnet
- use your own daemon - it's easy
- 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
- 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
- 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.
- 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)
- 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.
The official monero client shows the same behaviour.
of the "real" stagenet. After creating a new wallet, make a **new** one by recovering from the seed.
The official client shows the same behaviour.
### HOW TO BUILD
No need to build. Binaries are included:
- 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.
Check out [the instructions](doc/BUILDING-external-libs.md)
### Donations
- Address: 4AdkPJoxn7JCvAby9szgnt93MSEwdnxdhaASxbTBm6x5dCwmsDep2UYN4FhStDn5i11nsJbpU7oj59ahg8gXb1Mg3viqCuk
- Viewkey: b1aff2a12191723da0afbe75516f94dd8b068215f6e847d8da57aca5f1f98e0c
- Address: WmsfCJfmd6QQ84Rfb2mD1y7ryBzvTiQ8MMngmgRjxDMCCkeuChA9B9ZRNZyQyjgH1zdQMBXeQB9vZhUwPHmLGhyo2nMoE2ARv

View File

@@ -7,8 +7,8 @@ android {
applicationId "com.m2049r.aeonwallet"
minSdkVersion 21
targetSdkVersion 25
versionCode 10
versionName "0.1.0 'Rebase ALPHA'"
versionCode 12
versionName "0.1.2 'Rebase RC2'"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -494,11 +494,11 @@ public class LoginActivity extends SecureActivity
break;
case NetworkType_Testnet:
toolbar.setSubtitle(getString(R.string.connect_testnet));
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(R.color.give);
break;
case NetworkType_Stagenet:
toolbar.setSubtitle(getString(R.string.connect_stagenet));
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(R.color.give);
break;
default:
throw new IllegalStateException("NetworkType unknown: " + WalletManager.getInstance().getNetworkType());

View File

@@ -270,10 +270,10 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
break;
case NetworkType_Testnet:
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(R.color.give);
break;
case NetworkType_Stagenet:
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(R.color.give);
break;
default:
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());

View File

@@ -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.ExchangeCallback;
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.OkHttpClientSingleton;
import com.m2049r.aeonwallet.widget.Toolbar;
import java.text.NumberFormat;
@@ -101,7 +99,9 @@ public class WalletFragment extends Fragment
ivSynced = (ImageView) view.findViewById(R.id.ivSynced);
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);
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
String displayB;
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;
displayB = Helper.getFormattedAmount(amountB, false);
} else { // XMR
@@ -159,10 +159,10 @@ public class WalletFragment extends Fragment
tvBalance.setText(displayB);
}
String balanceCurrency = "XMR";
String balanceCurrency = Helper.CRYPTO;
double balanceRate = 1.0;
private final ExchangeApi exchangeApi = new ExchangeApiImpl(OkHttpClientSingleton.getOkHttpClient());
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
void refreshBalance() {
if (sCurrency.getSelectedItemPosition() == 0) { // XMR
@@ -170,9 +170,10 @@ public class WalletFragment extends Fragment
tvBalance.setText(Helper.getFormattedAmount(amountXmr, true));
} else { // not XMR
String currency = (String) sCurrency.getSelectedItem();
Timber.d(currency);
if (!currency.equals(balanceCurrency) || (balanceRate <= 0)) {
showExchanging();
exchangeApi.queryExchangeRate("XMR", currency,
exchangeApi.queryExchangeRate(Helper.CRYPTO, currency,
new ExchangeCallback() {
@Override
public void onSuccess(final ExchangeRate exchangeRate) {
@@ -228,10 +229,10 @@ public class WalletFragment extends Fragment
public void exchange(final ExchangeRate exchangeRate) {
hideExchanging();
if (!"XMR".equals(exchangeRate.getBaseCurrency())) {
if (!Helper.CRYPTO.equals(exchangeRate.getBaseCurrency())) {
Timber.e("Not XMR");
sCurrency.setSelection(0, true);
balanceCurrency = "XMR";
balanceCurrency = Helper.CRYPTO;
balanceRate = 1.0;
} else {
int spinnerPosition = ((ArrayAdapter) sCurrency.getAdapter()).getPosition(exchangeRate.getQuoteCurrency());

View File

@@ -96,10 +96,6 @@ public class SendFragment extends Fragment
private Button bDone;
private View llXmrToEnabled;
private View ibXmrToInfoClose;
static private int MAX_FALLBACK = Integer.MAX_VALUE;
@Override
@@ -510,22 +506,4 @@ public class SendFragment extends Fragment
inflater.inflate(R.menu.send_menu, menu);
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();
}
}

View File

@@ -103,7 +103,6 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
final ImageView ivTxType;
final TextView tvAmount;
final TextView tvFee;
final TextView tvPaymentId;
@@ -112,7 +111,6 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
ViewHolder(View itemView) {
super(itemView);
ivTxType = (ImageView) itemView.findViewById(R.id.ivTxType);
tvAmount = (TextView) itemView.findViewById(R.id.tx_amount);
tvFee = (TextView) itemView.findViewById(R.id.tx_fee);
tvPaymentId = (TextView) itemView.findViewById(R.id.tx_paymentid);
@@ -131,11 +129,6 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
this.infoItem = infoItems.get(position);
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);
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* 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.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.ExchangeException;
import com.m2049r.aeonwallet.service.exchange.api.ExchangeRate;
import com.m2049r.aeonwallet.util.Helper;
import org.json.JSONArray;
import org.json.JSONException;
@@ -37,6 +38,7 @@ import okhttp3.Request;
import okhttp3.Response;
public class ExchangeApiImpl implements ExchangeApi {
static final String CRYPTO_ID = "1026";
@NonNull
private final OkHttpClient okHttpClient;
@@ -52,7 +54,7 @@ public class ExchangeApiImpl implements ExchangeApi {
}
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
@@ -67,12 +69,12 @@ public class ExchangeApiImpl implements ExchangeApi {
boolean inverse = false;
String fiat = null;
if (baseCurrency.equals("XMR")) {
if (baseCurrency.equals(Helper.CRYPTO)) {
fiat = quoteCurrency;
inverse = false;
}
if (quoteCurrency.equals("XMR")) {
if (quoteCurrency.equals(Helper.CRYPTO)) {
fiat = baseCurrency;
inverse = true;
}
@@ -85,7 +87,8 @@ public class ExchangeApiImpl implements ExchangeApi {
final boolean swapAssets = inverse;
final HttpUrl url = baseUrl.newBuilder()
.addQueryParameter("pair", "XMR" + fiat)
.addEncodedPathSegments(CRYPTO_ID + "/")
.addQueryParameter("convert", fiat)
.build();
final Request httpRequest = createHttpRequest(url);
@@ -101,12 +104,12 @@ public class ExchangeApiImpl implements ExchangeApi {
if (response.isSuccessful()) {
try {
final JSONObject json = new JSONObject(response.body().string());
final JSONArray jsonError = json.getJSONArray("error");
if (jsonError.length() > 0) {
final String errorMsg = jsonError.getString(0);
callback.onError(new ExchangeException(response.code(), errorMsg));
final JSONObject metadata = json.getJSONObject("metadata");
if (!metadata.isNull("error")) {
final String errorMsg = metadata.getString("error");
callback.onError(new ExchangeException(response.code(), (String) errorMsg));
} else {
final JSONObject jsonResult = json.getJSONObject("result");
final JSONObject jsonResult = json.getJSONObject("data");
reportSuccess(jsonResult, swapAssets, callback);
}
} catch (JSONException ex) {
@@ -130,7 +133,6 @@ public class ExchangeApiImpl implements ExchangeApi {
}
}
private Request createHttpRequest(final HttpUrl url) {
return new Request.Builder()
.url(url)

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.m2049r.aeonwallet.service.exchange.kraken;
package com.m2049r.aeonwallet.service.exchange.coinmarketcap;
import android.support.annotation.NonNull;
@@ -25,6 +25,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -37,7 +38,7 @@ class ExchangeRateImpl implements ExchangeRate {
@Override
public String getServiceName() {
return "kraken.com";
return "coinmarketcap.com";
}
@Override
@@ -64,29 +65,21 @@ class ExchangeRateImpl implements ExchangeRate {
ExchangeRateImpl(final JSONObject jsonObject, final boolean swapAssets) throws JSONException, ExchangeException {
try {
final String key = jsonObject.keys().next(); // we expect only one
Pattern pattern = Pattern.compile("^X(.*?)Z(.*?)$");
Matcher matcher = pattern.matcher(key);
if (matcher.find()) {
this.baseCurrency = swapAssets ? matcher.group(2) : matcher.group(1);
this.quoteCurrency = swapAssets ? matcher.group(1) : matcher.group(2);
} else {
throw new ExchangeException("no pair returned!");
}
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 baseC = jsonObject.getString("symbol");
final JSONObject quotes = jsonObject.getJSONObject("quotes");
final Iterator<String> keys = quotes.keys();
String key = null;
// get key which is not USD unless it is the only one
while (keys.hasNext()) {
key = keys.next();
if (!key.equals("USD")) break;
}
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) {
throw new ExchangeException(ex.getLocalizedMessage());
}

View File

@@ -56,6 +56,7 @@ import com.m2049r.aeonwallet.R;
import com.m2049r.aeonwallet.model.NetworkType;
import com.m2049r.aeonwallet.model.Wallet;
import com.m2049r.aeonwallet.model.WalletManager;
import com.m2049r.aeonwallet.service.exchange.api.ExchangeApi;
import java.io.File;
import java.io.IOException;
@@ -72,6 +73,8 @@ import okhttp3.HttpUrl;
import timber.log.Timber;
public class Helper {
static public final String CRYPTO = "AEON";
static private final String WALLET_DIR = "aeonwallet" + (BuildConfig.DEBUG ? "-debug" : "");
static private final String HOME_DIR = "aeon" + (BuildConfig.DEBUG ? "-debug" : "");
@@ -285,15 +288,6 @@ public class Helper {
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();
public static String bytesToHex(byte[] data) {
@@ -341,13 +335,11 @@ public class Helper {
// or the password used to derive the CrAzYpass for the wallet
static public String getWalletPassword(Context context, String walletName, String password) {
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)
if (WalletManager.getInstance().verifyWalletPassword(walletPath, password, true)) {
return password;
}
Timber.e("B");
// maybe this is a malformed CrAzYpass?
String possibleCrazyPass = CrazyPassEncoder.reformat(password);
@@ -356,15 +348,12 @@ public class Helper {
return possibleCrazyPass;
}
}
Timber.e("C");
// generate & try with CrAzYpass
String crazyPass = KeyStoreHelper.getCrazyPass(context, password);
Timber.e("D /%s/",crazyPass);
if (WalletManager.getInstance().verifyWalletPassword(walletPath, crazyPass, true)) {
return crazyPass;
}
Timber.e("E");
return null;
}
@@ -516,4 +505,9 @@ public class Helper {
return false;
}
}
static public ExchangeApi getExchangeApi() {
return new com.m2049r.aeonwallet.service.exchange.coinmarketcap.ExchangeApiImpl(OkHttpClientSingleton.getOkHttpClient());
}
}

View File

@@ -37,8 +37,6 @@ public class Notice {
private static final String PREFS_NAME = "notice";
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 void init() {

View File

@@ -22,25 +22,13 @@ import java.util.regex.Pattern;
public class UserNotes {
public String txNotes = "";
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) {
if (txNotes == null) {
return;
}
this.txNotes = txNotes;
Pattern p = Pattern.compile("^\\{(xmrto-\\w{6}),([0-9.]*)BTC,(\\w*)\\} ?(.*)");
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;
}
note = txNotes;
}
public void setNote(String newNote) {
@@ -53,21 +41,6 @@ public class UserNotes {
}
private String buildTxNote() {
StringBuffer sb = new StringBuffer();
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();
return note;
}
}

View File

@@ -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.ExchangeCallback;
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.OkHttpClientSingleton;
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() {
showProgress();

View File

@@ -30,6 +30,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
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.ExchangeCallback;
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.OkHttpClientSingleton;
import java.util.Locale;
@@ -166,7 +165,11 @@ public class ExchangeView extends LinearLayout
etAmount = (TextInputLayout) findViewById(R.id.etAmount);
tvAmountB = (TextView) findViewById(R.id.tvAmountB);
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.setAdapter(adapter);
evExchange = (ImageView) findViewById(R.id.evExchange);
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() {
showProgress();
String currencyA = (String) sCurrencyA.getSelectedItem();
String currencyB = (String) sCurrencyB.getSelectedItem();
exchangeApi.queryExchangeRate(currencyA, currencyB,
new ExchangeCallback() {
@Override

View File

@@ -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);
}
}

View File

@@ -3,7 +3,7 @@
android:shape="rectangle">
<gradient
android:angle="45"
android:endColor="@color/gradientOrange"
android:startColor="@color/gradientPink"
android:endColor="@color/gradientPink"
android:startColor="@color/gradientOrange"
android:type="linear" />
</shape>

View File

@@ -3,7 +3,7 @@
android:shape="oval">
<gradient
android:angle="45"
android:endColor="@color/gradientOrange"
android:startColor="@color/gradientPink"
android:endColor="@color/gradientPink"
android:startColor="@color/gradientOrange"
android:type="linear" />
</shape>

View File

@@ -57,6 +57,7 @@
android:layout_marginStart="8dp"
android:entries="@array/currency"
android:gravity="center"
android:minWidth="96dp"
android:paddingBottom="2dp"
android:paddingEnd="4dp"
android:paddingStart="4dp"

View 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" />

View 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" />

View File

@@ -20,38 +20,23 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="9"
android:orientation="horizontal">
android:orientation="vertical">
<ImageView
android:id="@+id/ivTxType"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_gravity="center"
android:src="@drawable/ic_xmrto_32dp"
android:visibility="visible" />
<LinearLayout
<TextView
android:id="@+id/tx_amount"
style="@style/MoneroText.PosAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
android:gravity="end"
tools:text="+ 999.999999" />
<TextView
android:id="@+id/tx_amount"
style="@style/MoneroText.PosAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
tools:text="+ 999.999999" />
<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>
<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>
<TextView

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
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
android:layout_width="match_parent"
@@ -12,12 +12,12 @@
<Spinner
android:id="@+id/sCurrencyA"
android:layout_width="64dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:entries="@array/currency"
android:gravity="center"
android:textAlignment="center" />
android:minWidth="72dp" />
<com.m2049r.aeonwallet.widget.CTextInputLayout
android:id="@+id/etAmount"
@@ -49,19 +49,18 @@
<Spinner
android:id="@+id/sCurrencyB"
style="@style/MoneroSpinnerGray"
android:layout_width="64sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:entries="@array/currency"
android:gravity="center"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:minWidth="72dp"
android:textAlignment="center" />
<TextView
android:id="@+id/tvAmountB"
style="@style/MoneroText"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:layout_marginStart="16dp"

View File

@@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -29,15 +29,10 @@
von Transaktionen lokal gesammelt und verarbeitet und verschlüsselt in das Monero-Netzwerk übertragen.
</p>
<p>Andere persönliche Daten werden von der App nicht gesammelt.</p>
<p>Wenn du den USD/EUR Umrechner (optional) nutzt fragt Monerujo
den aktuellen Kurs über die öffentliche Schnittstelle von kraken.com ab.
Siehe dir ihre Datenschutzerklärung unter https://www.kraken.com/legal/privacy für
Details darüber an, wie Daten in deinen Anfragen gesammelt werden (insbesondere der
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>
<p>Wenn du den Umrechner (optional) nutzt fragt Monerujo
den aktuellen Kurs über die öffentliche Schnittstelle von coinmarketcap.com ab.
Siehe dir ihre Datenschutzerklärung unter https://coinmarketcap.com/privacy für
Details darüber an, wie Daten in deinen Anfragen gesammelt werden.</p>
<h2>App-Berechtigungen</h2>
<ul>
<li>INTERNET : Verbinde zum Monero Netzwerk über eine Monero Daemon Node</li>

View File

@@ -160,8 +160,6 @@
<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
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>
<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>
@@ -176,29 +174,6 @@
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
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>
</resources>

View File

@@ -29,11 +29,10 @@
Monero de forma cifrada.
</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
de cambio a través de la API pública de kraken.com.
Vea su política de privadad en https://www.kraken.com/legal/privacy para conocer más
detalles acerca de como se recopilan los datos de sus peticiones (especialmente la sección
"Innformation We Collect Automatically").</p>
<p>Si utiliza la funcionalidad de cambio (opcional), monerujo obtiene la tasa
de cambio a través de la API pública de coinmarketcap.com.
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.</p>
<h2>Permisos de la App</h2>
<ul>
<li>INTERNET : Conectar a la red de Monero a través de un Daemon Nodo de Monero</li>

Some files were not shown because too many files have changed in this diff Show More