Skip to content

Commit

Permalink
Merge pull request #98 from tonkeeper/update_ton_kotlin_lib
Browse files Browse the repository at this point in the history
update
  • Loading branch information
polstianka authored Oct 23, 2024
2 parents 21fc470 + 6050f3c commit a4e275e
Show file tree
Hide file tree
Showing 76 changed files with 420 additions and 1,079 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ data class KeyEntity(
) {

val hex: String
get() = publicKey.key.hex().lowercase()
get() = hex(publicKey.key.toByteArray()).lowercase()

constructor(json: JSONObject) : this(
json.getLong(Key.ID),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.tonapps.signer.deeplink.entities

import android.net.Uri
import android.util.Log
import com.tonapps.blockchain.ton.TonNetwork
import com.tonapps.blockchain.ton.extensions.safeParseCell
import com.tonapps.blockchain.ton.extensions.parseCell
import com.tonapps.blockchain.ton.extensions.safePublicKey
import com.tonapps.extensions.getMultipleQuery
import com.tonapps.signer.Key
import com.tonapps.signer.deeplink.DeeplinkSource
import org.ton.api.pub.PublicKeyEd25519
import org.ton.cell.Cell

Expand All @@ -29,7 +27,7 @@ data class SignRequestEntity(

private val tonNetwork: String = uri.getMultipleQuery("tn", "network") ?: "mainnet"

val body: Cell = uri.getQueryParameter(Key.BODY)?.safeParseCell() ?: throw IllegalArgumentException("body is required")
val body: Cell = uri.getQueryParameter(Key.BODY)?.parseCell() ?: throw IllegalArgumentException("body is required")
val publicKey: PublicKeyEd25519 = uri.getQueryParameter(Key.PK)?.safePublicKey() ?: throw IllegalArgumentException("pk is required")

val network: TonNetwork = if (tonNetwork == "mainnet" || tonNetwork == "-239") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ class SignViewModel(

fun openEmulate() = keyEntity.map {
val contract = BaseWalletContract.create(it.publicKey, v, network.value)
val cell = contract.createTransferMessageCell(contract.address, EmptyPrivateKeyEd25519, seqno, unsignedBody)
val cell = contract.createTransferMessageCell(contract.address, EmptyPrivateKeyEd25519.invoke(), seqno, unsignedBody)
cell.hex()
}.flowOn(Dispatchers.IO).take(1)

private fun sign(privateKey: PrivateKeyEd25519): ByteArray {
return privateKey.sign(unsignedBody.hash())
return privateKey.sign(unsignedBody.hash().toByteArray())
}

private fun parseBoc(): List<SignItem> {
Expand Down
9 changes: 3 additions & 6 deletions apps/wallet/api/src/main/java/com/tonapps/wallet/api/API.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package com.tonapps.wallet.api

import android.content.Context
import android.net.Uri
import android.util.ArrayMap
import android.util.Log
import androidx.core.graphics.drawable.toIcon
import androidx.core.net.toUri
import com.squareup.moshi.JsonAdapter
import com.tonapps.blockchain.ton.contract.BaseWalletContract
import com.tonapps.blockchain.ton.contract.WalletVersion
import com.tonapps.blockchain.ton.extensions.EmptyPrivateKeyEd25519
import com.tonapps.blockchain.ton.extensions.base64
import com.tonapps.blockchain.ton.extensions.hex
import com.tonapps.blockchain.ton.extensions.isValidTonAddress
import com.tonapps.blockchain.ton.extensions.toRawAddress
import com.tonapps.extensions.locale
import com.tonapps.extensions.toUriOrNull
import com.tonapps.extensions.unicodeToPunycode
import com.tonapps.icu.Coins
import com.tonapps.network.SSEvent
import com.tonapps.network.SSLSocketFactoryTcpNoDelay
Expand Down Expand Up @@ -398,7 +395,7 @@ class API(
testnet: Boolean
): List<AccountDetailsEntity> {
return try {
val query = pk.key.hex()
val query = pk.hex()
val wallets = withRetry {
wallet(testnet).getWalletsByPublicKey(query).accounts
} ?: return emptyList()
Expand Down Expand Up @@ -666,7 +663,7 @@ class API(
normalizedAccountId = "$normalizedAccountId.t.me"
}
if (!normalizedAccountId.isValidTonAddress()) {
normalizedAccountId = normalizedAccountId.lowercase().trim().unicodeToPunycode()
normalizedAccountId = normalizedAccountId.lowercase().trim()
}
return withRetry { accounts(testnet).getAccount(normalizedAccountId) }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.tonapps.wallet.api

sealed class APIException(message: String?, cause: Throwable?): Throwable(message, cause) {

class Emulation(boc: String, cause: Throwable? = null): APIException(
message = "Boc: $boc",
cause = cause
)
}
36 changes: 30 additions & 6 deletions apps/wallet/api/src/main/java/com/tonapps/wallet/api/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import com.squareup.moshi.adapter
import io.tonapi.infrastructure.ClientException
import android.util.Log
import com.tonapps.network.OkHttpError
import io.tonapi.infrastructure.ClientError
import io.tonapi.infrastructure.Response
import io.tonapi.infrastructure.ServerError
import kotlinx.coroutines.delay
import kotlinx.coroutines.CancellationException

Expand Down Expand Up @@ -33,12 +36,9 @@ fun <R> withRetry(
} catch (e: CancellationException) {
throw e
} catch (e: Throwable) {
Log.e("TonkeeperLog", "Error in retry block", e)
val statusCode = when (e) {
is ClientException -> e.statusCode
is OkHttpError -> e.statusCode
else -> 0
}
val statusCode = e.getHttpStatusCode()
val message = e.getDebugMessage()
Log.e("TonkeeperLog", "Error in retry block(code=$statusCode): $message", e)
if (statusCode == 429) { // Too many requests
SystemClock.sleep((3000..5000).random().toLong())
return withRetry(times, delay, retryBlock)
Expand All @@ -50,3 +50,27 @@ fun <R> withRetry(
}
return null
}

private fun Throwable.getHttpStatusCode(): Int {
return when (this) {
is ClientException -> statusCode
is OkHttpError -> statusCode
else -> 0
}
}

private fun Throwable.getDebugMessage(): String {
return when (this) {
is ClientException -> getHttpBodyMessage()
is OkHttpError -> body
else -> message ?: "Unknown error"
}
}

private fun ClientException.getHttpBodyMessage(): String {
return when (response) {
is ClientError<*> -> (response as ClientError<*>).body.toString()
is ServerError<*> -> (response as ServerError<*>).body.toString()
else -> response.toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.tonapps.blockchain.ton.extensions.toAccountId
import com.tonapps.blockchain.ton.extensions.toRawAddress
import com.tonapps.blockchain.ton.extensions.toUserFriendly
import com.tonapps.blockchain.ton.extensions.toWalletAddress
import com.tonapps.extensions.ifPunycodeToUnicode
import com.tonapps.extensions.short4
import io.tonapi.models.Account
import io.tonapi.models.AccountAddress
Expand Down Expand Up @@ -43,7 +42,7 @@ data class AccountEntity(
constructor(model: AccountAddress, testnet: Boolean): this(
address = model.address.toUserFriendly(model.isWallet, testnet),
accountId = model.address.toRawAddress(),
name = model.name?.ifPunycodeToUnicode(),
name = model.name,
iconUri = model.icon?.let { Uri.parse(it) },
isWallet = model.isWallet,
isScam = model.isScam
Expand All @@ -52,7 +51,7 @@ data class AccountEntity(
constructor(account: Account, testnet: Boolean) : this(
address = account.address.toUserFriendly(account.isWallet, testnet),
accountId = account.address.toRawAddress(),
name = account.name?.ifPunycodeToUnicode(),
name = account.name,
iconUri = account.icon?.let { Uri.parse(it) },
isWallet = account.isWallet,
isScam = account.isScam ?: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package com.tonapps.wallet.api.entity

import android.net.Uri
import android.os.Parcelable
import android.util.Log
import com.tonapps.blockchain.ton.extensions.safeParseCell
import com.tonapps.blockchain.ton.extensions.parseCell
import com.tonapps.blockchain.ton.extensions.toRawAddress
import com.tonapps.wallet.api.R
import io.tonapi.models.JettonBalanceLock
Expand All @@ -14,6 +13,8 @@ import io.tonapi.models.JettonVerificationType
import kotlinx.parcelize.Parcelize
import org.ton.block.StateInit
import org.ton.cell.Cell
import org.ton.tlb.CellRef
import org.ton.tlb.asRef

@Parcelize
data class TokenEntity(
Expand Down Expand Up @@ -50,7 +51,7 @@ data class TokenEntity(
data class TransferPayload(
val tokenAddress: String,
val customPayload: Cell? = null,
val stateInit: StateInit? = null
val stateInit: CellRef<StateInit>? = null
) {

companion object {
Expand All @@ -65,10 +66,8 @@ data class TokenEntity(

constructor(tokenAddress: String, model: JettonTransferPayload) : this(
tokenAddress = tokenAddress,
customPayload = model.customPayload?.safeParseCell(),
stateInit = model.stateInit?.safeParseCell()?.let {
StateInit.Companion.loadTlb(it)
},
customPayload = model.customPayload?.parseCell(),
stateInit = model.stateInit?.parseCell()?.asRef(StateInit),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import com.tonapps.network.get
import com.tonapps.wallet.api.entity.ConfigEntity
import com.tonapps.wallet.api.entity.NotificationEntity
import com.tonapps.wallet.api.withRetry
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import org.json.JSONObject
import java.util.Locale
Expand Down Expand Up @@ -80,14 +82,17 @@ internal class InternalApi(
}
}

suspend fun resolveCountry(): String? {
return try {
val data = withRetry { okHttpClient.get("https://api.country.is/") } ?: return null
val country = JSONObject(data).getString("country")
suspend fun resolveCountry(): String? = withContext(Dispatchers.IO) {
try {
val country = withRetry {
okHttpClient.get("https://boot.tonkeeper.com/my/ip")
}?.let {
JSONObject(it).getString("country")
}
if (country.isNullOrBlank()) {
null
} else {
country
country.uppercase()
}
} catch (e: Throwable) {
null
Expand Down
7 changes: 6 additions & 1 deletion apps/wallet/data/account/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ dependencies {
implementation(Dependence.KotlinX.serializationJSON)
implementation(Dependence.KotlinX.coroutines)
implementation(Dependence.Koin.core)
implementation(Dependence.ton)
implementation(Dependence.TON.tvm)
implementation(Dependence.TON.crypto)
implementation(Dependence.TON.tlb)
implementation(Dependence.TON.blockTlb)
implementation(Dependence.TON.tonapiTl)
implementation(Dependence.TON.contract)
implementation(project(Dependence.Module.tonApi))
implementation(project(Dependence.Wallet.Data.core))
implementation(project(Dependence.Wallet.Data.rn))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ class AccountRepository(
}

suspend fun getPrivateKey(id: String): PrivateKeyEd25519 {
val wallet = database.getAccount(id) ?: return EmptyPrivateKeyEd25519
return vaultSource.getPrivateKey(wallet.publicKey) ?: EmptyPrivateKeyEd25519
val wallet = database.getAccount(id) ?: return EmptyPrivateKeyEd25519.invoke()
return vaultSource.getPrivateKey(wallet.publicKey) ?: EmptyPrivateKeyEd25519.invoke()
}

suspend fun pairLedger(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.tonapps.wallet.data.collectibles.entities

import android.os.Parcelable
import android.util.Log
import com.tonapps.extensions.ifPunycodeToUnicode
import kotlinx.parcelize.Parcelize

@Parcelize
Expand All @@ -24,7 +22,7 @@ data class NftMetadataEntity(
}

val name: String?
get() = strings["name"]?.ifPunycodeToUnicode()
get() = strings["name"]

val description: String?
get() = strings["description"]
Expand Down
7 changes: 6 additions & 1 deletion apps/wallet/data/core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ dependencies {
api(platform(Dependence.Firebase.bom))
api(Dependence.Firebase.crashlytics)

implementation(Dependence.ton)
implementation(Dependence.TON.tvm)
implementation(Dependence.TON.crypto)
implementation(Dependence.TON.tlb)
implementation(Dependence.TON.blockTlb)
implementation(Dependence.TON.tonapiTl)
implementation(Dependence.TON.contract)
implementation(Dependence.Koin.core)
implementation(Dependence.AndroidX.biometric)
implementation(project(Dependence.Lib.extensions))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,26 @@ package com.tonapps.wallet.data.core.entity

import android.os.Parcelable
import android.util.Log
import com.tonapps.blockchain.ton.TONOpCode
import com.tonapps.blockchain.ton.extensions.base64
import com.tonapps.blockchain.ton.extensions.loadOpCode
import com.tonapps.blockchain.ton.extensions.parseCell
import com.tonapps.blockchain.ton.extensions.safeParseCell
import com.tonapps.blockchain.ton.extensions.storeOpCode
import com.tonapps.blockchain.ton.extensions.toTlb
import com.tonapps.extensions.optStringCompat
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.json.JSONObject
import org.ton.block.AddrStd
import org.ton.block.Coins
import org.ton.block.MsgAddressInt
import org.ton.block.StateInit
import org.ton.cell.Cell
import org.ton.cell.CellBuilder
import org.ton.contract.wallet.WalletTransfer
import org.ton.contract.wallet.WalletTransferBuilder
import org.ton.tlb.loadTlb
import org.ton.tlb.storeTlb
import org.ton.cell.buildCell
import org.ton.tlb.CellRef
import org.ton.tlb.asRef

@Parcelize
data class RawMessageEntity(
val addressValue: String,
val amount: Long,
val stateInitValue: String?,
val payloadValue: String
val payloadValue: String?
): Parcelable {

@IgnoredOnParcel
Expand All @@ -42,20 +35,21 @@ data class RawMessageEntity(
}

@IgnoredOnParcel
val stateInit: StateInit? by lazy {
stateInitValue?.toTlb()
val stateInit: CellRef<StateInit>? by lazy {
val cell = stateInitValue?.parseCell() ?: return@lazy null
cell.asRef(StateInit)
}

@IgnoredOnParcel
val payload: Cell by lazy {
payloadValue.parseCell()
payloadValue?.parseCell() ?: Cell.empty()
}

constructor(json: JSONObject) : this(
json.getString("address"),
parseAmount(json.get("amount")),
json.optString("stateInit"),
json.optString("payload")
json.optStringCompat("stateInit"),
json.optStringCompat("payload")
)

private companion object {
Expand Down
7 changes: 6 additions & 1 deletion apps/wallet/data/dapps/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ android {


dependencies {
implementation(Dependence.ton)
implementation(Dependence.TON.tvm)
implementation(Dependence.TON.crypto)
implementation(Dependence.TON.tlb)
implementation(Dependence.TON.blockTlb)
implementation(Dependence.TON.tonapiTl)
implementation(Dependence.TON.contract)
implementation(project(Dependence.Wallet.api))
implementation(project(Dependence.Wallet.Data.core))
implementation(project(Dependence.Wallet.Data.rn))
Expand Down
Loading

0 comments on commit a4e275e

Please sign in to comment.