Skip to content

Commit

Permalink
Rotate keys
Browse files Browse the repository at this point in the history
  • Loading branch information
abdrasulov committed Oct 18, 2024
1 parent a30cc3a commit 0a02ad0
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ class AddressWatchViewModel : ViewModel() {

when (Configuration.chain) {
Chain.BinanceSmartChain -> {
transactionSource = TransactionSource.bscscan(Configuration.bscScanKey)
transactionSource = TransactionSource.bscscan(listOf(Configuration.bscScanKey))
rpcSource = RpcSource.binanceSmartChainHttp()
}
Chain.Ethereum -> {
transactionSource = TransactionSource.ethereumEtherscan(Configuration.etherscanKey)
transactionSource = TransactionSource.ethereumEtherscan(Configuration.etherscanKey.split(","))
rpcSource = RpcSource.Http(listOf(URI(Configuration.ethereumRpc)), null)
}
else -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,17 +193,17 @@ class MainViewModel : ViewModel() {
private fun createKit(): EthereumKit {
when (Configuration.chain) {
Chain.BinanceSmartChain -> {
transactionSource = TransactionSource.bscscan(Configuration.bscScanKey)
transactionSource = TransactionSource.bscscan(listOf(Configuration.bscScanKey))
rpcSource = RpcSource.binanceSmartChainHttp()
}

Chain.Ethereum -> {
transactionSource = TransactionSource.ethereumEtherscan(Configuration.etherscanKey)
transactionSource = TransactionSource.ethereumEtherscan(Configuration.etherscanKey.split(","))
rpcSource = RpcSource.Http(listOf(URI(Configuration.ethereumRpc)), null)
}

Chain.ArbitrumOne -> {
transactionSource = TransactionSource.arbiscan(Configuration.arbiscanApiKey)
transactionSource = TransactionSource.arbiscan(listOf(Configuration.arbiscanApiKey),)
rpcSource = RpcSource.arbitrumOneRpcHttp()
}

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.3'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ class EthereumKit(
private fun transactionProvider(transactionSource: TransactionSource, address: Address): ITransactionProvider {
when (transactionSource.type) {
is TransactionSource.SourceType.Etherscan -> {
val service = EtherscanService(transactionSource.type.apiBaseUrl, transactionSource.type.apiKey)
val service = EtherscanService(transactionSource.type.apiBaseUrl, transactionSource.type.apiKeys)
return EtherscanTransactionProvider(service, address)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,78 +8,78 @@ class TransactionSource(val name: String, val type: SourceType) {
}

sealed class SourceType {
class Etherscan(val apiBaseUrl: String, val txBaseUrl: String, val apiKey: String) : SourceType()
class Etherscan(val apiBaseUrl: String, val txBaseUrl: String, val apiKeys: List<String>) : SourceType()
}

companion object {
private fun etherscan(apiSubdomain: String, txSubdomain: String?, apiKey: String): TransactionSource {
private fun etherscan(apiSubdomain: String, txSubdomain: String?, apiKeys: List<String>): TransactionSource {
return TransactionSource(
"etherscan.io",
SourceType.Etherscan("https://$apiSubdomain.etherscan.io", "https://${txSubdomain?.let { "$it." } ?: ""}etherscan.io", apiKey)
SourceType.Etherscan("https://$apiSubdomain.etherscan.io", "https://${txSubdomain?.let { "$it." } ?: ""}etherscan.io", apiKeys)
)
}

fun ethereumEtherscan(apiKey: String): TransactionSource {
return etherscan("api", null, apiKey)
fun ethereumEtherscan(apiKeys: List<String>): TransactionSource {
return etherscan("api", null, apiKeys)
}

fun goerliEtherscan(apiKey: String): TransactionSource {
return etherscan("api-goerli", "goerli", apiKey)
fun goerliEtherscan(apiKeys: List<String>): TransactionSource {
return etherscan("api-goerli", "goerli", apiKeys)
}

fun bscscan(apiKey: String): TransactionSource {
fun bscscan(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"bscscan.com",
SourceType.Etherscan("https://api.bscscan.com", "https://bscscan.com", apiKey)
SourceType.Etherscan("https://api.bscscan.com", "https://bscscan.com", apiKeys)
)
}

fun polygonscan(apiKey: String): TransactionSource {
fun polygonscan(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"polygonscan.com",
SourceType.Etherscan("https://api.polygonscan.com", "https://polygonscan.com", apiKey)
SourceType.Etherscan("https://api.polygonscan.com", "https://polygonscan.com", apiKeys)
)
}

fun optimisticEtherscan(apiKey: String): TransactionSource {
fun optimisticEtherscan(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"optimistic.etherscan.io",
SourceType.Etherscan("https://api-optimistic.etherscan.io", "https://optimistic.etherscan.io", apiKey)
SourceType.Etherscan("https://api-optimistic.etherscan.io", "https://optimistic.etherscan.io", apiKeys)
)
}

fun arbiscan(apiKey: String): TransactionSource {
fun arbiscan(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"arbiscan.io",
SourceType.Etherscan("https://api.arbiscan.io", "https://arbiscan.io", apiKey)
SourceType.Etherscan("https://api.arbiscan.io", "https://arbiscan.io", apiKeys)
)
}

fun snowtrace(apiKey: String): TransactionSource {
fun snowtrace(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"snowtrace.io",
SourceType.Etherscan("https://api.snowtrace.io", "https://snowtrace.io", apiKey)
SourceType.Etherscan("https://api.snowtrace.io", "https://snowtrace.io", apiKeys)
)
}

fun gnosis(apiKey: String): TransactionSource {
fun gnosis(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"gnosisscan.io",
SourceType.Etherscan("https://api.gnosisscan.io", "https://gnosisscan.io", apiKey)
SourceType.Etherscan("https://api.gnosisscan.io", "https://gnosisscan.io", apiKeys)
)
}

fun fantom(apiKey: String): TransactionSource {
fun fantom(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"ftmscan.com",
SourceType.Etherscan("https://api.ftmscan.com", "https://ftmscan.com", apiKey)
SourceType.Etherscan("https://api.ftmscan.com", "https://ftmscan.com", apiKeys)
)
}

fun basescan(apiKey: String): TransactionSource {
fun basescan(apiKeys: List<String>): TransactionSource {
return TransactionSource(
"basescan.org",
SourceType.Etherscan("https://api.basescan.org", "https://basescan.org", apiKey)
SourceType.Etherscan("https://api.basescan.org", "https://basescan.org", apiKeys)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import io.horizontalsystems.ethereumkit.core.retryWhenError
import io.horizontalsystems.ethereumkit.core.toHexString
import io.horizontalsystems.ethereumkit.models.Address
import io.reactivex.Single
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
Expand All @@ -22,8 +20,10 @@ import java.util.logging.Logger

class EtherscanService(
baseUrl: String,
private val apiKey: String
private val apiKeys: List<String>
) {
private val apiKeysSize = apiKeys.size
private var apiKeyIndex = 0

private val logger = Logger.getLogger("EtherscanService")

Expand All @@ -32,21 +32,27 @@ class EtherscanService(
private val gson: Gson

init {
val loggingInterceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
logger.info(message)
}
}).setLevel(HttpLoggingInterceptor.Level.BASIC)
val loggingInterceptor = HttpLoggingInterceptor {
logger.info(it)
}.setLevel(HttpLoggingInterceptor.Level.BASIC)

val httpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.addInterceptor(Interceptor { chain ->
val originalRequest: Request = chain.request()
val requestWithUserAgent: Request = originalRequest.newBuilder()
.addInterceptor { chain ->
val originalRequest = chain.request()
val originalUrl = originalRequest.url

val url = originalUrl.newBuilder()
.addQueryParameter("apikey", getNextApiKey())
.build()

val request = originalRequest.newBuilder()
.header("User-Agent", "Mobile App Agent")
.url(url)
.build()
chain.proceed(requestWithUserAgent)
})

chain.proceed(request)
}
.addInterceptor(loggingInterceptor)

gson = GsonBuilder()
.setLenient()
Expand All @@ -62,12 +68,17 @@ class EtherscanService(
service = retrofit.create(EtherscanServiceAPI::class.java)
}

private fun getNextApiKey(): String {
if (apiKeyIndex >= apiKeysSize) apiKeyIndex = 0

return apiKeys[apiKeyIndex++]
}

fun getTransactionList(address: Address, startBlock: Long): Single<EtherscanResponse> {
return service.accountApi(
action = "txlist",
address = address.hex,
startBlock = startBlock,
apiKey = apiKey
).map {
parseResponse(it)
}.retryWhenError(RequestError.RateLimitExceed::class)
Expand All @@ -78,7 +89,6 @@ class EtherscanService(
action = "txlistinternal",
address = address.hex,
startBlock = startBlock,
apiKey = apiKey
).map {
parseResponse(it)
}.retryWhenError(RequestError.RateLimitExceed::class)
Expand All @@ -89,7 +99,6 @@ class EtherscanService(
action = "tokentx",
address = address.hex,
startBlock = startBlock,
apiKey = apiKey
).map {
parseResponse(it)
}.retryWhenError(RequestError.RateLimitExceed::class)
Expand All @@ -99,7 +108,6 @@ class EtherscanService(
return service.accountApi(
action = "txlistinternal",
txHash = transactionHash.toHexString(),
apiKey = apiKey
).map {
parseResponse(it)
}.retryWhenError(RequestError.RateLimitExceed::class)
Expand All @@ -110,7 +118,6 @@ class EtherscanService(
action = "tokennfttx",
address = address.hex,
startBlock = startBlock,
apiKey = apiKey
).map {
parseResponse(it)
}.retryWhenError(RequestError.RateLimitExceed::class)
Expand All @@ -121,7 +128,6 @@ class EtherscanService(
action = "token1155tx",
address = address.hex,
startBlock = startBlock,
apiKey = apiKey
).map {
parseResponse(it)
}.retryWhenError(RequestError.RateLimitExceed::class)
Expand Down Expand Up @@ -163,8 +169,7 @@ class EtherscanService(
@Query("txhash") txHash: String? = null,
@Query("startblock") startBlock: Long? = null,
@Query("endblock") endBlock: Long? = null,
@Query("sort") sort: String? = "desc",
@Query("apikey") apiKey: String
@Query("sort") sort: String? = "desc"
): Single<JsonElement>
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Tue Apr 19 11:44:39 KGT 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

0 comments on commit 0a02ad0

Please sign in to comment.