package com.wallet.crypto.trustapp.service; import com.google.gson.Gson; import com.wallet.crypto.trustapp.entity.ApiErrorException; import com.wallet.crypto.trustapp.entity.ErrorEnvelope; import com.wallet.crypto.trustapp.entity.TokenInfo; import io.reactivex.Observable; import io.reactivex.ObservableOperator; import io.reactivex.Observer; import io.reactivex.annotations.NonNull; import io.reactivex.observers.DisposableObserver; import io.reactivex.schedulers.Schedulers; import okhttp3.OkHttpClient; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.GET; import retrofit2.http.Path; import static com.wallet.crypto.trustapp.C.ErrorCode.UNKNOWN; public class EthplorerTokenService implements TokenExplorerClientType { private static final String ETHPLORER_API_URL = "https://api.ethplorer.io"; private EthplorerApiClient ethplorerApiClient; public EthplorerTokenService( OkHttpClient httpClient, Gson gson) { ethplorerApiClient = new Retrofit.Builder() .baseUrl(ETHPLORER_API_URL) .client(httpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build() .create(EthplorerApiClient.class); } @Override public Observable<TokenInfo[]> fetch(String walletAddress) { return ethplorerApiClient.fetchTokens(walletAddress) .lift(apiError()) .map(r -> { if (r.tokens == null) { return new TokenInfo[0]; } else { int len = r.tokens.length; TokenInfo[] result = new TokenInfo[len]; for (int i = 0; i < len; i++) { result[i] = r.tokens[i].tokenInfo; } return result; } }) .subscribeOn(Schedulers.io()); } private static @NonNull ApiErrorOperator apiError() { return new ApiErrorOperator(); } public interface EthplorerApiClient { @GET("/getAddressInfo/{address}?apiKey=freekey") Observable<Response<EthplorerResponse>> fetchTokens(@Path("address") String address); } private static class Token { TokenInfo tokenInfo; } private static class EthplorerResponse { Token[] tokens; EthplorerError error; } private static class EthplorerError { int code; String message; } private final static class ApiErrorOperator implements ObservableOperator<EthplorerResponse, Response<EthplorerResponse>> { @Override public Observer<? super Response<EthplorerResponse>> apply(Observer<? super EthplorerResponse> observer) throws Exception { return new DisposableObserver<Response<EthplorerResponse>>() { @Override public void onNext(Response<EthplorerResponse> response) { EthplorerResponse body = response.body(); if (body != null && body.error == null) { observer.onNext(body); observer.onComplete(); } else { if (body != null) { observer.onError(new ApiErrorException(new ErrorEnvelope(body.error.code, body.error.message))); } else { observer.onError(new ApiErrorException(new ErrorEnvelope(UNKNOWN, "Service not available"))); } } } @Override public void onError(Throwable e) { observer.onError(e); } @Override public void onComplete() { observer.onComplete(); } }; } } }