Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/app main hyuk dev #663

Merged
merged 16 commits into from
Jan 23, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[APP-1075] init gno-testnet main token send
  • Loading branch information
Kwonhyukjoon committed Jan 9, 2025
commit b6079a87c6241953b924df33be957e7996cba8b2
6 changes: 4 additions & 2 deletions app/src/main/java/wannabit/io/cosmostaion/chain/BaseChain.kt
Original file line number Diff line number Diff line change
@@ -43,6 +43,7 @@ import wannabit.io.cosmostaion.chain.cosmosClass.ChainFetchAi60Old
import wannabit.io.cosmostaion.chain.cosmosClass.ChainFetchAi60Secp
import wannabit.io.cosmostaion.chain.cosmosClass.ChainFinschia
import wannabit.io.cosmostaion.chain.cosmosClass.ChainFirma
import wannabit.io.cosmostaion.chain.testnetClass.ChainGnoTestnet
import wannabit.io.cosmostaion.chain.cosmosClass.ChainGovgen
import wannabit.io.cosmostaion.chain.cosmosClass.ChainGravityBridge
import wannabit.io.cosmostaion.chain.cosmosClass.ChainInjective
@@ -604,8 +605,8 @@ fun allChains(): MutableList<BaseChain> {
chains.add(ChainCoreum())
chains.add(ChainCronos())
chains.add(ChainCryptoorg())
chains.add(ChainDHealth())
chains.add(ChainDesmos())
chains.add(ChainDHealth())
chains.add(ChainDoravota())
chains.add(ChainDungeon())
chains.add(ChainDydx())
@@ -704,6 +705,7 @@ fun allChains(): MutableList<BaseChain> {
chains.add(ChainBitcoin44Testnet())
chains.add(ChainBitcoin49Testnet())
chains.add(ChainBitcoin84Testnet())
chains.add(ChainGnoTestnet())
chains.add(ChainInitiaTestnet())
chains.add(ChainMantraTestnet())
chains.add(ChainNeutronTestnet())
@@ -745,6 +747,6 @@ val EVM_BASE_FEE = BigDecimal("588000000000000")

enum class PubKeyType { ETH_KECCAK256, COSMOS_SECP256K1, BERA_SECP256K1, SUI_ED25519, BTC_LEGACY, BTC_NESTED_SEGWIT, BTC_NATIVE_SEGWIT, NONE }

enum class CosmosEndPointType { UNKNOWN, USE_GRPC, USE_LCD }
enum class CosmosEndPointType { UNKNOWN, USE_GRPC, USE_LCD, USE_RPC }

enum class FetchState { IDLE, BUSY, SUCCESS, FAIL }
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package wannabit.io.cosmostaion.chain.testnetClass

import android.os.Parcelable
import com.google.common.collect.ImmutableList
import kotlinx.parcelize.Parcelize
import org.bitcoinj.crypto.ChildNumber
import wannabit.io.cosmostaion.R
import wannabit.io.cosmostaion.chain.AccountKeyType
import wannabit.io.cosmostaion.chain.BaseChain
import wannabit.io.cosmostaion.chain.CosmosEndPointType
import wannabit.io.cosmostaion.chain.PubKeyType

@Parcelize
class ChainGnoTestnet : BaseChain(), Parcelable {

override var name: String = "Gno Testnet"
override var tag: String = "gno118_T"
override var logo: Int = R.drawable.chain_gno_testnet
override var isTestnet: Boolean = true
override var apiName: String = "gno-testnet"

override var accountKeyType = AccountKeyType(PubKeyType.COSMOS_SECP256K1, "m/44'/118'/0'/0/X")
override var setParentPath: List<ChildNumber> = ImmutableList.of(
ChildNumber(44, true), ChildNumber(118, true), ChildNumber.ZERO_HARDENED, ChildNumber.ZERO
)

override var cosmosEndPointType: CosmosEndPointType? = CosmosEndPointType.USE_RPC
override var stakeDenom: String = "ugnot"
override var accountPrefix: String = "g"
override var mainUrl: String = "https://rpc.test5.gno.land"
}
14 changes: 14 additions & 0 deletions app/src/main/java/wannabit/io/cosmostaion/common/Extensions.kt
Original file line number Diff line number Diff line change
@@ -893,3 +893,17 @@ fun com.initia.mstaking.v1.StakingProto.Validator.isActiveValidator(chain: Chain
}
}

fun String.regexWithNumberAndChar(): Pair<String, String> {
val regex = Regex("[0-9]*\\.?[0-9]*")
val matchResult = regex.find(this)
return if (matchResult != null) {
val amount = matchResult.value
val denomIndex = amount.length
val denom = this.substring(denomIndex)
Pair(denom, amount)

} else {
Pair("", "")
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package wannabit.io.cosmostaion.data.model.req

import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName


data class SignPayload(
val chain_id: String,
val account_number: String,
val sequence: String,
val fee: Fee,
val msgs: MutableList<Msgs>?,
val memo: String? = ""
) {
fun toJson(): String {
val gson = GsonBuilder().setPrettyPrinting().create()
return gson.toJson(this)
}
}

data class Fee(
val gas_wanted: String,
val gas_fee: String
)

data class Msgs(
@SerializedName("@type")
val type: String,
val from_address: String,
val to_address: String,
val amount: String
)
Original file line number Diff line number Diff line change
@@ -2,19 +2,20 @@ package wannabit.io.cosmostaion.data.repository.tx

import com.cosmos.base.abci.v1beta1.AbciProto
import com.cosmos.tx.v1beta1.TxProto.Fee
import com.gno.bank.BankProto.MsgSend
import com.google.gson.JsonObject
import com.ibc.applications.transfer.v1.TxProto.MsgTransfer
import io.grpc.ManagedChannel
import org.web3j.protocol.Web3j
import wannabit.io.cosmostaion.chain.BaseChain
import wannabit.io.cosmostaion.chain.fetcher.SuiFetcher
import wannabit.io.cosmostaion.chain.majorClass.ChainBitCoin84
import wannabit.io.cosmostaion.sign.BitCoinJS
import wannabit.io.cosmostaion.data.model.req.LFee
import wannabit.io.cosmostaion.data.model.req.Msg
import wannabit.io.cosmostaion.data.model.res.LegacyRes
import wannabit.io.cosmostaion.data.model.res.NetworkResult
import wannabit.io.cosmostaion.data.model.res.Token
import wannabit.io.cosmostaion.sign.BitCoinJS
import wannabit.io.cosmostaion.ui.tx.genTx.SendAssetType

interface TxRepository {
@@ -116,6 +117,10 @@ interface TxRepository {
selectedChain: BaseChain
): String

suspend fun broadcastRpcTx(
msgSend: MsgSend, fee: Fee?, memo: String, selectedChain: BaseChain
): AbciProto.TxResponse?

suspend fun broadcastOktTx(
msgs: MutableList<Msg>, fee: LFee, memo: String, selectedChain: BaseChain
): LegacyRes?
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import com.cosmos.tx.v1beta1.ServiceProto
import com.cosmos.tx.v1beta1.ServiceProto.BroadcastMode
import com.cosmos.tx.v1beta1.TxProto.Fee
import com.fasterxml.jackson.databind.ObjectMapper
import com.gno.bank.BankProto.MsgSend
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.protobuf.ByteString
@@ -49,6 +50,7 @@ import wannabit.io.cosmostaion.chain.majorClass.SUI_MAIN_DENOM
import wannabit.io.cosmostaion.common.BaseConstant.ICNS_OSMOSIS_ADDRESS
import wannabit.io.cosmostaion.common.BaseConstant.NS_ARCHWAY_ADDRESS
import wannabit.io.cosmostaion.common.BaseConstant.NS_STARGZE_ADDRESS
import wannabit.io.cosmostaion.common.formatJsonString
import wannabit.io.cosmostaion.common.jsonRpcResponse
import wannabit.io.cosmostaion.common.percentile
import wannabit.io.cosmostaion.common.safeApiCall
@@ -146,7 +148,25 @@ class TxRepositoryImpl : TxRepository {
override suspend fun auth(
managedChannel: ManagedChannel?, chain: BaseChain
) {
return if (chain.cosmosFetcher()?.endPointType(chain) == CosmosEndPointType.USE_GRPC) {
return if (chain.cosmosFetcher()?.endPointType(chain) == CosmosEndPointType.USE_RPC) {
val authRequest = JsonRpcRequest(
method = "abci_query",
params = listOf("auth/accounts/${chain.address}", "", "0", true)
)
val authResponse = jsonRpcResponse(chain.mainUrl, authRequest)
val jsonResponse = Gson().fromJson(
authResponse.body?.string(), JsonObject::class.java
)
val data =
jsonResponse["result"].asJsonObject["response"].asJsonObject["ResponseBase"].asJsonObject["Data"].asString
val decodeData = formatJsonString(String(Base64.decode(data)))
val dataJson = Gson().fromJson(decodeData, JsonObject::class.java)
val accountData = dataJson["BaseAccount"].asJsonObject
chain.cosmosFetcher()?.cosmosAccountNumber =
accountData["account_number"].asString.toLong()
chain.cosmosFetcher()?.cosmosSequence = accountData["sequence"].asString.toLong()

} else if (chain.cosmosFetcher()?.endPointType(chain) == CosmosEndPointType.USE_GRPC) {
val stub = QueryGrpc.newBlockingStub(managedChannel)
.withDeadlineAfter(duration, TimeUnit.SECONDS)
val request = QueryAccountRequest.newBuilder().setAddress(chain.address).build()
@@ -1326,6 +1346,30 @@ class TxRepositoryImpl : TxRepository {
}
}

override suspend fun broadcastRpcTx(
msgSend: MsgSend, fee: Fee?, memo: String, selectedChain: BaseChain
): TxResponse? {
return try {
val broadcastTx = Signer.signRpcBroadcastTx(msgSend, fee, memo, selectedChain)
val txByte = Base64.toBase64String(broadcastTx.toByteArray())
val broadcastRequest = JsonRpcRequest(
method = "broadcast_tx_async", params = listOf(txByte)
)
val broadcastResponse = jsonRpcResponse(selectedChain.mainUrl, broadcastRequest)
val broadcastJsonObject = Gson().fromJson(
broadcastResponse.body?.string(), JsonObject::class.java
)
val result = broadcastJsonObject["result"].asJsonObject
return if (result["error"].isJsonNull) {
TxResponse.newBuilder().setCode(0).setTxhash(result["hash"].asString).build()
} else {
TxResponse.newBuilder().setCode(-1).setTxhash(result["hash"].asString).build()
}
} catch (e: Exception) {
null
}
}

override suspend fun broadcastOktTx(
msgs: MutableList<Msg>, fee: LFee, memo: String, selectedChain: BaseChain
): LegacyRes? {
@@ -1910,8 +1954,7 @@ class TxRepositoryImpl : TxRepository {
val sendRawTransactionRequest = JsonRpcRequest(
method = "sendrawtransaction", params = listOf(txHex)
)
val sendRawTransactionResponse =
jsonRpcResponse(chain.mainUrl, sendRawTransactionRequest)
val sendRawTransactionResponse = jsonRpcResponse(chain.mainUrl, sendRawTransactionRequest)
val sendRawTransactionJsonObject = Gson().fromJson(
sendRawTransactionResponse.body?.string(), JsonObject::class.java
)
Original file line number Diff line number Diff line change
@@ -182,4 +182,6 @@ interface WalletRepository {
): NetworkResult<MutableList<JsonObject>>

suspend fun bitBalance(chain: ChainBitCoin84): NetworkResult<JsonObject>

suspend fun rpcAuth(chain: BaseChain): NetworkResult<okhttp3.Response>
}
Original file line number Diff line number Diff line change
@@ -55,7 +55,6 @@ import wannabit.io.cosmostaion.chain.majorClass.ChainSui
import wannabit.io.cosmostaion.chain.testnetClass.ChainInitiaTestnet
import wannabit.io.cosmostaion.common.jsonRpcResponse
import wannabit.io.cosmostaion.common.safeApiCall
import wannabit.io.cosmostaion.data.api.RetrofitInstance.baseApi
import wannabit.io.cosmostaion.data.api.RetrofitInstance.bitApi
import wannabit.io.cosmostaion.data.api.RetrofitInstance.ecoApi
import wannabit.io.cosmostaion.data.api.RetrofitInstance.lcdApi
@@ -306,9 +305,11 @@ class WalletRepositoryImpl : WalletRepository {
return if (chain.cosmosFetcher?.endPointType(chain) == CosmosEndPointType.USE_GRPC) {
channel?.let { managedChannel ->
val pageRequest = PaginationProto.PageRequest.newBuilder().setLimit(500).build()
val stub = newBlockingStub(managedChannel).withDeadlineAfter(duration, TimeUnit.SECONDS)
val request = com.cosmos.staking.v1beta1.QueryProto.QueryValidatorsRequest.newBuilder()
.setPagination(pageRequest).setStatus("BOND_STATUS_UNBONDED").build()
val stub =
newBlockingStub(managedChannel).withDeadlineAfter(duration, TimeUnit.SECONDS)
val request =
com.cosmos.staking.v1beta1.QueryProto.QueryValidatorsRequest.newBuilder()
.setPagination(pageRequest).setStatus("BOND_STATUS_UNBONDED").build()
safeApiCall(Dispatchers.IO) {
stub.validators(request).validatorsList
}
@@ -333,9 +334,11 @@ class WalletRepositoryImpl : WalletRepository {
return if (chain.cosmosFetcher?.endPointType(chain) == CosmosEndPointType.USE_GRPC) {
channel?.let { managedChannel ->
val pageRequest = PaginationProto.PageRequest.newBuilder().setLimit(500).build()
val stub = newBlockingStub(managedChannel).withDeadlineAfter(duration, TimeUnit.SECONDS)
val request = com.cosmos.staking.v1beta1.QueryProto.QueryValidatorsRequest.newBuilder()
.setPagination(pageRequest).setStatus("BOND_STATUS_UNBONDING").build()
val stub =
newBlockingStub(managedChannel).withDeadlineAfter(duration, TimeUnit.SECONDS)
val request =
com.cosmos.staking.v1beta1.QueryProto.QueryValidatorsRequest.newBuilder()
.setPagination(pageRequest).setStatus("BOND_STATUS_UNBONDING").build()
safeApiCall(Dispatchers.IO) {
stub.validators(request).validatorsList
}
@@ -525,8 +528,7 @@ class WalletRepositoryImpl : WalletRepository {
}

override suspend fun initiaBondedValidator(
channel: ManagedChannel?,
chain: ChainInitiaTestnet
channel: ManagedChannel?, chain: ChainInitiaTestnet
): NetworkResult<MutableList<com.initia.mstaking.v1.StakingProto.Validator>> {
return if (chain.initiaFetcher()?.endPointType(chain) == CosmosEndPointType.USE_GRPC) {
val pageRequest = PaginationProto.PageRequest.newBuilder().setLimit(500).build()
@@ -540,14 +542,14 @@ class WalletRepositoryImpl : WalletRepository {

} else {
safeApiCall(Dispatchers.IO) {
lcdApi(chain).lcdInitiaBondedValidatorInfo().initiaValidators(com.initia.mstaking.v1.StakingProto.BondStatus.BOND_STATUS_BONDED)
lcdApi(chain).lcdInitiaBondedValidatorInfo()
.initiaValidators(com.initia.mstaking.v1.StakingProto.BondStatus.BOND_STATUS_BONDED)
}
}
}

override suspend fun initiaUnBondedValidator(
channel: ManagedChannel?,
chain: ChainInitiaTestnet
channel: ManagedChannel?, chain: ChainInitiaTestnet
): NetworkResult<MutableList<com.initia.mstaking.v1.StakingProto.Validator>> {
return if (chain.initiaFetcher()?.endPointType(chain) == CosmosEndPointType.USE_GRPC) {
val pageRequest = PaginationProto.PageRequest.newBuilder().setLimit(500).build()
@@ -560,14 +562,14 @@ class WalletRepositoryImpl : WalletRepository {
}
} else {
safeApiCall(Dispatchers.IO) {
lcdApi(chain).lcdInitiaUnBondedValidatorInfo().initiaValidators(com.initia.mstaking.v1.StakingProto.BondStatus.BOND_STATUS_UNBONDED)
lcdApi(chain).lcdInitiaUnBondedValidatorInfo()
.initiaValidators(com.initia.mstaking.v1.StakingProto.BondStatus.BOND_STATUS_UNBONDED)
}
}
}

override suspend fun initiaUnBondingValidator(
channel: ManagedChannel?,
chain: ChainInitiaTestnet
channel: ManagedChannel?, chain: ChainInitiaTestnet
): NetworkResult<MutableList<com.initia.mstaking.v1.StakingProto.Validator>> {
return if (chain.initiaFetcher()?.endPointType(chain) == CosmosEndPointType.USE_GRPC) {
val pageRequest = PaginationProto.PageRequest.newBuilder().setLimit(500).build()
@@ -580,7 +582,8 @@ class WalletRepositoryImpl : WalletRepository {
}
} else {
safeApiCall(Dispatchers.IO) {
lcdApi(chain).lcdInitiaUnBondingValidatorInfo().initiaValidators(com.initia.mstaking.v1.StakingProto.BondStatus.BOND_STATUS_UNBONDING)
lcdApi(chain).lcdInitiaUnBondingValidatorInfo()
.initiaValidators(com.initia.mstaking.v1.StakingProto.BondStatus.BOND_STATUS_UNBONDING)
}
}
}
@@ -886,4 +889,13 @@ class WalletRepositoryImpl : WalletRepository {
bitApi(chain).bitBalance(chain.mainAddress)
}
}

override suspend fun rpcAuth(chain: BaseChain): NetworkResult<okhttp3.Response> {
val authRequest = JsonRpcRequest(
method = "abci_query", params = listOf("auth/accounts/${chain.address}", "", "0", false)
)
return safeApiCall(Dispatchers.IO) {
jsonRpcResponse(chain.mainUrl, authRequest)
}
}
}
Loading