Skip to content

Commit a14887a

Browse files
authored
Merge pull request #650 from cosmostation/feature/APP-main_hyuk_dev
Feature/app main hyuk dev
2 parents 7a2bba0 + 8afde1b commit a14887a

File tree

87 files changed

+2801
-650
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+2801
-650
lines changed

app/build.gradle

+4-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ android {
2020
compileSdk 34
2121
buildToolsVersion = "30.0.3"
2222
applicationId "wannabit.io.cosmostaion"
23-
minSdkVersion 24
23+
minSdkVersion 26
2424
targetSdkVersion 34
2525
versionCode 312
2626
versionName "1.10.9"
@@ -155,7 +155,7 @@ dependencies {
155155
//qr
156156
implementation 'com.journeyapps:zxing-android-embedded:3.5.0'
157157
implementation 'com.budiyev.android:code-scanner:2.1.0'
158-
implementation 'org.mozilla:rhino:1.7.13'
158+
implementation 'org.mozilla:rhino:1.7.15'
159159

160160
//kotlin
161161
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.8.0'
@@ -192,4 +192,6 @@ dependencies {
192192
//coil
193193
implementation 'io.coil-kt:coil:1.2.0'
194194
implementation 'io.coil-kt:coil-svg:1.2.0'
195+
196+
implementation("androidx.javascriptengine:javascriptengine:1.0.0-beta01")
195197
}

app/src/main/assets/bitcoin.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src/main/java/wannabit/io/cosmostaion/chain/BaseChain.kt

+15-2
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,14 @@ import wannabit.io.cosmostaion.chain.evmClass.ChainOptimism
9797
import wannabit.io.cosmostaion.chain.evmClass.ChainPolygon
9898
import wannabit.io.cosmostaion.chain.evmClass.ChainXplaEvm
9999
import wannabit.io.cosmostaion.chain.evmClass.ChainZetaEvm
100+
import wannabit.io.cosmostaion.chain.majorClass.ChainBitCoin44
101+
import wannabit.io.cosmostaion.chain.majorClass.ChainBitCoin49
102+
import wannabit.io.cosmostaion.chain.majorClass.ChainBitCoin84
100103
import wannabit.io.cosmostaion.chain.majorClass.ChainSui
101104
import wannabit.io.cosmostaion.chain.testnetClass.ChainArtelaTestnet
105+
import wannabit.io.cosmostaion.chain.testnetClass.ChainBitcoin44Testnet
106+
import wannabit.io.cosmostaion.chain.testnetClass.ChainBitcoin49Testnet
107+
import wannabit.io.cosmostaion.chain.testnetClass.ChainBitcoin84Testnet
102108
import wannabit.io.cosmostaion.chain.testnetClass.ChainCosmosTestnet
103109
import wannabit.io.cosmostaion.chain.testnetClass.ChainMantraTestnet
104110
import wannabit.io.cosmostaion.chain.testnetClass.ChainNeutronTestnet
@@ -159,6 +165,7 @@ open class BaseChain : Parcelable {
159165

160166
open var mainAddress: String = ""
161167
open var mainUrl: String = ""
168+
open var rpcUrl: String = ""
162169

163170
open var fetched = false
164171
open var fetchedState = true
@@ -346,7 +353,7 @@ open class BaseChain : Parcelable {
346353
}
347354

348355
fun supportFeeMarket(): Boolean? {
349-
return if (getChainListParam()?.get("fee")?.asJsonObject?.get("feemarket")?.isJsonNull == true) {
356+
return if (getChainListParam()?.get("fee")?.asJsonObject?.get("feemarket") == null) {
350357
false
351358
} else {
352359
getChainListParam()?.get("fee")?.asJsonObject?.get("feemarket")?.asBoolean
@@ -474,7 +481,10 @@ open class BaseChain : Parcelable {
474481
}
475482

476483
fun allValue(isUsd: Boolean?): BigDecimal {
477-
if (this is ChainSui) {
484+
if (this is ChainBitCoin84) {
485+
return btcFetcher?.allAssetValue(isUsd) ?: BigDecimal.ZERO
486+
487+
} else if (this is ChainSui) {
478488
return suiFetcher?.allAssetValue(isUsd) ?: BigDecimal.ZERO
479489

480490
} else if (this is ChainOkt996Keccak) {
@@ -603,6 +613,9 @@ fun allChains(): MutableList<BaseChain> {
603613
chains.add(ChainMantraTestnet())
604614
chains.add(ChainNeutronTestnet())
605615
chains.add(ChainNillionTestnet())
616+
// chains.add(ChainBitcoin44Testnet())
617+
// chains.add(ChainBitcoin49Testnet())
618+
// chains.add(ChainBitcoin84Testnet())
606619

607620
chains.forEach { chain ->
608621
if (chain.chainIdCosmos.isEmpty()) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
package wannabit.io.cosmostaion.chain
2+
3+
import com.google.gson.Gson
4+
import com.google.gson.JsonObject
5+
import wannabit.io.cosmostaion.common.BaseData
6+
import wannabit.io.cosmostaion.common.jsonRpcResponse
7+
import wannabit.io.cosmostaion.data.model.req.JsonRpcRequest
8+
import java.math.BigDecimal
9+
import java.math.RoundingMode
10+
11+
class BtcFetcher(private val chain: BaseChain) : CosmosFetcher(chain) {
12+
13+
var btcBalances = BigDecimal.ZERO
14+
var btcPendingInput = BigDecimal.ZERO
15+
var btcPendingOutput = BigDecimal.ZERO
16+
var btcBlockHeight: Long = 0
17+
var btcHistory: MutableList<JsonObject> = mutableListOf()
18+
19+
var bitState = true
20+
21+
override fun allAssetValue(isUsd: Boolean?): BigDecimal {
22+
val price = BaseData.getPrice(chain.coinGeckoId, isUsd)
23+
return (btcBalances.add(btcPendingInput)).multiply(price).movePointLeft(8).setScale(8, RoundingMode.DOWN)
24+
}
25+
26+
fun mempoolUrl(): String {
27+
if (chain.isTestnet) {
28+
return "https://mempool.space/testnet4/"
29+
}
30+
return "https://mempool.space/"
31+
}
32+
33+
fun bitType(): String {
34+
return when (chain.accountKeyType.pubkeyType) {
35+
PubKeyType.BTC_NATIVE_SEGWIT -> {
36+
"p2wpkh"
37+
}
38+
39+
PubKeyType.BTC_NESTED_SEGWIT -> {
40+
"p2sh"
41+
}
42+
43+
PubKeyType.BTC_LEGACY -> {
44+
"p2pkh"
45+
}
46+
47+
else -> {
48+
""
49+
}
50+
}
51+
}
52+
53+
fun network(): String {
54+
return if (!chain.isTestnet) "bitcoin" else "testnet"
55+
}
56+
57+
fun bitVBytesFee(utxo: MutableList<JsonObject>?): BigDecimal {
58+
return when (chain.accountKeyType.pubkeyType) {
59+
PubKeyType.BTC_NATIVE_SEGWIT -> {
60+
P2WPKH_VBYTE.OVERHEAD.toBigDecimal().add(
61+
P2WPKH_VBYTE.INPUTS.toBigDecimal().multiply(
62+
BigDecimal(utxo!!.count())
63+
)
64+
).add(P2WPKH_VBYTE.OUTPUTS.toBigDecimal().multiply(BigDecimal(2)))
65+
}
66+
67+
PubKeyType.BTC_NESTED_SEGWIT -> {
68+
P2SH_VBYTE.OVERHEAD.toBigDecimal().add(
69+
P2SH_VBYTE.INPUTS.toBigDecimal().multiply(
70+
BigDecimal(utxo!!.count())
71+
)
72+
).add(P2SH_VBYTE.OUTPUTS.toBigDecimal().multiply(BigDecimal(2)))
73+
}
74+
75+
else -> {
76+
P2PKH_VBYTE.OVERHEAD.toBigDecimal().add(
77+
P2PKH_VBYTE.INPUTS.toBigDecimal().multiply(
78+
BigDecimal(utxo!!.count())
79+
)
80+
).add(P2PKH_VBYTE.OUTPUTS.toBigDecimal().multiply(BigDecimal(2)))
81+
}
82+
}
83+
}
84+
85+
fun txInputString(utxo: MutableList<JsonObject>?): String {
86+
var inputString = ""
87+
when (chain.accountKeyType.pubkeyType) {
88+
PubKeyType.BTC_NATIVE_SEGWIT -> {
89+
utxo?.forEach { tx ->
90+
if (tx["status"].asJsonObject["confirmed"].asBoolean) {
91+
val input = """
92+
{
93+
hash: '${tx["txid"].asString}',
94+
index: ${tx["vout"].asInt},
95+
witnessUtxo: {
96+
script: senderPayment.output,
97+
value: ${tx["value"].asLong}
98+
}
99+
},
100+
"""
101+
inputString += input
102+
}
103+
}
104+
}
105+
106+
PubKeyType.BTC_NESTED_SEGWIT -> {
107+
utxo?.forEach { tx ->
108+
if (tx["status"].asJsonObject["confirmed"].asBoolean) {
109+
val input = """
110+
{
111+
hash: '${tx["txid"].asString}',
112+
index: ${tx["vout"].asInt},
113+
redeemScript: senderPayment.redeem.output,
114+
witnessUtxo: {
115+
script: senderPayment.output,
116+
value: ${tx["value"].asLong}
117+
}
118+
},
119+
"""
120+
inputString += input
121+
}
122+
}
123+
}
124+
125+
PubKeyType.BTC_LEGACY -> {
126+
utxo?.forEach { tx ->
127+
if (tx["status"].asJsonObject["block_hash"] != null) {
128+
val rawTransactionRequest = JsonRpcRequest(
129+
method = "getrawtransaction", params = listOf(
130+
tx["txid"].asString, false, tx["status"].asJsonObject["block_hash"].asString
131+
)
132+
)
133+
val rawTransactionResponse =
134+
jsonRpcResponse(chain.rpcUrl, rawTransactionRequest)
135+
val rawTransactionJsonObject = Gson().fromJson(
136+
rawTransactionResponse.body?.string(), JsonObject::class.java
137+
)
138+
val nonWitnessUtxoHex = rawTransactionJsonObject["result"].asString
139+
140+
if (tx["status"].asJsonObject["confirmed"].asBoolean) {
141+
val input = """
142+
{
143+
hash: '${tx["txid"].asString}',
144+
index: ${tx["vout"].asInt},
145+
nonWitnessUtxo: aTb('${nonWitnessUtxoHex}'),
146+
},
147+
"""
148+
inputString += input
149+
}
150+
}
151+
}
152+
}
153+
154+
else -> {}
155+
}
156+
return inputString
157+
}
158+
159+
fun txOutputString(
160+
receiver: String, toAmount: String, changedValue: String, opReturn: String?
161+
): String {
162+
return if (opReturn?.isNotEmpty() == true) {
163+
"""
164+
{
165+
address: '${receiver}',
166+
value: ${toAmount.toLong()}
167+
},
168+
{
169+
address: '${chain.mainAddress}',
170+
value: ${changedValue.toLong()}
171+
},
172+
m('${opReturn}')
173+
"""
174+
175+
} else {
176+
"""
177+
{
178+
address: '${receiver}',
179+
value: ${toAmount.toLong()}
180+
},
181+
{
182+
address: '${chain.mainAddress}',
183+
value: ${changedValue.toLong()}
184+
},
185+
"""
186+
}
187+
}
188+
}
189+
190+
const val OP_RETURN = 83
191+
192+
object P2WPKH_VBYTE {
193+
const val OVERHEAD = 11
194+
const val INPUTS = 68
195+
const val OUTPUTS = 31
196+
}
197+
198+
object P2SH_VBYTE {
199+
const val OVERHEAD = 10
200+
const val INPUTS = 297
201+
const val OUTPUTS = 32
202+
}
203+
204+
object P2PKH_VBYTE {
205+
const val OVERHEAD = 10
206+
const val INPUTS = 148
207+
const val OUTPUTS = 34
208+
}

app/src/main/java/wannabit/io/cosmostaion/chain/cosmosClass/ChainMars.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ class ChainMars : BaseChain(), Parcelable {
2424
ChildNumber(44, true), ChildNumber(118, true), ChildNumber.ZERO_HARDENED, ChildNumber.ZERO
2525
)
2626

27-
override var cosmosEndPointType: CosmosEndPointType? = CosmosEndPointType.USE_GRPC
27+
override var cosmosEndPointType: CosmosEndPointType? = CosmosEndPointType.USE_LCD
2828
override var stakeDenom: String = "umars"
2929
override var accountPrefix: String = "mars"
30-
override var grpcHost: String = "grpc-mars-protocol.cosmostation.io"
31-
override var lcdUrl: String = "https://lcd-mars-protocol.cosmostation.io/"
30+
override var grpcHost: String = "mars-grpc.lavenderfive.com"
31+
override var lcdUrl: String = "https://mars-api.polkachu.com/"
3232
}

app/src/main/java/wannabit/io/cosmostaion/chain/majorClass/ChainBitCoin44.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import wannabit.io.cosmostaion.chain.PubKeyType
1111
import wannabit.io.cosmostaion.common.BaseKey
1212

1313
@Parcelize
14-
class ChainBitCoin44 : BaseChain(), Parcelable {
14+
class ChainBitCoin44 : ChainBitCoin84(), Parcelable {
1515

1616
override var name: String = "BitCoin"
1717
override var tag: String = "bitcoin44"
@@ -33,6 +33,6 @@ class ChainBitCoin44 : BaseChain(), Parcelable {
3333
override fun setInfoWithPrivateKey(privateKey: ByteArray?) {
3434
this.privateKey = privateKey
3535
publicKey = BaseKey.getPubKeyFromPKey(privateKey, accountKeyType.pubkeyType)
36-
mainAddress = BaseKey.getAddressFromPubKey(publicKey, accountKeyType.pubkeyType)
36+
mainAddress = BaseKey.getAddressFromPubKey(publicKey, accountKeyType.pubkeyType, bech32PrefixPattern, pubKeyHash, scriptHash)
3737
}
3838
}

app/src/main/java/wannabit/io/cosmostaion/chain/majorClass/ChainBitCoin49.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import wannabit.io.cosmostaion.chain.PubKeyType
1111
import wannabit.io.cosmostaion.common.BaseKey
1212

1313
@Parcelize
14-
class ChainBitCoin49 : BaseChain(), Parcelable {
14+
class ChainBitCoin49 : ChainBitCoin84(), Parcelable {
1515

1616
override var name: String = "BitCoin"
1717
override var tag: String = "bitcoin49"
@@ -33,6 +33,6 @@ class ChainBitCoin49 : BaseChain(), Parcelable {
3333
override fun setInfoWithPrivateKey(privateKey: ByteArray?) {
3434
this.privateKey = privateKey
3535
publicKey = BaseKey.getPubKeyFromPKey(privateKey, accountKeyType.pubkeyType)
36-
mainAddress = BaseKey.getAddressFromPubKey(publicKey, accountKeyType.pubkeyType)
36+
mainAddress = BaseKey.getAddressFromPubKey(publicKey, accountKeyType.pubkeyType, bech32PrefixPattern, pubKeyHash, scriptHash)
3737
}
3838
}

app/src/main/java/wannabit/io/cosmostaion/chain/majorClass/ChainBitCoin84.kt

+19-2
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@ package wannabit.io.cosmostaion.chain.majorClass
22

33
import android.os.Parcelable
44
import com.google.common.collect.ImmutableList
5+
import kotlinx.parcelize.IgnoredOnParcel
56
import kotlinx.parcelize.Parcelize
67
import org.bitcoinj.crypto.ChildNumber
78
import wannabit.io.cosmostaion.R
89
import wannabit.io.cosmostaion.chain.AccountKeyType
910
import wannabit.io.cosmostaion.chain.BaseChain
11+
import wannabit.io.cosmostaion.chain.BtcFetcher
1012
import wannabit.io.cosmostaion.chain.PubKeyType
1113
import wannabit.io.cosmostaion.common.BaseKey
1214

1315
@Parcelize
14-
class ChainBitCoin84 : BaseChain(), Parcelable {
16+
open class ChainBitCoin84 : BaseChain(), Parcelable {
17+
18+
@IgnoredOnParcel
19+
var btcFetcher: BtcFetcher? = null
20+
21+
open var pubKeyHash: Byte = 0x00
22+
open var scriptHash: Byte = 0x05
23+
open var bech32PrefixPattern: String = "bc"
1524

1625
override var name: String = "BitCoin"
1726
override var tag: String = "bitcoin84"
1827
override var logo: Int = R.drawable.chain_bitcoin
1928
override var apiName: String = "bitcoin"
29+
override var supportStaking = false
2030

2131
override var accountKeyType = AccountKeyType(PubKeyType.BTC_NATIVE_SEGWIT, "m/84'/0'/0'/0/X")
2232
override var setParentPath: List<ChildNumber> = ImmutableList.of(
@@ -28,10 +38,17 @@ class ChainBitCoin84 : BaseChain(), Parcelable {
2838
override var coinLogo: Int = R.drawable.token_btc
2939

3040
override var mainUrl: String = ""
41+
override var rpcUrl: String = "https://rpc-office.cosmostation.io/bitcoin-testnet"
3142

3243
override fun setInfoWithPrivateKey(privateKey: ByteArray?) {
3344
this.privateKey = privateKey
3445
publicKey = BaseKey.getPubKeyFromPKey(privateKey, accountKeyType.pubkeyType)
35-
mainAddress = BaseKey.getAddressFromPubKey(publicKey, accountKeyType.pubkeyType)
46+
mainAddress = BaseKey.getAddressFromPubKey(publicKey, accountKeyType.pubkeyType, bech32PrefixPattern, pubKeyHash, scriptHash)
47+
}
48+
49+
fun btcFetcher(): BtcFetcher? {
50+
if (btcFetcher != null) return btcFetcher
51+
btcFetcher = BtcFetcher(this)
52+
return btcFetcher
3653
}
3754
}

0 commit comments

Comments
 (0)