Skip to content

Commit

Permalink
Add terra IBC, WASM tokens (#1447)
Browse files Browse the repository at this point in the history
  • Loading branch information
yvebe authored Dec 4, 2024
1 parent 6267a52 commit 3e7994e
Show file tree
Hide file tree
Showing 12 changed files with 1,981 additions and 1,542 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.vultisig.wallet.data.chains.helpers.EvmHelper
import com.vultisig.wallet.data.chains.helpers.PolkadotHelper
import com.vultisig.wallet.data.chains.helpers.SolanaHelper
import com.vultisig.wallet.data.chains.helpers.THORChainSwaps
import com.vultisig.wallet.data.chains.helpers.TerraHelper
import com.vultisig.wallet.data.chains.helpers.UtxoHelper
import com.vultisig.wallet.data.common.md5
import com.vultisig.wallet.data.common.toHexBytes
Expand Down Expand Up @@ -355,15 +356,22 @@ internal class KeysignViewModel(
return thorHelper.getSignedTransaction(keysignPayload, signatures)
}

Chain.GaiaChain, Chain.Kujira, Chain.Dydx, Chain.Osmosis,
Chain.TerraClassic, Chain.Terra, Chain.Noble -> {
Chain.GaiaChain, Chain.Kujira, Chain.Dydx, Chain.Osmosis, Chain.Noble -> {
return CosmosHelper(
coinType = chain.coinType,
denom = chain.feeUnit,
gasLimit = CosmosHelper.getChainGasLimit(chain),
).getSignedTransaction(keysignPayload, signatures)
}

Chain.TerraClassic, Chain.Terra -> {
return TerraHelper(
coinType = chain.coinType,
denom = chain.feeUnit,
gasLimit = CosmosHelper.getChainGasLimit(chain),
).getSignedTransaction(keysignPayload, signatures)
}

Chain.Solana -> {
val solanaHelper = SolanaHelper(vault.pubKeyEDDSA)
return solanaHelper.getSignedTransaction(keysignPayload, signatures)
Expand Down
45 changes: 44 additions & 1 deletion data/src/main/kotlin/com/vultisig/wallet/data/api/CosmosApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.vultisig.wallet.data.api

import com.vultisig.wallet.data.api.models.cosmos.CosmosBalance
import com.vultisig.wallet.data.api.models.cosmos.CosmosBalanceResponse
import com.vultisig.wallet.data.api.models.cosmos.CosmosIbcDenomTraceDenomTraceJson
import com.vultisig.wallet.data.api.models.cosmos.CosmosIbcDenomTraceJson
import com.vultisig.wallet.data.api.models.cosmos.CosmosTHORChainAccountResponse
import com.vultisig.wallet.data.api.models.cosmos.CosmosTransactionBroadcastResponse
import com.vultisig.wallet.data.api.models.cosmos.THORChainAccountValue
Expand All @@ -15,14 +17,21 @@ import io.ktor.client.request.setBody
import io.ktor.client.statement.bodyAsText
import io.ktor.http.ContentType
import io.ktor.http.contentType
import io.ktor.util.encodeBase64
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import timber.log.Timber
import javax.inject.Inject

interface CosmosApi {
suspend fun getBalance(address: String): List<CosmosBalance>
suspend fun getAccountNumber(address: String): THORChainAccountValue
suspend fun broadcastTransaction(tx: String): String?
suspend fun getWasmTokenBalance(address: String, contractAddress: String): CosmosBalance
suspend fun getIbcDenomTraces(contractAddress: String): CosmosIbcDenomTraceDenomTraceJson
suspend fun getLatestBlock(): String
}

interface CosmosApiFactory {
Expand All @@ -46,7 +55,7 @@ internal class CosmosApiFactoryImp @Inject constructor(
else -> throw IllegalArgumentException("Unsupported chain $chain")
}

return CosmosApiImp(httpClient, apiUrl, json, cosmosThorChainResponseSerializer,)
return CosmosApiImp(httpClient, apiUrl, json, cosmosThorChainResponseSerializer)
}
}

Expand Down Expand Up @@ -105,4 +114,38 @@ internal class CosmosApiImp(
throw e
}
}

override suspend fun getWasmTokenBalance(address: String, contractAddress: String): CosmosBalance {
val payload = "{\"balance\":{\"address\":\"$address\"}}".encodeBase64()

return CosmosBalance(
denom = contractAddress,
amount = httpClient
.get("$rpcEndpoint/cosmwasm/wasm/v1/contract/$contractAddress/smart/$payload")
.body<JsonObject>()["data"]
?.jsonObject
?.get("balance")
?.jsonPrimitive
?.content ?: "0"
)
}

override suspend fun getIbcDenomTraces(contractAddress: String): CosmosIbcDenomTraceDenomTraceJson {
val hash = contractAddress.removePrefix("ibc/")
return httpClient.get("$rpcEndpoint/ibc/apps/transfer/v1/denom_traces/$hash")
.body<CosmosIbcDenomTraceJson>()
.denomTrace!!
}

override suspend fun getLatestBlock(): String {
return httpClient.get("$rpcEndpoint/cosmos/base/tendermint/v1beta1/blocks/latest")
.body<JsonObject>()
.jsonObject["block"]
?.jsonObject
?.get("header")
?.jsonObject
?.get("height")
?.jsonPrimitive
?.content ?: "0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.vultisig.wallet.data.api.models.cosmos

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class CosmosIbcDenomTraceJson(
@SerialName("denom_trace")
val denomTrace: CosmosIbcDenomTraceDenomTraceJson?,
)

@Serializable
data class CosmosIbcDenomTraceDenomTraceJson(
@SerialName("path")
val path: String,
@SerialName("base_denom")
val baseDenom: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,22 @@ object SigningHelper {
utxo.getPreSignedImageHash(payload)
}

Chain.GaiaChain, Chain.Dydx, Chain.Kujira, Chain.Osmosis,
Chain.Terra, Chain.TerraClassic, Chain.Noble -> {
Chain.GaiaChain, Chain.Dydx, Chain.Kujira, Chain.Osmosis, Chain.Noble -> {
CosmosHelper(
coinType = chain.coinType,
denom = chain.feeUnit,
gasLimit = CosmosHelper.getChainGasLimit(chain),
).getPreSignedImageHash(payload)
}

Chain.Terra, Chain.TerraClassic -> {
TerraHelper(
coinType = chain.coinType,
denom = chain.feeUnit,
gasLimit = CosmosHelper.getChainGasLimit(chain),
).getPreSignedImageHash(payload)
}

Chain.MayaChain -> {
val mayaChainHelper = ThorChainHelper.maya(vault.pubKeyECDSA, vault.hexChainCode)
mayaChainHelper.getPreSignedImageHash(payload)
Expand Down
Loading

0 comments on commit 3e7994e

Please sign in to comment.