Initial commit: Pezkuwi Wallet Android

Security hardened release:
- Code obfuscation enabled (minifyEnabled=true, shrinkResources=true)
- Sensitive files excluded (google-services.json, keystores)
- Branch.io key moved to BuildConfig placeholder
- Updated dependencies: OkHttp 4.12.0, Gson 2.10.1, BouncyCastle 1.77
- Comprehensive ProGuard rules for crypto wallet
- Navigation 2.7.7, Lifecycle 2.7.0, ConstraintLayout 2.1.4
This commit is contained in:
2026-02-12 05:19:41 +03:00
commit a294aa1a6b
7687 changed files with 441811 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
/build
+19
View File
@@ -0,0 +1,19 @@
android {
namespace 'io.novafoundation.nova.feature_currency_api'
}
dependencies {
implementation coroutinesDep
implementation project(':core-db')
implementation project(':runtime')
implementation project(":common")
implementation daggerDep
implementation substrateSdkDep
implementation androidDep
api project(':core-api')
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />
@@ -0,0 +1,11 @@
package io.novafoundation.nova.feature_currency_api.di
import io.novafoundation.nova.feature_currency_api.domain.CurrencyInteractor
import io.novafoundation.nova.feature_currency_api.domain.interfaces.CurrencyRepository
interface CurrencyFeatureApi {
fun currencyInteractor(): CurrencyInteractor
fun currencyRepository(): CurrencyRepository
}
@@ -0,0 +1,5 @@
package io.novafoundation.nova.feature_currency_api.domain
enum class CurrencyCategory {
FIAT, FIAT_POPULAR, CRYPTO
}
@@ -0,0 +1,18 @@
package io.novafoundation.nova.feature_currency_api.domain
import io.novafoundation.nova.common.list.GroupedList
import io.novafoundation.nova.feature_currency_api.domain.model.Currency
import kotlinx.coroutines.flow.Flow
interface CurrencyInteractor {
suspend fun syncCurrencies()
fun observeCurrencies(): Flow<GroupedList<CurrencyCategory, Currency>>
fun observeSelectCurrency(): Flow<Currency>
suspend fun getSelectedCurrency(): Currency
suspend fun selectCurrency(currencyId: Int)
}
@@ -0,0 +1,17 @@
package io.novafoundation.nova.feature_currency_api.domain.interfaces
import io.novafoundation.nova.feature_currency_api.domain.model.Currency
import kotlinx.coroutines.flow.Flow
interface CurrencyRepository {
suspend fun syncCurrencies()
fun observeCurrencies(): Flow<List<Currency>>
fun observeSelectCurrency(): Flow<Currency>
suspend fun selectCurrency(currencyId: Int)
suspend fun getSelectedCurrency(): Currency
}
@@ -0,0 +1,17 @@
package io.novafoundation.nova.feature_currency_api.domain.model
data class Currency(
val code: String,
val name: String,
val symbol: String?,
val category: Category,
val popular: Boolean,
val id: Int,
val coingeckoId: String,
val selected: Boolean,
) {
enum class Category {
FIAT, CRYPTO
}
}
@@ -0,0 +1,8 @@
package io.novafoundation.nova.feature_currency_api.presentation
import io.novafoundation.nova.common.navigation.ReturnableRouter
interface CurrencyRouter : ReturnableRouter {
fun returnToWallet()
}
@@ -0,0 +1,41 @@
package io.novafoundation.nova.feature_currency_api.presentation.formatters
import io.novafoundation.nova.common.utils.formatting.currencyFormatter
import io.novafoundation.nova.common.utils.formatting.formatWithFullAmount
import io.novafoundation.nova.common.utils.formatting.simpleCurrencyFormatter
import io.novafoundation.nova.feature_currency_api.domain.model.Currency
import java.math.BigDecimal
import java.math.RoundingMode
private val currencyFormatter = currencyFormatter()
private val simpleCurrencyFormatter = simpleCurrencyFormatter()
@Deprecated("Use FiatFormatter instead")
fun BigDecimal.formatAsCurrencyNoAbbreviation(currency: Currency): String {
return formatCurrencySymbol(currency.symbol, currency.code) + this.formatWithFullAmount()
}
@Deprecated("Use FiatFormatter instead")
fun BigDecimal.formatAsCurrency(currency: Currency, roundingMode: RoundingMode = RoundingMode.FLOOR): String {
return formatAsCurrency(currency.symbol, currency.code, roundingMode)
}
@Deprecated("Use FiatFormatter instead")
fun BigDecimal.simpleFormatAsCurrency(currency: Currency, roundingMode: RoundingMode = RoundingMode.FLOOR): String {
return simpleFormatAsCurrency(currency.symbol, currency.code, roundingMode)
}
@Deprecated("Use FiatFormatter instead")
fun BigDecimal.formatAsCurrency(symbol: String?, code: String, roundingMode: RoundingMode = RoundingMode.FLOOR): String {
return formatCurrencySymbol(symbol, code) + currencyFormatter.format(this, roundingMode)
}
@Deprecated("Use FiatFormatter instead")
fun BigDecimal.simpleFormatAsCurrency(symbol: String?, code: String, roundingMode: RoundingMode = RoundingMode.FLOOR): String {
return formatCurrencySymbol(symbol, code) + simpleCurrencyFormatter.format(this, roundingMode)
}
@Deprecated("Use FiatFormatter instead")
private fun formatCurrencySymbol(symbol: String?, code: String): String {
return symbol ?: "$code "
}
@@ -0,0 +1,37 @@
package io.novafoundation.nova.feature_currency_api.presentation.mapper
import io.novafoundation.nova.core_db.model.CurrencyLocal
import io.novafoundation.nova.feature_currency_api.domain.model.Currency
import io.novafoundation.nova.feature_currency_api.presentation.model.CurrencyModel
fun mapCurrencyToUI(currency: Currency): CurrencyModel {
return CurrencyModel(
id = currency.id,
displayCode = currency.symbol ?: currency.code,
code = currency.code,
name = currency.name,
isSelected = currency.selected
)
}
fun mapCurrencyFromLocal(local: CurrencyLocal): Currency {
return with(local) {
Currency(
code = code,
name = name,
symbol = symbol,
category = mapCurrencyCategoryFromLocal(category),
popular = popular,
id = id,
coingeckoId = coingeckoId,
selected = selected
)
}
}
private fun mapCurrencyCategoryFromLocal(local: CurrencyLocal.Category): Currency.Category {
return when (local) {
CurrencyLocal.Category.CRYPTO -> Currency.Category.CRYPTO
CurrencyLocal.Category.FIAT -> Currency.Category.FIAT
}
}
@@ -0,0 +1,9 @@
package io.novafoundation.nova.feature_currency_api.presentation.model
data class CurrencyModel(
val id: Int,
val displayCode: String,
val code: String,
val name: String,
val isSelected: Boolean
)