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
+29
View File
@@ -0,0 +1,29 @@
apply plugin: 'kotlin-parcelize'
android {
namespace 'io.novafoundation.nova.feature_nft_api'
}
dependencies {
implementation coroutinesDep
implementation project(':runtime')
implementation project(":feature-account-api")
implementation project(":feature-wallet-api")
implementation project(":common")
implementation androidDep
implementation materialDep
implementation daggerDep
implementation substrateSdkDep
implementation constraintDep
implementation lifeCycleKtxDep
api project(':core-api')
api project(':core-db')
testImplementation project(':test-shared')
}
View File
+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,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
@@ -0,0 +1,8 @@
package io.novafoundation.nova.feature_nft_api
import io.novafoundation.nova.feature_nft_api.data.repository.NftRepository
interface NftFeatureApi {
val nftRepository: NftRepository
}
@@ -0,0 +1,69 @@
package io.novafoundation.nova.feature_nft_api.data.model
import io.novafoundation.nova.feature_wallet_api.data.network.blockhain.types.Balance
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
import io.novasama.substrate_sdk_android.runtime.AccountId
import java.math.BigInteger
class Nft(
val identifier: String,
val instanceId: String?,
val collectionId: String,
val chain: Chain,
val owner: AccountId,
val metadataRaw: ByteArray?,
val details: Details,
val type: Type,
) {
sealed class Details {
class Loaded(
val price: Price?,
val issuance: Issuance,
val name: String?,
val label: String?,
val media: String?,
) : Details()
object Loadable : Details()
}
sealed class Price {
class NonFungible(val nftPrice: BigInteger) : Price()
class Fungible(val units: BigInteger, val totalPrice: Balance) : Price()
}
sealed class Issuance {
object Unlimited : Issuance()
class Limited(val max: Int, val edition: Int) : Issuance()
class Fungible(val myAmount: BigInteger, val totalSupply: BigInteger) : Issuance()
}
sealed class Type(val key: Key) {
enum class Key {
UNIQUES, RMRKV1, RMRKV2, PDC20, KODADOT, UNIQUE_NETWORK
}
object Uniques : Type(Key.UNIQUES)
object Rmrk1 : Type(Key.RMRKV1)
object Rmrk2 : Type(Key.RMRKV2)
object Pdc20 : Type(Key.PDC20)
object Kodadot : Type(Key.KODADOT)
object UniqueNetwork : Type(Key.UNIQUE_NETWORK)
}
}
val Nft.isFullySynced
get() = details is Nft.Details.Loaded
@@ -0,0 +1,24 @@
package io.novafoundation.nova.feature_nft_api.data.model
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
import io.novasama.substrate_sdk_android.runtime.AccountId
class NftDetails(
val identifier: String,
val chain: Chain,
val owner: AccountId,
val creator: AccountId?,
val media: String?,
val name: String,
val description: String?,
val issuance: Nft.Issuance,
val price: Nft.Price?,
val collection: Collection?
) {
class Collection(
val id: String,
val name: String? = null,
val media: String? = null
)
}
@@ -0,0 +1,24 @@
package io.novafoundation.nova.feature_nft_api.data.repository
import io.novafoundation.nova.feature_account_api.domain.model.MetaAccount
import io.novafoundation.nova.feature_nft_api.data.model.Nft
import io.novafoundation.nova.feature_nft_api.data.model.NftDetails
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
import kotlinx.coroutines.flow.Flow
interface NftRepository {
fun allNftFlow(metaAccount: MetaAccount): Flow<List<Nft>>
fun nftDetails(nftId: String): Flow<NftDetails>
fun initialNftSyncTrigger(): Flow<NftSyncTrigger>
suspend fun initialNftSync(metaAccount: MetaAccount, forceOverwrite: Boolean)
suspend fun initialNftSync(metaAccount: MetaAccount, chain: Chain)
suspend fun fullNftSync(nft: Nft)
}
class NftSyncTrigger(val chain: Chain)