mirror of https://github.com/m2049r/xmrwallet.git
coinmarketcap for exchange rates (#304)
This commit is contained in:
parent
843566b820
commit
37244cb9e0
|
@ -43,9 +43,7 @@ import com.m2049r.xmrwallet.model.Wallet;
|
|||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||
import com.m2049r.xmrwallet.service.exchange.kraken.ExchangeApiImpl;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.OkHttpClientSingleton;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
@ -152,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
|
||||
|
@ -161,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
|
||||
|
@ -172,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) {
|
||||
|
@ -230,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());
|
||||
|
|
|
@ -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.xmrwallet.service.exchange.kraken;
|
||||
package com.m2049r.xmrwallet.service.exchange.coinmarketcap;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
@ -23,6 +23,7 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
|||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeException;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||
import com.m2049r.xmrwallet.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 = "328";
|
||||
|
||||
@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)
|
|
@ -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.xmrwallet.service.exchange.kraken;
|
||||
package com.m2049r.xmrwallet.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());
|
||||
}
|
|
@ -56,6 +56,7 @@ import com.m2049r.xmrwallet.R;
|
|||
import com.m2049r.xmrwallet.model.NetworkType;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.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 = "XMR";
|
||||
|
||||
static private final String WALLET_DIR = "monerujo" + (BuildConfig.DEBUG ? "-debug" : "");
|
||||
static private final String HOME_DIR = "monero" + (BuildConfig.DEBUG ? "-debug" : "");
|
||||
|
||||
|
@ -523,4 +526,9 @@ public class Helper {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static public ExchangeApi getExchangeApi() {
|
||||
return new com.m2049r.xmrwallet.service.exchange.coinmarketcap.ExchangeApiImpl(OkHttpClientSingleton.getOkHttpClient());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,9 +36,7 @@ import com.m2049r.xmrwallet.model.Wallet;
|
|||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||
import com.m2049r.xmrwallet.service.exchange.kraken.ExchangeApiImpl;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.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();
|
||||
|
|
|
@ -42,9 +42,7 @@ import com.m2049r.xmrwallet.model.Wallet;
|
|||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||
import com.m2049r.xmrwallet.service.exchange.kraken.ExchangeApiImpl;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.OkHttpClientSingleton;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -315,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
|
||||
|
|
|
@ -29,11 +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 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>
|
||||
<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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -31,11 +31,10 @@
|
|||
réseau Monero sous une forme chiffrée.
|
||||
</p>
|
||||
<p>Aucune autre donnée personnelle n’est collectée par l’application.</p>
|
||||
<p>Si vous utilisez la fonction (optionnelle) de change USD/EUR, monerujo récupère le
|
||||
taux de change via l’API publique de kraken.com.
|
||||
Consultez leur politique de confidentialité sur https://www.kraken.com/legal/privacy
|
||||
pour des détails sur la façon dont les données de vos requêtes sont collectées
|
||||
(particulièrement la rubrique "Information We Collect Automatically").</p>
|
||||
<p>Si vous utilisez la fonction (optionnelle) de change, monerujo récupère le
|
||||
taux de change via l’API publique de coinmarketcap.com.
|
||||
Consultez leur politique de confidentialité sur https://coinmarketcap.com/privacy
|
||||
pour des détails sur la façon dont les données de vos requêtes sont collectées.</p>
|
||||
<p>Si vous utilisez l’application pour payer à une adresse BTC, vous utiliserez
|
||||
le service XMR.TO. Consultez leur politique de confidentialité sur https://xmr.to/
|
||||
pour plus de détails. Monerujo leur transmet l’adresse de destination BTC et le
|
||||
|
|
|
@ -15,35 +15,35 @@
|
|||
|
||||
<string name="privacy_policy"><![CDATA[
|
||||
<h1>Politica per la Privacy</h1>
|
||||
<p>Questa pagina ti informa sulla nostra politica riguardante la raccolta, l'utilizzo e la rivelazione di informazioni personali che riceviamo dagli utenti della nostra app (monerujo: Portafoglio Monero).
|
||||
<p>Questa pagina ti informa sulla nostra politica riguardante la raccolta, l\'utilizzo e la rivelazione di informazioni personali che riceviamo dagli utenti della nostra app (monerujo: Portafoglio Monero).
|
||||
</p>
|
||||
<p>Usando questa app, acconsenti alla raccolta e all'utilizzo delle informazioni in accordo con questa politica.
|
||||
<p>Usando questa app, acconsenti alla raccolta e all\'utilizzo delle informazioni in accordo con questa politica.
|
||||
</p>
|
||||
<h2>Dati raccolti</h2>
|
||||
<p>Per "dato personale" si intende ogni tipo di dato grazie al quale è possibile identificare un individuo.
|
||||
</p>
|
||||
<p>Le chiavi e gli indirizzi pubblici di Monero vengono raccolti e processati dall'app localmente con lo scopo di processare le transazioni e vengono trasmessi all'interno della rete Monero in modo cifrato.
|
||||
<p>Le chiavi e gli indirizzi pubblici di Monero vengono raccolti e processati dall\'app localmente con lo scopo di processare le transazioni e vengono trasmessi all\'interno della rete Monero in modo cifrato.
|
||||
</p>
|
||||
<p>Altri dati personali non sono raccolti dall'app.</p>
|
||||
<p>Se usi la funzionalità (opzionale) del cambio USD/EUR, monerujo recupera il tasso di cambio attraverso le API pubbliche di kraken.com.
|
||||
Controlla la loro politica per la privacy (in lingua inglese) su https://www.kraken.com/legal/privacy per conoscere i dettagli su come vengono raccolti i dati nelle tue richieste (specialmente la sezione "Information We Collect Automatically" - "Informazioni che raccogliamo in modo automatico).</p>
|
||||
<p>Altri dati personali non sono raccolti dall\'app.</p>
|
||||
<p>Se usi la funzionalità (opzionale) del cambio, monerujo recupera il tasso di cambio attraverso le API pubbliche di coinmarketcap.com.
|
||||
Controlla la loro politica per la privacy (in lingua inglese) su https://coinmarketcap.com/privacy per conoscere i dettagli su come vengono raccolti i dati nelle tue richieste.</p>
|
||||
<p>Se utilizzi l'app per effettuare pagamenti ad indirizzi BTC, stai usando il servizio XMR.TO.
|
||||
Controlla la loro politica per la privacy (in lingua inglese) su https://xmr.to/ per conoscere i dettagli. Monerujo invia a loro l'indirizzo di destinazione BTC e l'ammontare della transazione. Anche il tuo IP potrebbe essere raccolto.</p>
|
||||
<h2>Permessi app</h2>
|
||||
<ul>
|
||||
<li>INTERNET : Connessione alla rete Monero attraverso un nodo </li>
|
||||
<li>READ_EXTERNAL_STORAGE : Legge i file di portafoglio salvati all'interno del dispositivo</li>
|
||||
<li>WRITE_EXTERNAL_STORAGE : Scrive i file di portafoglio salvati all'interno del dispositivo</li>
|
||||
<li>READ_EXTERNAL_STORAGE : Legge i file di portafoglio salvati all\'interno del dispositivo</li>
|
||||
<li>WRITE_EXTERNAL_STORAGE : Scrive i file di portafoglio salvati all\'interno del dispositivo</li>
|
||||
<li>WAKE_LOCK : Tiene il dispositivo sveglio durante la sincronizzazione</li>
|
||||
<li>CAMERA : Scansione codici QR di indirizzi Monero</li>
|
||||
</ul>
|
||||
<h2>Modifica a questa Politica per la Privacy</h2>
|
||||
<p>Potremmo aggiorare questa politica per la privacy di volta in volta. Ti invieremo una notifica su ciò che è cambiato pubblicando la nuova politica per la privacy all'interno dell'app e sul sito (www.monerujo.io)
|
||||
<p>Potremmo aggiorare questa politica per la privacy di volta in volta. Ti invieremo una notifica su ciò che è cambiato pubblicando la nuova politica per la privacy all\'interno dell\'app e sul sito (www.monerujo.io)
|
||||
Sei invitato a rivedere periodicamente questa politica per la privacy per controllarne i cambiamenti.
|
||||
<p>Questa politica per la privacy è stata aggiornata il 10 novembre 2017.
|
||||
</p>
|
||||
<h2>Contattaci</h2>
|
||||
<p>Se hai dubbi o domande sulla nostra politica per la privacy, oppure su come i tuoi dati vengono raccolti e processati, contattaci all'indirizzo email privacy@monerujo.io.
|
||||
<p>Se hai dubbi o domande sulla nostra politica per la privacy, oppure su come i tuoi dati vengono raccolti e processati, contattaci all\'indirizzo email privacy@monerujo.io.
|
||||
</p>
|
||||
]]></string>
|
||||
</resources>
|
||||
|
|
|
@ -30,11 +30,10 @@
|
|||
in encrypted form.
|
||||
</p>
|
||||
<p>Other personal data is not collected by the app.</p>
|
||||
<p>If you use the USD/EUR exchange (optional) functionality, monerujo fetches the exchange
|
||||
rate through the public API of kraken.com.
|
||||
See their privacy policy at https://www.kraken.com/legal/privacy for
|
||||
details on how data in your requests is collected (especially the
|
||||
section "Information We Collect Automatically").</p>
|
||||
<p>If you use the exchange (optional) functionality, monerujo fetches the exchange
|
||||
rate through the public API of coinmarketcap.com.
|
||||
See their privacy policy at https://coinmarketcap.com/privacy for
|
||||
details on how data in your requests is collected.</p>
|
||||
<p>If you use the app to pay to BTC addresses, you will be using the XMR.TO service.
|
||||
See their privacy policy at https://xmr.to/ for details. Monerujo send them the BTC
|
||||
destination address and amount. Your IP will also be collectable.</p>
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
<p>Monerujo 只会在本地端使用您的 Monero 私钥以及公开地址执行必要的处理,并在加密后发送至
|
||||
Monero 网络进行交易。</p>
|
||||
<p>其他个人信息都不会被 monerujo 收集。</p>
|
||||
<p>如果你使用 USD/EUR 外汇的功能(可选用),monerujo 將通过 kraken.com 的公开
|
||||
API 抓取当前汇率。如果你想了解自己被收集的信息如何被使用,请访问 https://www.kraken.com/legal/privacy
|
||||
查看他们的隐私政策,特別是「Information We Collect Automatically」章节。</p>
|
||||
<p>如果你使用外汇的功能(可选用),monerujo 將通过 coinmarketcap.com 的公开
|
||||
API 抓取当前汇率。如果你想了解自己被收集的信息如何被使用,请访问 https://coinmarketcap.com/privacy
|
||||
查看他们的隐私政策。</p>
|
||||
<p>如果你想使用本 App 支付款项至比特币地址,您将使用 XMR.TO 所提供的服务。Monerujo
|
||||
将发送比特币的目标地址以及金额至 XMR.TO,您的 IP 在此时也可能会被收集。详情请至 https://xmr.to/
|
||||
查看他们的隐私政策。</p>
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
<p>Monerujo 只會在本地端使用您的 Monero 金鑰以及公開地址執行必要的處理,並在加密後發送至
|
||||
Monero 網路進行交易。</p>
|
||||
<p>其餘的個人資料都不會被 monerujo 收集。</p>
|
||||
<p>倘若您有使用 USD/EUR 匯兌的功能(可選用),monerujo 將透過 kraken.com 的公開
|
||||
API 抓取目前的匯率。若欲了解您要求的資料會如何被收集及使用,請至 https://www.kraken.com/legal/privacy
|
||||
觀看他們的隱私權政策,特別是「Information We Collect Automatically」章節。</p>
|
||||
<p>倘若您有使用匯兌的功能(可選用),monerujo 將透過 coinmarketcap.com 的公開
|
||||
API 抓取目前的匯率。若欲了解您要求的資料會如何被收集及使用,請至 https://coinmarketcap.com/privacy
|
||||
觀看他們的隱私權政策。</p>
|
||||
<p>若您想使用本 App 支付款項至 BTC 位址,您將使用 XMR.TO 所提供的服務。Monerujo
|
||||
將發送 BTC 目標位址以及金額至 XMR.TO,您的 IP 在此時也可能會被收集。詳情請至 https://xmr.to/
|
||||
觀看他們的隱私權政策。</p>
|
||||
|
|
|
@ -30,11 +30,10 @@
|
|||
in encrypted form.
|
||||
</p>
|
||||
<p>Other personal data is not collected by the app.</p>
|
||||
<p>If you use the USD/EUR exchange (optional) functionality, monerujo fetches the exchange
|
||||
rate through the public API of kraken.com.
|
||||
See their privacy policy at https://www.kraken.com/legal/privacy for
|
||||
details on how data in your requests is collected (especially the
|
||||
section "Information We Collect Automatically").</p>
|
||||
<p>If you use the exchange (optional) functionality, monerujo fetches the exchange
|
||||
rate through the public API of coinmarketcap.com.
|
||||
See their privacy policy at https://coinmarketcap.com/privacy for
|
||||
details on how data in your requests is collected.</p>
|
||||
<p>If you use the app to pay to BTC addresses, you will be using the XMR.TO service.
|
||||
See their privacy policy at https://xmr.to/ for details. Monerujo send them the BTC
|
||||
destination address and amount. Your IP will also be collectable.</p>
|
||||
|
|
|
@ -321,6 +321,37 @@
|
|||
<item>XMR</item>
|
||||
<item>EUR</item>
|
||||
<item>USD</item>
|
||||
<item>JPY</item>
|
||||
<item>GBP</item>
|
||||
<item>CHF</item>
|
||||
<item>CAD</item>
|
||||
<item>AUD</item>
|
||||
<item>ZAR</item>
|
||||
|
||||
<item>BRL</item>
|
||||
<item>CLP</item>
|
||||
<item>CNY</item>
|
||||
<item>CZK</item>
|
||||
<item>DKK</item>
|
||||
<item>HKD</item>
|
||||
<item>HUF</item>
|
||||
<item>IDR</item>
|
||||
<item>ILS</item>
|
||||
<item>INR</item>
|
||||
<item>KRW</item>
|
||||
<item>MXN</item>
|
||||
<item>MYR</item>
|
||||
<item>NOK</item>
|
||||
<item>NZD</item>
|
||||
<item>PHP</item>
|
||||
<item>PKR</item>
|
||||
<item>PLN</item>
|
||||
<item>RUB</item>
|
||||
<item>SEK</item>
|
||||
<item>SGD</item>
|
||||
<item>THB</item>
|
||||
<item>TRY</item>
|
||||
<item>TWD</item>
|
||||
</string-array>
|
||||
|
||||
<string name="fab_create_new">Create new wallet</string>
|
||||
|
|
|
@ -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.xmrwallet.service.exchange.kraken;
|
||||
package com.m2049r.xmrwallet.service.exchange.coinmarketcap;
|
||||
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||
|
@ -73,7 +73,7 @@ public class ExchangeRateTest {
|
|||
public void queryExchangeRate_shouldBeGetMethod()
|
||||
throws InterruptedException, TimeoutException {
|
||||
|
||||
exchangeApi.queryExchangeRate("XMR", "USD", mockExchangeCallback);
|
||||
exchangeApi.queryExchangeRate("XMR", "EUR", mockExchangeCallback);
|
||||
|
||||
RecordedRequest request = mockWebServer.takeRequest();
|
||||
assertEquals("GET", request.getMethod());
|
||||
|
@ -83,18 +83,46 @@ public class ExchangeRateTest {
|
|||
public void queryExchangeRate_shouldHavePairInUrl()
|
||||
throws InterruptedException, TimeoutException {
|
||||
|
||||
exchangeApi.queryExchangeRate("XMR", "USD", mockExchangeCallback);
|
||||
exchangeApi.queryExchangeRate("XMR", "EUR", mockExchangeCallback);
|
||||
|
||||
RecordedRequest request = mockWebServer.takeRequest();
|
||||
assertEquals("/?pair=XMRUSD", request.getPath());
|
||||
assertEquals("/328/?convert=EUR", request.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryExchangeRate_wasSuccessfulShouldRespondWithRate()
|
||||
throws InterruptedException, JSONException, TimeoutException {
|
||||
final String base = "XMR";
|
||||
final String quote = "EUR";
|
||||
final double rate = 1.56;
|
||||
MockResponse jsonMockResponse = new MockResponse().setBody(
|
||||
createMockExchangeRateResponse(base, quote, rate));
|
||||
mockWebServer.enqueue(jsonMockResponse);
|
||||
|
||||
exchangeApi.queryExchangeRate(base, quote, new ExchangeCallback() {
|
||||
@Override
|
||||
public void onSuccess(final ExchangeRate exchangeRate) {
|
||||
waiter.assertEquals(exchangeRate.getBaseCurrency(), base);
|
||||
waiter.assertEquals(exchangeRate.getQuoteCurrency(), quote);
|
||||
waiter.assertEquals(exchangeRate.getRate(), rate);
|
||||
waiter.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(final Exception e) {
|
||||
waiter.fail(e);
|
||||
waiter.resume();
|
||||
}
|
||||
});
|
||||
waiter.await();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryExchangeRate_wasSuccessfulShouldRespondWithRateUSD()
|
||||
throws InterruptedException, JSONException, TimeoutException {
|
||||
final String base = "XMR";
|
||||
final String quote = "USD";
|
||||
final double rate = 100;
|
||||
final double rate = 1.56;
|
||||
MockResponse jsonMockResponse = new MockResponse().setBody(
|
||||
createMockExchangeRateResponse(base, quote, rate));
|
||||
mockWebServer.enqueue(jsonMockResponse);
|
||||
|
@ -121,6 +149,7 @@ public class ExchangeRateTest {
|
|||
public void queryExchangeRate_wasNotSuccessfulShouldCallOnError()
|
||||
throws InterruptedException, JSONException, TimeoutException {
|
||||
mockWebServer.enqueue(new MockResponse().setResponseCode(500));
|
||||
|
||||
exchangeApi.queryExchangeRate("XMR", "USD", new ExchangeCallback() {
|
||||
@Override
|
||||
public void onSuccess(final ExchangeRate exchangeRate) {
|
||||
|
@ -142,9 +171,10 @@ public class ExchangeRateTest {
|
|||
@Test
|
||||
public void queryExchangeRate_unknownAssetShouldCallOnError()
|
||||
throws InterruptedException, JSONException, TimeoutException {
|
||||
mockWebServer.enqueue(new MockResponse().
|
||||
setResponseCode(200).
|
||||
setBody("{\"error\":[\"EQuery:Unknown asset pair\"]}"));
|
||||
MockResponse jsonMockResponse = new MockResponse().setBody(
|
||||
createMockExchangeRateErrorResponse());
|
||||
mockWebServer.enqueue(jsonMockResponse);
|
||||
|
||||
exchangeApi.queryExchangeRate("XMR", "ABC", new ExchangeCallback() {
|
||||
@Override
|
||||
public void onSuccess(final ExchangeRate exchangeRate) {
|
||||
|
@ -157,7 +187,7 @@ public class ExchangeRateTest {
|
|||
waiter.assertTrue(e instanceof ExchangeException);
|
||||
ExchangeException ex = (ExchangeException) e;
|
||||
waiter.assertTrue(ex.getCode() == 200);
|
||||
waiter.assertEquals(ex.getErrorMsg(), "EQuery:Unknown asset pair");
|
||||
waiter.assertEquals(ex.getErrorMsg(), "id not found");
|
||||
waiter.resume();
|
||||
}
|
||||
|
||||
|
@ -167,19 +197,49 @@ public class ExchangeRateTest {
|
|||
|
||||
private String createMockExchangeRateResponse(final String base, final String quote, final double rate) {
|
||||
return "{\n" +
|
||||
" \"error\":[],\n" +
|
||||
" \"result\":{\n" +
|
||||
" \"X" + base + "Z" + quote + "\":{\n" +
|
||||
" \"a\":[\"" + rate + "\",\"322\",\"322.000\"],\n" +
|
||||
" \"b\":[\"" + rate + "\",\"76\",\"76.000\"],\n" +
|
||||
" \"c\":[\"" + rate + "\",\"2.90000000\"],\n" +
|
||||
" \"v\":[\"4559.03962053\",\"5231.33235586\"],\n" +
|
||||
" \"p\":[\"" + rate + "\",\"" + rate + "\"],\n" +
|
||||
" \"t\":[801,1014],\n" +
|
||||
" \"l\":[\"" + (rate * 0.8) + "\",\"" + rate + "\"],\n" +
|
||||
" \"h\":[\"" + (rate * 1.2) + "\",\"" + rate + "\"],\n" +
|
||||
" \"o\":\"" + rate + "\"\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"id\": 328, \n" +
|
||||
" \"name\": \"Monero\", \n" +
|
||||
" \"symbol\": \"" + base + "\", \n" +
|
||||
" \"website_slug\": \"monero\", \n" +
|
||||
" \"rank\": 12, \n" +
|
||||
" \"circulating_supply\": 16112286.0, \n" +
|
||||
" \"total_supply\": 16112286.0, \n" +
|
||||
" \"max_supply\": null, \n" +
|
||||
" \"quotes\": {\n" +
|
||||
" \"USD\": {\n" +
|
||||
" \"price\": " + rate + ", \n" +
|
||||
" \"volume_24h\": 35763700.0, \n" +
|
||||
" \"market_cap\": 2559791130.0, \n" +
|
||||
" \"percent_change_1h\": -0.16, \n" +
|
||||
" \"percent_change_24h\": -3.46, \n" +
|
||||
" \"percent_change_7d\": 1.49\n" +
|
||||
" }, \n" +
|
||||
(!"USD".equals(quote) ? (
|
||||
" \"" + quote + "\": {\n" +
|
||||
" \"price\": " + rate + ", \n" +
|
||||
" \"volume_24h\": 30377728.701265607, \n" +
|
||||
" \"market_cap\": 2174289586.0, \n" +
|
||||
" \"percent_change_1h\": -0.16, \n" +
|
||||
" \"percent_change_24h\": -3.46, \n" +
|
||||
" \"percent_change_7d\": 1.49\n" +
|
||||
" }\n") : "") +
|
||||
" }, \n" +
|
||||
" \"last_updated\": 1528492746\n" +
|
||||
" }, \n" +
|
||||
" \"metadata\": {\n" +
|
||||
" \"timestamp\": 1528492705, \n" +
|
||||
" \"error\": null\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
}
|
||||
|
||||
private String createMockExchangeRateErrorResponse() {
|
||||
return "{\n" +
|
||||
" \"data\": null, \n" +
|
||||
" \"metadata\": {\n" +
|
||||
" \"timestamp\": 1525137187, \n" +
|
||||
" \"error\": \"id not found\"\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
}
|
Loading…
Reference in New Issue