Skip to content

Commit

Permalink
add decimal
Browse files Browse the repository at this point in the history
  • Loading branch information
hoanganhtuan95ptit committed Feb 16, 2023
1 parent 1969f4b commit f1da7a9
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 27 deletions.
111 changes: 85 additions & 26 deletions app/src/androidTest/java/com/one/web3/ktx/Web3Test.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,31 @@ import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
class Web3Test {

private var web3: Web3? = null

private var retrofit: Retrofit? = null

private var chainList: List<Chain>? = null

@Test
fun testBalanceNative() = runBlocking {
private fun getWeb3(retrofit: Retrofit): Web3 {

if (web3 != null) {

return web3!!
}

return Web3(retrofit).apply {

web3 = this
}
}

private fun getRetrofit(): Retrofit {

if (retrofit != null) {

return retrofit!!
}

val okHttpClient = OkHttpClient
.Builder()
Expand All @@ -38,58 +59,96 @@ class Web3Test {
.build()


val retrofit = Retrofit.Builder()
return Retrofit.Builder()
.baseUrl("https://github.com/hoanganhtuan95ptit/Web3Ktx/")
.addConverterFactory(JacksonConverterFactory.create())
.client(okHttpClient)
.build()
.build().apply {

retrofit = this
}
}

private suspend fun getChainList(retrofit: Retrofit): List<Chain> {

val list = chainList ?: retrofit.create(ChainService::class.java).call("https://raw.githubusercontent.com/hoanganhtuan95ptit/config/main/chain/chains.json").apply {
if (chainList != null) {

return chainList!!
}

return retrofit.create(ChainService::class.java).call("https://raw.githubusercontent.com/hoanganhtuan95ptit/config/main/chain/chains.json").apply {

chainList = this
}
}

@Test
fun testDecimalMulti() = runBlocking {

list.map { chain ->
val retrofit = getRetrofit()

val list = getChainList(retrofit)


val tokens = listOf("0x0000000000085d4780b73119b644ae5ecd22b376", "0x028171bca77440897b824ca71d1c56cac55b68a3")

list.first().let { chain ->

val rpcUrls = chain.urls.filter { it.type == "PRC" }.sortedByDescending { it.priority }.map { it.url }

if (rpcUrls.isEmpty()) return@map
if (rpcUrls.isEmpty()) return@let

val balance = Web3(retrofit).runCatching { balanceNative("0x8d61ab7571b117644a52240456df66ef846cd999", chain.id, rpcUrls) }.getOrNull()
val balance = getWeb3(retrofit).runCatching {

Log.d("tuanha", "testBalanceNative: chainName:${chain.name} chainId:${chain.id} - balance:$balance")
decimalMulti(tokens, "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696", chain.id, rpcUrls)
}.getOrElse {

Log.d("tuanha", "testDecimalMulti: ", it)
null
}

Log.d("tuanha", "testDecimalMulti: chainName:${chain.name} chainId:${chain.id} - balance:${balance.toJson()}")
}

Unit
}

@Test
fun testBalanceMulti() = runBlocking {
fun testBalanceNative() = runBlocking {

val okHttpClient = OkHttpClient
.Builder()
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.connectTimeout(20, TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().setLevel(if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE))
.hostnameVerifier { _, _ -> true }
.build()
val retrofit = getRetrofit()

val list = getChainList(retrofit)

val retrofit = Retrofit.Builder()
.baseUrl("https://github.com/hoanganhtuan95ptit/Web3Ktx/")
.addConverterFactory(JacksonConverterFactory.create())
.client(okHttpClient)
.build()

list.map { chain ->

val rpcUrls = chain.urls.filter { it.type == "PRC" }.sortedByDescending { it.priority }.map { it.url }

val list = chainList ?: retrofit.create(ChainService::class.java).call("https://raw.githubusercontent.com/hoanganhtuan95ptit/config/main/chain/chains.json").apply {
if (rpcUrls.isEmpty()) return@map

chainList = this
val balance = getWeb3(retrofit).runCatching {

balanceNative("0x8d61ab7571b117644a52240456df66ef846cd999", chain.id, rpcUrls)
}.getOrElse {

Log.d("tuanha", "testBalanceNative: ", it)
null
}

Log.d("tuanha", "testBalanceNative: chainName:${chain.name} chainId:${chain.id} - balance:$balance")
}

Unit
}

@Test
fun testBalanceMulti() = runBlocking {

val retrofit = getRetrofit()

val list = getChainList(retrofit)


val tokens = listOf("0x0000000000085d4780b73119b644ae5ecd22b376", "0x028171bca77440897b824ca71d1c56cac55b68a3")

Expand All @@ -101,7 +160,7 @@ class Web3Test {

if (rpcUrls.isEmpty()) return@let

val balance = Web3(retrofit).runCatching {
val balance = getWeb3(retrofit).runCatching {

balanceMulti(tokens, wallets, "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696", chain.id, rpcUrls)
}.getOrElse {
Expand Down
15 changes: 14 additions & 1 deletion web3/src/main/java/com/one/web3/Web3.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import com.one.web3.task.decimal.DecimalCallTask
import com.one.web3.task.decimal.DecimalEvmCallTask
import com.one.web3.task.decimal.DecimalParam
import com.one.web3.task.decimal.DecimalSolCallTask
import com.one.web3.task.decimalmulti.DecimalMultiEvmCallTask
import com.one.web3.task.decimalmulti.DecimalMultiParam
import com.one.web3.task.decimalmulti.DecimalMultiTask
import com.one.web3.task.gasprice.GasPriceCallTask
import com.one.web3.task.gasprice.GasPriceEvmCallTask
import com.one.web3.task.gasprice.GasPriceParam
Expand All @@ -25,12 +28,14 @@ import retrofit2.Retrofit
import java.math.BigDecimal
import java.math.BigInteger

class Web3(private val retrofit: Retrofit, private val tasks: List<Web3Task<*, *>> = emptyList()) {
open class Web3(private val retrofit: Retrofit, private val tasks: List<Web3Task<*, *>> = emptyList()) {

val taskList: List<Web3Task<*, *>> by lazy {

arrayListOf<Web3Task<*, *>>().apply {

add(DecimalMultiEvmCallTask(retrofit))

add(BalanceMultiEvmCallTask(retrofit))

add(BalanceEvmCallTask(retrofit))
Expand All @@ -54,11 +59,18 @@ class Web3(private val retrofit: Retrofit, private val tasks: List<Web3Task<*, *
return execute<DecimalParam, Int, DecimalCallTask>(DecimalParam(tokenAddress, chainId, rpcUrls))
}

suspend fun decimalMulti(tokenAddressList: List<String>, multiCallAddress: String, chainId: Long, rpcUrls: List<String>): Map<String, Int> {

return execute<DecimalMultiParam, Map<String, Int>, DecimalMultiTask>(DecimalMultiParam(tokenAddressList, multiCallAddress, chainId, rpcUrls))
}


suspend fun gasPrice(chainId: Long, rpcUrls: List<String>): BigInteger {

return execute<GasPriceParam, BigInteger, GasPriceCallTask>(GasPriceParam(chainId, rpcUrls))
}


suspend fun balance(tokenAddress: String, walletAddress: String, chainId: Long, rpcUrls: List<String>): BigDecimal {

return execute<BalanceParam, BigDecimal, BalanceTask>(BalanceParam(tokenAddress, walletAddress, chainId, rpcUrls))
Expand All @@ -69,6 +81,7 @@ class Web3(private val retrofit: Retrofit, private val tasks: List<Web3Task<*, *
return execute<BalanceMultiParam, Map<Pair<String, String>, BigDecimal>, BalanceMultiTask>(BalanceMultiParam(tokenAddressList, walletAddressList, multiCallAddress, chainId, rpcUrls))
}


suspend fun balanceNative(walletAddress: String, chainId: Long, rpcUrls: List<String>): BigInteger {

return execute<BalanceNativeParam, BigInteger, BalanceNativeTask>(BalanceNativeParam(walletAddress, chainId, rpcUrls))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.one.web3.task.decimalmulti

import com.one.web3.task.EvmMultiCallV2
import com.one.web3.task.decimal.functionDecimalEvmOf
import org.bouncycastle.util.encoders.Hex
import org.web3j.abi.FunctionEncoder
import org.web3j.abi.datatypes.Address
import org.web3j.abi.datatypes.DynamicBytes
import org.web3j.abi.datatypes.DynamicStruct
import org.web3j.utils.Numeric
import retrofit2.Retrofit

class DecimalMultiEvmCallTask(private val retrofit: Retrofit) : DecimalMultiTask, EvmMultiCallV2 {

override fun providerRetrofit(): Retrofit = retrofit

override suspend fun executeTask(param: DecimalMultiParam): Map<String, Int> {


val staticStruct = hashMapOf<String, DynamicStruct>()

param.tokenAddressList.map { tokenAddress ->

val function = functionDecimalEvmOf()

val encodeDataOfNameFunction = FunctionEncoder.encode(function)

val struct = DynamicStruct(Address(tokenAddress), DynamicBytes(Hex.decode(encodeDataOfNameFunction.substring(2).toByteArray())))

staticStruct.put(tokenAddress, struct)
}


val results = hashMapOf<String, Int>()

readMultiCall(param.multiCallAddress, staticStruct.values.toList(), param.rpcUrls).forEachIndexed { index, result ->

if (result.success.value != true) return@forEachIndexed

val key = staticStruct.keys.toList().getOrNull(index) ?: return@forEachIndexed

val value = Numeric.toBigInt(result.returnData.value).toInt()

results[key] = value
}


return results
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.one.web3.task.decimalmulti

import com.one.web3.Param
import com.one.web3.Web3Task

interface DecimalMultiTask : Web3Task<DecimalMultiParam, Map<String, Int>>

data class DecimalMultiParam(val tokenAddressList: List<String>, val multiCallAddress: String, override val chainId: Long, override val rpcUrls: List<String>) : Param(chainId, rpcUrls)

0 comments on commit f1da7a9

Please sign in to comment.