Skip to content

Commit

Permalink
bug fixeds for need_for_release
Browse files Browse the repository at this point in the history
  • Loading branch information
polstianka committed Jan 20, 2025
1 parent bb22395 commit a704ac5
Show file tree
Hide file tree
Showing 44 changed files with 451 additions and 203 deletions.
11 changes: 7 additions & 4 deletions apps/wallet/api/src/main/java/com/tonapps/wallet/api/API.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import com.tonapps.blockchain.ton.extensions.toRawAddress
import com.tonapps.extensions.toUriOrNull
import com.tonapps.icu.Coins
import com.tonapps.network.SSEvent
import com.tonapps.network.execute
import com.tonapps.network.get
import com.tonapps.network.post
import com.tonapps.network.postJSON
import com.tonapps.network.requestBuilder
import com.tonapps.network.sse
import com.tonapps.wallet.api.core.SourceAPI
import com.tonapps.wallet.api.entity.AccountDetailsEntity
Expand Down Expand Up @@ -768,10 +770,11 @@ class API(
json.put("silent", true)
val data = json.toString().replace("\\/", "/")

tonAPIHttpClient.postJSON(url, data, ArrayMap<String, String>().apply {
set("X-TonConnect-Auth", token)
set("Connection", "close")
}).isSuccessful
val builder = requestBuilder(url)
builder.delete(data.toRequestBody("application/json".toMediaType()))
builder.addHeader("X-TonConnect-Auth", token)
builder.addHeader("Connection", "close")
tonAPIHttpClient.execute(builder.build()).isSuccessful
} catch (e: Throwable) {
false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import android.os.Parcelable
import android.util.Log
import com.tonapps.blockchain.ton.contract.BaseWalletContract
import com.tonapps.blockchain.ton.contract.WalletVersion
import com.tonapps.blockchain.ton.extensions.isValidTonAddress
import com.tonapps.blockchain.ton.extensions.toRawAddress
import com.tonapps.blockchain.ton.extensions.toUserFriendly
import io.tonapi.models.Account
import io.tonapi.models.AccountStatus
import kotlinx.parcelize.Parcelize
Expand All @@ -17,6 +20,7 @@ data class AccountDetailsEntity(
val balance: Long,
val new: Boolean = false,
val initialized: Boolean,
val testnet: Boolean,
): Parcelable {

val address: String
Expand All @@ -29,29 +33,55 @@ data class AccountDetailsEntity(
contract: BaseWalletContract,
testnet: Boolean,
new: Boolean = false,
initialized: Boolean
initialized: Boolean,
) : this(
query = "",
preview = AccountEntity(contract.address, testnet),
active = true,
walletVersion = contract.getWalletVersion(),
balance = 0,
new = new,
initialized = initialized
initialized = initialized,
testnet = testnet,
)

constructor(query: String, account: Account, testnet: Boolean, new: Boolean = false) : this(
constructor(
query: String,
account: Account,
testnet: Boolean,
new: Boolean = false
) : this(
query = query,
preview = AccountEntity(account, testnet),
active = account.status == AccountStatus.active,
walletVersion = resolveVersion(account.interfaces),
walletVersion = resolveVersion(testnet, account.interfaces, account.address),
balance = account.balance,
new = new,
initialized = account.status == AccountStatus.active || account.status == AccountStatus.frozen
initialized = account.status == AccountStatus.active || account.status == AccountStatus.frozen,
testnet = testnet,
)

private companion object {
private fun resolveVersion(interfaces: List<String>?): WalletVersion {

private fun resolveVersion(testnet: Boolean, interfaces: List<String>?, address: String): WalletVersion {
val version = resolveVersionByInterface(interfaces)
if (version == WalletVersion.UNKNOWN) {
return resolveVersionByAddress(address.toUserFriendly(
wallet = true,
testnet = testnet,
))
}
return version
}

private fun resolveVersionByAddress(userFriendlyAddress: String): WalletVersion {
/*if (userFriendlyAddress.isValidTonAddress()) {
return WalletVersion.V5BETA
}*/
return WalletVersion.UNKNOWN
}

private fun resolveVersionByInterface(interfaces: List<String>?): WalletVersion {
interfaces ?: return WalletVersion.UNKNOWN
return if (interfaces.contains("wallet_v5_beta")) {
WalletVersion.V5BETA
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@ data class BadDomainsEntity(
override fun hashCode(): Int {
return array.contentHashCode()
}

companion object {

fun BadDomainsEntity?.isNullOrEmpty(): Boolean {
return this == null || this.isEmpty
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import android.net.Uri
import android.util.Log
import com.tonapps.extensions.MutableEffectFlow
import com.tonapps.icu.Coins
import com.tonapps.tonkeeper.client.safemode.BadDomainsEntity.Companion.isNullOrEmpty
import com.tonapps.wallet.api.API
import com.tonapps.wallet.data.core.BlobDataSource
import com.tonapps.wallet.data.settings.SafeModeState
import com.tonapps.wallet.data.settings.SettingsRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -16,6 +19,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
Expand All @@ -25,21 +29,20 @@ import java.util.concurrent.ConcurrentHashMap
class SafeModeClient(
private val context: Context,
private val api: API,
private val scope: CoroutineScope
private val scope: CoroutineScope,
private val settingsRepository: SettingsRepository,
) {

private val scamDomains = ConcurrentHashMap<String, Boolean>()
private val blobCache = BlobDataSource.simple<BadDomainsEntity>(context, "safemode")
private val badDomainsFlow = flow {
getCachedBadDomains()?.let {
emit(it)
}
private val scamDomains: ConcurrentHashMap<String, Boolean> by lazy {
ConcurrentHashMap<String, Boolean>(20, 1.0f, 2)
}

loadBadDomains()?.let {
emit(it)
}
}.distinctUntilChanged()
private val blobCache: BlobDataSource<BadDomainsEntity> by lazy {
BlobDataSource.simple<BadDomainsEntity>(context, "safemode")
}

private val _badDomainsFlow = MutableStateFlow<BadDomainsEntity?>(null)
private val badDomainsFlow = _badDomainsFlow.asStateFlow().filterNotNull()
private val _isReadyFlow = MutableStateFlow<Boolean?>(null)
val isReadyFlow = _isReadyFlow.asStateFlow().filterNotNull()

Expand All @@ -52,6 +55,15 @@ class SafeModeClient(
}
_isReadyFlow.value = true
}.launchIn(scope)

settingsRepository.safeModeStateFlow.onEach { state ->
if (state == SafeModeState.Enabled && _badDomainsFlow.value.isNullOrEmpty()) {
_badDomainsFlow.value = getCachedBadDomains()
loadBadDomains()?.let {
_badDomainsFlow.value = it
}
}
}.flowOn(Dispatchers.IO).launchIn(scope)
}

fun isHasScamUris(vararg uris: Uri): Boolean {
Expand All @@ -70,10 +82,10 @@ class SafeModeClient(
return false
}

private fun getCachedBadDomains(): BadDomainsEntity? {
private fun getCachedBadDomains(): BadDomainsEntity {
val entity = blobCache.getCache("scam_domains")
if (entity == null || entity.isEmpty) {
return null
return BadDomainsEntity(emptyArray())
}
return entity
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import com.tonapps.wallet.api.entity.StoryEntity

object AnalyticsHelper {

private val regexPrivateData: Regex by lazy {
Regex("[a-f0-9]{64}|0:[a-f0-9]{64}")
}

fun setConfig(context: Context, config: ConfigEntity) {
initAptabase(
context = context,
Expand All @@ -18,6 +22,10 @@ object AnalyticsHelper {
)
}

private fun removePrivateDataFromUrl(url: String): String {
return url.replace(regexPrivateData, "X")
}

@UiThread
fun firstLaunch(installId: String) {
Aptabase.instance.trackEvent("first_launch", hashMapOf(
Expand Down Expand Up @@ -50,7 +58,7 @@ object AnalyticsHelper {
Aptabase.instance.trackEvent("push_click", hashMapOf(
"firebase_user_id" to installId,
"push_id" to pushId,
"payload" to payload
"payload" to removePrivateDataFromUrl(payload)
))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,14 +413,15 @@ class HistoryHelper(
var actionOutStatusAny = 0

for ((actionIndex, action) in actions.withIndex()) {
if (options.spamFilter == ActionOptions.SpamFilter.SPAM && !event.isScam) {
val isScam = event.isScam || settingsRepository.isSpamTransaction(wallet.id, event.eventId)

if (options.spamFilter == ActionOptions.SpamFilter.SPAM && !isScam) {
continue
} else if (options.spamFilter == ActionOptions.SpamFilter.NOT_SPAM && event.isScam) {
} else if (options.spamFilter == ActionOptions.SpamFilter.NOT_SPAM && isScam) {
continue
}

val timestamp = if (options.removeDate) 0 else event.timestamp
val isScam = event.isScam || settingsRepository.isSpamTransaction(wallet.id, event.eventId)

val item = action(
index = actionIndex,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,5 +270,9 @@ sealed class DeepLinkRoute {
.replace("///", "//")
.toUri()
}

fun isAppLink(url: String): Boolean {
return url.startsWith(PREFIX) || url.startsWith("ton://") || url.startsWith("https://app.tonkeeper.com")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.net.Uri
import android.util.Log
import android.webkit.WebResourceRequest
import androidx.annotation.LayoutRes
import androidx.camera.core.imagecapture.BundlingNode
import androidx.core.net.toUri
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tonapps.extensions.appVersionName
Expand Down Expand Up @@ -82,16 +83,20 @@ abstract class InjectedTonConnectScreen(@LayoutRes layoutId: Int, wallet: Wallet
return false
}
val deeplink = DeepLink(url, false, refererUri)
return processDeeplink(deeplink, url.toString())
}

fun processDeeplink(deeplink: DeepLink, url: String): Boolean {
return when (deeplink.route) {
is DeepLinkRoute.TonConnect -> {
rootViewModel.processTonConnectDeepLink(deeplink, null)
true
}
is DeepLinkRoute.Unknown -> {
navigation?.openURL(url.toString())
navigation?.openURL(url)
true
}
else -> rootViewModel.processDeepLink(uri = url, fromQR = false, refSource = refererUri, internal = false, fromPackageName = null)
else -> rootViewModel.processDeepLink(uri = url.toUri(), fromQR = false, refSource = deeplink.referrer, internal = false, fromPackageName = null)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ class TonConnectWebView @JvmOverloads constructor(

init {
isVerticalScrollBarEnabled = false
settings.setSupportZoom(false)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package com.tonapps.tonkeeper.ui.screen.backup.main

import android.os.Bundle
import android.view.View
import com.tonapps.extensions.bestMessage
import com.tonapps.tonkeeper.extensions.toast
import com.tonapps.tonkeeper.koin.walletViewModel
import com.tonapps.tonkeeper.ui.base.BaseListWalletScreen
import com.tonapps.tonkeeper.ui.base.ScreenContext
import com.tonapps.tonkeeper.ui.screen.backup.main.list.Adapter
import com.tonapps.tonkeeper.ui.screen.backup.main.list.Item
import com.tonapps.tonkeeper.ui.screen.phrase.PhraseScreen
import com.tonapps.tonkeeperx.BuildConfig
import com.tonapps.wallet.data.account.entities.WalletEntity
import com.tonapps.wallet.localization.Localization
import uikit.base.BaseFragment
Expand Down Expand Up @@ -50,8 +53,12 @@ class BackupScreen(wallet: WalletEntity): BaseListWalletScreen<ScreenContext.Wal
}

private fun openRecoveryPhrase(backup: Boolean = false, backupId: Long = 0) {
viewModel.getRecoveryPhrase(requireContext()) { words ->
navigation?.add(PhraseScreen.newInstance(screenContext.wallet, words, backup, backupId))
viewModel.getRecoveryPhrase(requireContext()) { words, error ->
if (error != null) {
navigation?.toast(error.bestMessage)
} else {
navigation?.add(PhraseScreen.newInstance(screenContext.wallet, words, backup, backupId))
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,28 @@ class BackupViewModel(

fun getRecoveryPhrase(
context: Context,
callback: (Array<String>) -> Unit
callback: (Array<String>, Throwable?) -> Unit
) {
viewModelScope.launch(Dispatchers.IO) {
val confirmed = passcodeManager.confirmation(context, getString(Localization.app_name))
if (confirmed) {
val words = accountRepository.getMnemonic(wallet.id) ?: return@launch
withContext(Dispatchers.Main) {
callback(words)
try {
val words = accountRepository.getMnemonic(wallet.id) ?: emptyArray()
if (words.isEmpty()) {
val hasPrivateKey = accountRepository.getPrivateKey(wallet.id) != null
if (hasPrivateKey) {
throw IllegalStateException("No mnemonic but has private key")
} else {
throw IllegalStateException("No mnemonic and no private key")
}
}
withContext(Dispatchers.Main) {
callback(words, null)
}
} catch (e: Throwable) {
withContext(Dispatchers.Main) {
callback(emptyArray(), e)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import androidx.webkit.WebViewFeature
import com.facebook.drawee.backends.pipeline.Fresco
import com.tonapps.extensions.toUriOrNull
import com.tonapps.tonkeeper.core.AnalyticsHelper
import com.tonapps.tonkeeper.deeplink.DeepLink
import com.tonapps.tonkeeper.deeplink.DeepLinkRoute
import com.tonapps.tonkeeper.extensions.copyToClipboard
import com.tonapps.tonkeeper.extensions.loadSquare
import com.tonapps.tonkeeper.extensions.setWallet
Expand Down Expand Up @@ -136,6 +138,17 @@ class DAppScreen(wallet: WalletEntity): InjectedTonConnectScreen(R.layout.fragme
}

private fun openNewTab(url: String) {
if (DeepLinkRoute.isAppLink(url)) {
val deeplink = DeepLink(url.toUri(), false, null)
if (!processDeeplink(deeplink, url)) {
forceOpenNewTab(url)
}
} else {
forceOpenNewTab(url)
}
}

private fun forceOpenNewTab(url: String) {
val uri = url.toUriOrNull() ?: return
navigation?.add(newInstance(
wallet = wallet,
Expand Down
Loading

0 comments on commit a704ac5

Please sign in to comment.