Skip to content

Commit

Permalink
Doge: Exchange rates hacks
Browse files Browse the repository at this point in the history
  • Loading branch information
langerhans committed Dec 26, 2020
1 parent b200935 commit 4a2eebb
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 31 deletions.
2 changes: 1 addition & 1 deletion wallet/src/de/schildbach/wallet/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public final static class Files {
public static final int ADDRESS_FORMAT_GROUP_SIZE = 4;
public static final int ADDRESS_FORMAT_LINE_SIZE = 12;

public static final MonetaryFormat LOCAL_FORMAT = new MonetaryFormat().noCode().minDecimals(2).optionalDecimals();
public static final MonetaryFormat LOCAL_FORMAT = new MonetaryFormat().noCode().minDecimals(4).optionalDecimals();

public static final BaseEncoding HEX = BaseEncoding.base16().lowerCase();

Expand Down
22 changes: 18 additions & 4 deletions wallet/src/de/schildbach/wallet/exchangerate/CoinGecko.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -58,7 +62,7 @@ public HttpUrl url() {
return URL;
}

public List<ExchangeRateEntry> parse(final BufferedSource jsonSource) throws IOException {
public List<ExchangeRateEntry> parse(final BufferedSource jsonSource, double conv) throws IOException {
final JsonAdapter<Response> jsonAdapter = moshi.adapter(Response.class);
final Response jsonResponse = jsonAdapter.fromJson(jsonSource);
final List<ExchangeRateEntry> result = new ArrayList<>(jsonResponse.rates.size());
Expand All @@ -67,9 +71,19 @@ public List<ExchangeRateEntry> parse(final BufferedSource jsonSource) throws IOE
final ExchangeRateJson exchangeRate = entry.getValue();
if (exchangeRate.type == Type.FIAT) {
try {
final Fiat rate = Fiat.parseFiatInexact(symbol, exchangeRate.value);
if (rate.signum() > 0)
result.add(new ExchangeRateEntry(SOURCE, new ExchangeRate(rate)));
final String rate = exchangeRate.value;
final double btcRate = Double.parseDouble(Fiat.parseFiatInexact(symbol, rate).toPlainString());
DecimalFormat df = new DecimalFormat("#.########");
df.setRoundingMode(RoundingMode.HALF_UP);
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
dfs.setGroupingSeparator(',');
df.setDecimalFormatSymbols(dfs);
long val = new BigDecimal(df.format(btcRate*conv)).movePointRight(8).longValue();
final Fiat dogeRate = Fiat.valueOf(symbol, val);

if (dogeRate.signum() > 0)
result.add(new ExchangeRateEntry(SOURCE, new ExchangeRate(dogeRate)));
} catch (final ArithmeticException x) {
log.warn("problem parsing {} exchange rate from {}: {}", symbol, URL, x.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
Expand Down Expand Up @@ -80,48 +82,96 @@ public InvalidationTracker exchangeRateInvalidationTracker() {
return db.getInvalidationTracker();
}

private void maybeRequestExchangeRates() {
final Stopwatch watch = Stopwatch.createStarted();
final long now = System.currentTimeMillis();

final long lastUpdated = this.lastUpdated.get();
if (lastUpdated != 0 && now - lastUpdated <= UPDATE_FREQ_MS)
return;

final CoinGecko coinGecko = new CoinGecko(new Moshi.Builder().build());
private void requestDogeBtcConversion(DogeConversionCallback cb) {
final Request.Builder request = new Request.Builder();
request.url(coinGecko.url());
request.url("https://api.coingecko.com/api/v3/simple/price?ids=dogecoin&vs_currencies=btc");
final Headers.Builder headers = new Headers.Builder();
headers.add("User-Agent", userAgent);
headers.add("Accept", coinGecko.mediaType().toString());
headers.add("Accept", "application/json");
request.headers(headers.build());

final OkHttpClient.Builder httpClientBuilder = Constants.HTTP_CLIENT.newBuilder();
httpClientBuilder.connectionSpecs(Collections.singletonList(ConnectionSpec.RESTRICTED_TLS));
final Call call = httpClientBuilder.build().newCall(request.build());
call.enqueue(new Callback() {
@Override
public void onResponse(final Call call, final Response response) throws IOException {
public void onFailure(Call call, IOException e) {
log.warn("problem fetching doge btc conversion", e);
}

@Override
public void onResponse(Call call, Response response) throws IOException {
try {
if (response.isSuccessful()) {
for (final ExchangeRateEntry exchangeRate : coinGecko.parse(response.body().source()))
dao.insertOrUpdate(exchangeRate);
ExchangeRatesRepository.this.lastUpdated.set(now);
watch.stop();
log.info("fetched exchange rates from {}, took {}", coinGecko.url(), watch);
log.info("fetched doge btc conversion");
double conv = new Moshi.Builder().build().adapter(DogeBtcConversionResponse.class).fromJson(response.body().source()).dogecoin.btc;
cb.done(conv);
} else {
log.warn("http status {} {} when fetching exchange rates from {}", response.code(),
response.message(), coinGecko.url());
log.warn("http status {} {} when fetching doge btc conversion", response.code(), response.message());
}
} catch (final Exception x) {
log.warn("problem fetching exchange rates from " + coinGecko.url(), x);
log.warn("problem fetching doge btc conversion", x);
}
}
});
}

@Override
public void onFailure(final Call call, final IOException x) {
log.warn("problem fetching exchange rates from " + coinGecko.url(), x);
}
private static class DogeBtcConversionResponse {
public DogeBtcConversionEntry dogecoin;
}

private static class DogeBtcConversionEntry {
public double btc;
}

private interface DogeConversionCallback {
void done(double conv);
}

private void maybeRequestExchangeRates() {
final Stopwatch watch = Stopwatch.createStarted();
final long now = System.currentTimeMillis();

final long lastUpdated = this.lastUpdated.get();
if (lastUpdated != 0 && now - lastUpdated <= UPDATE_FREQ_MS)
return;

requestDogeBtcConversion(conv -> {
final CoinGecko coinGecko = new CoinGecko(new Moshi.Builder().build());
final Request.Builder request = new Request.Builder();
request.url(coinGecko.url());
final Headers.Builder headers = new Headers.Builder();
headers.add("User-Agent", userAgent);
headers.add("Accept", coinGecko.mediaType().toString());
request.headers(headers.build());

final OkHttpClient.Builder httpClientBuilder = Constants.HTTP_CLIENT.newBuilder();
httpClientBuilder.connectionSpecs(Collections.singletonList(ConnectionSpec.RESTRICTED_TLS));
final Call call = httpClientBuilder.build().newCall(request.build());
call.enqueue(new Callback() {
@Override
public void onResponse(final Call call, final Response response) throws IOException {
try {
if (response.isSuccessful()) {
for (final ExchangeRateEntry exchangeRate : coinGecko.parse(response.body().source(), conv))
dao.insertOrUpdate(exchangeRate);
ExchangeRatesRepository.this.lastUpdated.set(now);
watch.stop();
log.info("fetched exchange rates from {}, took {}", coinGecko.url(), watch);
} else {
log.warn("http status {} {} when fetching exchange rates from {}", response.code(),
response.message(), coinGecko.url());
}
} catch (final Exception x) {
log.warn("problem fetching exchange rates from " + coinGecko.url(), x);
}
}

@Override
public void onFailure(final Call call, final IOException x) {
log.warn("problem fetching exchange rates from " + coinGecko.url(), x);
}
});
});
}
}
4 changes: 2 additions & 2 deletions wallet/src/de/schildbach/wallet/ui/ExchangeRatesAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ public void onBindViewHolder(final ViewHolder holder, final int position, final
holder.defaultView.setVisibility(listItem.isDefault ? View.VISIBLE : View.INVISIBLE);
}
if (fullBind || changes.contains(ChangeType.RATE)) {
holder.rateView.setFormat(Constants.LOCAL_FORMAT.minDecimals(listItem.baseRateMinDecimals));
holder.rateView.setAmount(listItem.baseRateAsFiat);
holder.rateView.setFormat(Constants.LOCAL_FORMAT.postfixCode().code(0, "/1k"));
holder.rateView.setAmount(listItem.baseRateAsFiat.divide(10));
holder.walletView.setFormat(Constants.LOCAL_FORMAT);
if (listItem.balanceAsFiat != null) {
holder.walletView.setAmount(listItem.balanceAsFiat);
Expand Down

0 comments on commit 4a2eebb

Please sign in to comment.