Last active
October 13, 2020 09:35
-
-
Save Legion1900/26bbd2d05c9e974a785441632cf79ff3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Code of this class belongs to https://github.com/horizontalsystems/ethereum-kit-android library; | |
* Modified by Sapien Wallet team on 10.12.2020 | |
* */ | |
import com.google.gson.Gson | |
import com.google.gson.JsonElement | |
import com.google.gson.reflect.TypeToken | |
import com.sapien.wallet.di.modules.ApiKeyModule | |
import com.sapien.wallet.di.modules.retrofit.GsonModule | |
import io.horizontalsystems.ethereumkit.api.models.etherscan.EtherscanResponse | |
import io.horizontalsystems.ethereumkit.core.retryWhenError | |
import io.horizontalsystems.ethereumkit.models.Address | |
import io.reactivex.Single | |
import retrofit2.http.GET | |
import retrofit2.http.Query | |
import javax.inject.Inject | |
import javax.inject.Named | |
import javax.inject.Singleton | |
@Singleton | |
class EtherscanService @Inject constructor( | |
@Named(GsonModule.ETHERSCAN_SERVICE) private val gson: Gson, | |
private val service: EtherscanServiceAPI, | |
@Named(ApiKeyModule.ETHERSCAN) private val apiKey: String | |
) { | |
fun getTransactionList(address: Address, startBlock: Long): Single<EtherscanResponse> { | |
return service.getTransactionList("account", "txList", address.hex, startBlock, 99_999_999, "desc", apiKey) | |
.map { parseResponse(it) } | |
.retryWhenError(RequestError.RateLimitExceed::class) | |
} | |
fun getInternalTransactionList(address: Address, startBlock: Long): Single<EtherscanResponse> { | |
return service.getTransactionList( | |
"account", | |
"txlistinternal", | |
address.hex, | |
startBlock, | |
99_999_999, | |
"desc", | |
apiKey | |
) | |
.map { parseResponse(it) } | |
.retryWhenError(RequestError.RateLimitExceed::class) | |
} | |
fun getTokenTransactions(contractAddress: Address, address: Address, startBlock: Long): Single<EtherscanResponse> { | |
return service.getTokenTransactions( | |
"account", | |
"tokentx", | |
contractAddress.hex, | |
address.hex, | |
startBlock, | |
99_999_999, | |
"desc", | |
apiKey | |
) | |
.map { parseResponse(it) } | |
.retryWhenError(RequestError.RateLimitExceed::class) | |
} | |
private fun parseResponse(response: JsonElement): EtherscanResponse { | |
try { | |
val responseObj = response.asJsonObject | |
val status = responseObj["status"].asJsonPrimitive.asString | |
val message = responseObj["message"].asJsonPrimitive.asString | |
if (status == "0" && message != "No transactions found") { | |
val result = responseObj["result"].asJsonPrimitive.asString | |
if (message == "NOTOK" && result == "Max rate limit reached") { | |
throw RequestError.RateLimitExceed() | |
} | |
} | |
val result: List<Map<String, String>> = | |
gson.fromJson(responseObj["result"], object : TypeToken<List<Map<String, String>>>() {}.type) | |
return EtherscanResponse(status, message, result) | |
} catch (rateLimitExceeded: RequestError.RateLimitExceed) { | |
throw rateLimitExceeded | |
} catch (err: Throwable) { | |
throw RequestError.ResponseError("Unexpected response: $response") | |
} | |
} | |
open class RequestError(message: String? = null) : Exception(message ?: "") { | |
class ResponseError(message: String) : RequestError(message) | |
class RateLimitExceed : RequestError() | |
} | |
interface EtherscanServiceAPI { | |
@GET("/api") | |
fun getTransactionList( | |
@Query("module") module: String, | |
@Query("action") action: String, | |
@Query("address") address: String, | |
@Query("startblock") startblock: Long, | |
@Query("endblock") endblock: Long, | |
@Query("sort") sort: String, | |
@Query("apiKey") apiKey: String | |
): Single<JsonElement> | |
@GET("/api") | |
fun getTokenTransactions( | |
@Query("module") module: String, | |
@Query("action") action: String, | |
@Query("contractaddress") contractAddress: String, | |
@Query("address") address: String, | |
@Query("startblock") startblock: Long, | |
@Query("endblock") endblock: Long, | |
@Query("sort") sort: String, | |
@Query("apiKey") apiKey: String | |
): Single<JsonElement> | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment