mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-04-27 02:08:00 +00:00
Initial commit: Pezkuwi Wallet Android
Complete rebrand of Nova Wallet for Pezkuwichain ecosystem. ## Features - Full Pezkuwichain support (HEZ & PEZ tokens) - Polkadot ecosystem compatibility - Staking, Governance, DeFi, NFTs - XCM cross-chain transfers - Hardware wallet support (Ledger, Polkadot Vault) - WalletConnect v2 - Push notifications ## Languages - English, Turkish, Kurmanci (Kurdish), Spanish, French, German, Russian, Japanese, Chinese, Korean, Portuguese, Vietnamese Based on Nova Wallet by Novasama Technologies GmbH © Dijital Kurdistan Tech Institute 2026
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.withChildScope
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeComponent
|
||||
import io.novafoundation.nova.runtime.ext.Geneses
|
||||
import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
|
||||
import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
open class BaseIntegrationTest {
|
||||
|
||||
protected val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
protected val runtimeApi = FeatureUtils.getFeature<RuntimeComponent>(context, RuntimeApi::class.java)
|
||||
|
||||
val chainRegistry = runtimeApi.chainRegistry()
|
||||
|
||||
private val externalRequirementFlow = runtimeApi.externalRequirementFlow()
|
||||
|
||||
@Before
|
||||
fun setup() = runBlocking {
|
||||
externalRequirementFlow.emit(ChainConnection.ExternalRequirement.ALLOWED)
|
||||
}
|
||||
|
||||
protected fun runTest(action: suspend CoroutineScope.() -> Unit) {
|
||||
runBlocking {
|
||||
withChildScope {
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected suspend fun ChainRegistry.polkadot(): Chain {
|
||||
return getChain(Chain.Geneses.POLKADOT)
|
||||
}
|
||||
|
||||
protected suspend fun ChainRegistry.polkadotAssetHub(): Chain {
|
||||
return getChain(Chain.Geneses.POLKADOT_ASSET_HUB)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.bindEventRecords
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.LOG_TAG
|
||||
import io.novafoundation.nova.common.utils.system
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeComponent
|
||||
import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection
|
||||
import io.novasama.substrate_sdk_android.runtime.metadata.storage
|
||||
import io.novasama.substrate_sdk_android.runtime.metadata.storageKey
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class BlockParsingIntegrationTest {
|
||||
|
||||
private val chainGenesis = "f1cf9022c7ebb34b162d5b5e34e705a5a740b2d0ecc1009fb89023e62a488108" // Shiden
|
||||
|
||||
private val runtimeApi = FeatureUtils.getFeature<RuntimeComponent>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
RuntimeApi::class.java
|
||||
)
|
||||
|
||||
private val chainRegistry = runtimeApi.chainRegistry()
|
||||
private val externalRequirementFlow = runtimeApi.externalRequirementFlow()
|
||||
|
||||
private val rpcCalls = runtimeApi.rpcCalls()
|
||||
|
||||
private val remoteStorage = runtimeApi.remoteStorageSource()
|
||||
|
||||
@Test
|
||||
fun testBlockParsing() = runBlocking {
|
||||
externalRequirementFlow.emit(ChainConnection.ExternalRequirement.ALLOWED)
|
||||
val chain = chainRegistry.getChain(chainGenesis)
|
||||
|
||||
val block = rpcCalls.getBlock(chain.id)
|
||||
|
||||
val logTag = this@BlockParsingIntegrationTest.LOG_TAG
|
||||
|
||||
Log.d(logTag, block.block.header.number.toString())
|
||||
|
||||
val events = remoteStorage.query(
|
||||
chainId = chain.id,
|
||||
keyBuilder = { it.metadata.system().storage("Events").storageKey() },
|
||||
binding = { scale, runtime ->
|
||||
Log.d(logTag, scale!!)
|
||||
bindEventRecords(scale)
|
||||
}
|
||||
)
|
||||
|
||||
// val eventsRaw = "0x0800000000000000000000000000000002000000010000000000585f8f0900000000020000"
|
||||
// val type = bindEventRecords(eventsRaw, chainRegistry.getRuntime(chain.id))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.gson.Gson
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import dagger.Component
|
||||
import io.novafoundation.nova.common.data.network.NetworkApiCreator
|
||||
import io.novafoundation.nova.common.di.CommonApi
|
||||
import io.novafoundation.nova.common.di.FeatureContainer
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.NodeSelectionPreferencesLocal
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.RemoteToDomainChainMapperFacade
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapChainAssetToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapChainExplorerToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapChainExternalApiToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapChainLocalToChain
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapChainNodeToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapChainToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapExternalApisToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapNodeSelectionPreferencesToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapRemoteAssetToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapRemoteChainToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapRemoteExplorersToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.mappers.mapRemoteNodesToLocal
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.remote.ChainFetcher
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.remote.model.ChainRemote
|
||||
import io.novafoundation.nova.test_shared.assertAllItemsEquals
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
|
||||
@Component(
|
||||
dependencies = [
|
||||
CommonApi::class,
|
||||
RuntimeApi::class
|
||||
]
|
||||
)
|
||||
interface MappingTestAppComponent {
|
||||
|
||||
fun inject(test: ChainMappingIntegrationTest)
|
||||
}
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ChainMappingIntegrationTest {
|
||||
|
||||
private val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
|
||||
private val featureContainer = context as FeatureContainer
|
||||
|
||||
@Inject
|
||||
lateinit var networkApiCreator: NetworkApiCreator
|
||||
|
||||
@Inject
|
||||
lateinit var remoteToDomainChainMapperFacade: RemoteToDomainChainMapperFacade
|
||||
|
||||
lateinit var chainFetcher: ChainFetcher
|
||||
|
||||
private val gson = Gson()
|
||||
|
||||
@Before
|
||||
fun prepare() {
|
||||
val component = DaggerMappingTestAppComponent.builder()
|
||||
.commonApi(featureContainer.commonApi())
|
||||
.runtimeApi(featureContainer.getFeature(RuntimeApi::class.java))
|
||||
.build()
|
||||
|
||||
component.inject(this)
|
||||
|
||||
chainFetcher = networkApiCreator.create(ChainFetcher::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testChainMappingIsMatch() {
|
||||
runBlocking {
|
||||
val chainsRemote = chainFetcher.getChains()
|
||||
|
||||
val remoteToDomain = chainsRemote.map { mapRemoteToDomain(it) }
|
||||
val remoteToLocalToDomain = chainsRemote.map { mapRemoteToLocalToDomain(it) }
|
||||
val domainToLocalToDomain = remoteToDomain.map { mapDomainToLocalToDomain(it) }
|
||||
|
||||
assertAllItemsEquals(listOf(remoteToDomain, remoteToLocalToDomain, domainToLocalToDomain))
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapRemoteToLocalToDomain(chainRemote: ChainRemote): Chain {
|
||||
val chainLocal = mapRemoteChainToLocal(chainRemote, null, ChainLocal.Source.DEFAULT, gson)
|
||||
val assetsLocal = chainRemote.assets.map { mapRemoteAssetToLocal(chainRemote, it, gson, isEnabled = true) }
|
||||
val nodesLocal = mapRemoteNodesToLocal(chainRemote)
|
||||
val explorersLocal = mapRemoteExplorersToLocal(chainRemote)
|
||||
val externalApisLocal = mapExternalApisToLocal(chainRemote)
|
||||
|
||||
return mapChainLocalToChain(
|
||||
chainLocal = chainLocal,
|
||||
nodesLocal = nodesLocal,
|
||||
nodeSelectionPreferences = NodeSelectionPreferencesLocal(chainLocal.id, autoBalanceEnabled = true, selectedNodeUrl = null),
|
||||
assetsLocal = assetsLocal,
|
||||
explorersLocal = explorersLocal,
|
||||
externalApisLocal = externalApisLocal,
|
||||
gson = gson
|
||||
)
|
||||
}
|
||||
|
||||
private fun mapRemoteToDomain(chainRemote: ChainRemote): Chain {
|
||||
return remoteToDomainChainMapperFacade.mapRemoteChainToDomain(chainRemote, Chain.Source.DEFAULT)
|
||||
}
|
||||
|
||||
private fun mapDomainToLocalToDomain(chain: Chain): Chain {
|
||||
val chainLocal = mapChainToLocal(chain, gson)
|
||||
val nodesLocal = chain.nodes.nodes.map { mapChainNodeToLocal(it) }
|
||||
val nodeSelectionPreferencesLocal = mapNodeSelectionPreferencesToLocal(chain)
|
||||
val assetsLocal = chain.assets.map { mapChainAssetToLocal(it, gson) }
|
||||
val explorersLocal = chain.explorers.map { mapChainExplorerToLocal(it) }
|
||||
val externalApisLocal = chain.externalApis.map { mapChainExternalApiToLocal(gson, chain.id, it) }
|
||||
|
||||
return mapChainLocalToChain(
|
||||
chainLocal = chainLocal,
|
||||
nodesLocal = nodesLocal,
|
||||
nodeSelectionPreferences = nodeSelectionPreferencesLocal,
|
||||
assetsLocal = assetsLocal,
|
||||
explorersLocal = explorersLocal,
|
||||
externalApisLocal = externalApisLocal,
|
||||
gson = gson
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import androidx.room.Room
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.google.gson.Gson
|
||||
import dagger.Component
|
||||
import io.novafoundation.nova.common.data.network.NetworkApiCreator
|
||||
import io.novafoundation.nova.common.di.CommonApi
|
||||
import io.novafoundation.nova.common.di.FeatureContainer
|
||||
import io.novafoundation.nova.core_db.AppDatabase
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.ChainSyncService
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.remote.ChainFetcher
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@Component(
|
||||
dependencies = [
|
||||
CommonApi::class,
|
||||
]
|
||||
)
|
||||
interface TestAppComponent {
|
||||
|
||||
fun inject(test: ChainSyncServiceIntegrationTest)
|
||||
}
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ChainSyncServiceIntegrationTest {
|
||||
|
||||
private val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
|
||||
private val featureContainer = context as FeatureContainer
|
||||
|
||||
@Inject
|
||||
lateinit var networkApiCreator: NetworkApiCreator
|
||||
|
||||
lateinit var chainSyncService: ChainSyncService
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
val component = DaggerTestAppComponent.builder()
|
||||
.commonApi(featureContainer.commonApi())
|
||||
.build()
|
||||
|
||||
component.inject(this)
|
||||
|
||||
val chainDao = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
||||
.build()
|
||||
.chainDao()
|
||||
|
||||
chainSyncService = ChainSyncService(chainDao, networkApiCreator.create(ChainFetcher::class.java), Gson())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldFetchAndStoreRealChains() = runBlocking {
|
||||
chainSyncService.syncUp()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import io.novafoundation.nova.common.address.intoKey
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.emptySubstrateAccountId
|
||||
import io.novafoundation.nova.feature_account_api.data.fee.FeePaymentCurrency
|
||||
import io.novafoundation.nova.feature_account_api.domain.model.toDefaultSubstrateAddress
|
||||
import io.novafoundation.nova.feature_wallet_api.data.network.blockhain.assets.tranfers.AssetTransferBase
|
||||
import io.novafoundation.nova.feature_wallet_api.data.repository.getXcmChain
|
||||
import io.novafoundation.nova.feature_wallet_api.di.WalletFeatureApi
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.model.xcm.legacy.transferConfiguration
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.model.xcm.transferConfiguration
|
||||
import io.novafoundation.nova.runtime.ext.addressOf
|
||||
import io.novafoundation.nova.runtime.ext.emptyAccountId
|
||||
import io.novafoundation.nova.runtime.ext.normalizeTokenSymbol
|
||||
import io.novafoundation.nova.runtime.multiNetwork.findChain
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
|
||||
class CrossChainTransfersIntegrationTest : BaseIntegrationTest() {
|
||||
|
||||
private val walletApi = FeatureUtils.getFeature<WalletFeatureApi>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
WalletFeatureApi::class.java
|
||||
)
|
||||
|
||||
private val chainTransfersRepository = walletApi.crossChainTransfersRepository
|
||||
private val crossChainWeigher = walletApi.crossChainWeigher
|
||||
|
||||
private val parachainInfoRepository = runtimeApi.parachainInfoRepository
|
||||
|
||||
@Test
|
||||
fun testParachainToParachain() = performFeeTest(
|
||||
from = "Moonriver",
|
||||
what = "xcKAR",
|
||||
to = "Karura"
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testRelaychainToParachain() = performFeeTest(
|
||||
from = "Kusama",
|
||||
what = "KSM",
|
||||
to = "Moonriver"
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testParachainToRelaychain() = performFeeTest(
|
||||
from = "Moonriver",
|
||||
what = "xcKSM",
|
||||
to = "Kusama"
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testParachainToParachainNonReserve() = performFeeTest(
|
||||
from = "Karura",
|
||||
what = "BNC",
|
||||
to = "Moonriver"
|
||||
)
|
||||
|
||||
private fun performFeeTest(
|
||||
from: String,
|
||||
to: String,
|
||||
what: String
|
||||
) {
|
||||
runBlocking {
|
||||
val originChain = chainRegistry.findChain { it.name == from }!!
|
||||
val asssetInOrigin = originChain.assets.first { it.symbol.value == what }
|
||||
|
||||
val destinationChain = chainRegistry.findChain { it.name == to }!!
|
||||
val asssetInDestination = destinationChain.assets.first { normalizeTokenSymbol(it.symbol.value) == normalizeTokenSymbol(what) }
|
||||
|
||||
val crossChainConfig = chainTransfersRepository.getConfiguration()
|
||||
|
||||
val crossChainTransfer = crossChainConfig.transferConfiguration(
|
||||
originChain = parachainInfoRepository.getXcmChain(originChain),
|
||||
originAsset = asssetInOrigin,
|
||||
destinationChain = parachainInfoRepository.getXcmChain(destinationChain),
|
||||
)!!
|
||||
|
||||
val transfer = AssetTransferBase(
|
||||
recipient = originChain.addressOf(originChain.emptyAccountId()),
|
||||
originChain = originChain,
|
||||
originChainAsset = asssetInOrigin,
|
||||
destinationChain = destinationChain,
|
||||
destinationChainAsset = asssetInDestination,
|
||||
feePaymentCurrency = FeePaymentCurrency.Native,
|
||||
amountPlanks = BigInteger.ZERO
|
||||
)
|
||||
|
||||
val crossChainFeeResult = runCatching { crossChainWeigher.estimateFee(transfer, crossChainTransfer) }
|
||||
|
||||
check(crossChainFeeResult.isSuccess)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import io.novafoundation.nova.common.address.intoKey
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.toResult
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.composeCall
|
||||
import io.novafoundation.nova.common.utils.xcmPalletName
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.model.planksFromAmount
|
||||
import io.novafoundation.nova.feature_xcm_api.asset.MultiAsset
|
||||
import io.novafoundation.nova.feature_xcm_api.asset.MultiAssets
|
||||
import io.novafoundation.nova.feature_xcm_api.di.XcmFeatureApi
|
||||
import io.novafoundation.nova.feature_xcm_api.runtimeApi.dryRun.model.OriginCaller
|
||||
import io.novafoundation.nova.feature_xcm_api.runtimeApi.dryRun.model.getByLocation
|
||||
import io.novafoundation.nova.feature_xcm_api.multiLocation.Junctions
|
||||
import io.novafoundation.nova.feature_xcm_api.multiLocation.MultiLocation
|
||||
import io.novafoundation.nova.feature_xcm_api.multiLocation.MultiLocation.Junction.ParachainId
|
||||
import io.novafoundation.nova.feature_xcm_api.multiLocation.asLocation
|
||||
import io.novafoundation.nova.feature_xcm_api.multiLocation.toMultiLocation
|
||||
import io.novafoundation.nova.feature_xcm_api.versions.XcmVersion
|
||||
import io.novafoundation.nova.feature_xcm_api.versions.toEncodableInstance
|
||||
import io.novafoundation.nova.feature_xcm_api.versions.versionedXcm
|
||||
import io.novafoundation.nova.feature_xcm_api.weight.WeightLimit
|
||||
import io.novafoundation.nova.runtime.ext.utilityAsset
|
||||
import io.novafoundation.nova.runtime.multiNetwork.getRuntime
|
||||
import io.novasama.substrate_sdk_android.ss58.SS58Encoder.toAccountId
|
||||
import org.junit.Test
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
|
||||
class DryRunIntegrationTest : BaseIntegrationTest() {
|
||||
|
||||
private val xcmApi = FeatureUtils.getFeature<XcmFeatureApi>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
XcmFeatureApi::class.java
|
||||
)
|
||||
|
||||
private val dryRunApi = xcmApi.dryRunApi
|
||||
|
||||
@Test
|
||||
fun testDryRunXcmTeleport() = runTest {
|
||||
val polkadot = chainRegistry.polkadot()
|
||||
val polkadotAssetHub = chainRegistry.polkadotAssetHub()
|
||||
|
||||
val polkadotRuntime = chainRegistry.getRuntime(polkadot.id)
|
||||
|
||||
val polkadotLocation = MultiLocation.Interior.Here.asLocation()
|
||||
val polkadotAssetHubLocation = Junctions(ParachainId(1000)).asLocation()
|
||||
|
||||
val dotLocation = polkadotLocation.toRelative()
|
||||
val amount = polkadot.utilityAsset.planksFromAmount(BigDecimal.ONE)
|
||||
val assets = MultiAsset.from(dotLocation, amount)
|
||||
|
||||
val origin = "16WWmr2Xqgy5fna35GsNHXMU7vDBM12gzHCFGibQjSmKpAN".toAccountId().intoKey()
|
||||
val beneficiary = origin.toMultiLocation()
|
||||
|
||||
val xcmVersion = XcmVersion.V4
|
||||
|
||||
val pahVersionedLocation = polkadotAssetHubLocation.toRelative().versionedXcm(xcmVersion)
|
||||
|
||||
// Compose limited_teleport_assets call to execute on Polkadot
|
||||
val call = polkadotRuntime.composeCall(
|
||||
moduleName = polkadotRuntime.metadata.xcmPalletName(),
|
||||
callName = "limited_teleport_assets",
|
||||
arguments = mapOf(
|
||||
"dest" to pahVersionedLocation.toEncodableInstance(),
|
||||
"beneficiary" to beneficiary.versionedXcm(xcmVersion).toEncodableInstance(),
|
||||
"assets" to MultiAssets(assets).versionedXcm(xcmVersion).toEncodableInstance(),
|
||||
"fee_asset_item" to BigInteger.ZERO,
|
||||
"weight_limit" to WeightLimit.Unlimited.toEncodableInstance()
|
||||
)
|
||||
)
|
||||
|
||||
// Dry run call execution
|
||||
val dryRunEffects = dryRunApi.dryRunCall(
|
||||
originCaller = OriginCaller.System.Signed(origin),
|
||||
call = call,
|
||||
chainId = polkadot.id,
|
||||
xcmResultsVersion = XcmVersion.V4
|
||||
)
|
||||
.getOrThrow()
|
||||
.toResult().getOrThrow()
|
||||
|
||||
// Find xcm forwarded to Polkadot Asset Hub
|
||||
val forwardedXcm = dryRunEffects.forwardedXcms.getByLocation(pahVersionedLocation).first()
|
||||
println(forwardedXcm)
|
||||
|
||||
// Dry run execution of forwarded message on Polkadot Asset Hub
|
||||
val xcmDryRunEffects = dryRunApi.dryRunXcm(
|
||||
xcm = forwardedXcm,
|
||||
originLocation = polkadotLocation.fromPointOfViewOf(polkadotAssetHubLocation).versionedXcm(xcmVersion),
|
||||
chainId = polkadotAssetHub.id
|
||||
)
|
||||
.getOrThrow()
|
||||
.toResult().getOrThrow()
|
||||
|
||||
println(xcmDryRunEffects.emittedEvents)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.util.Log
|
||||
import io.novafoundation.nova.common.utils.average
|
||||
import io.novafoundation.nova.common.utils.divideToDecimal
|
||||
import io.novafoundation.nova.runtime.ethereum.gas.LegacyGasPriceProvider
|
||||
import io.novafoundation.nova.runtime.ethereum.gas.MaxPriorityFeeGasProvider
|
||||
import io.novafoundation.nova.runtime.ext.Ids
|
||||
import io.novafoundation.nova.runtime.multiNetwork.getCallEthereumApiOrThrow
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.take
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
|
||||
class GasPriceProviderIntegrationTest : BaseIntegrationTest() {
|
||||
|
||||
@Test
|
||||
fun compareLegacyAndImprovedGasPriceEstimations() = runTest {
|
||||
val api = chainRegistry.getCallEthereumApiOrThrow(Chain.Ids.MOONBEAM)
|
||||
|
||||
val legacy = LegacyGasPriceProvider(api)
|
||||
val improved = MaxPriorityFeeGasProvider(api)
|
||||
|
||||
val legacyStats = mutableSetOf<BigInteger>()
|
||||
val improvedStats = mutableSetOf<BigInteger>()
|
||||
|
||||
api.newHeadsFlow().map {
|
||||
legacyStats.add(legacy.getGasPrice())
|
||||
improvedStats.add(improved.getGasPrice())
|
||||
}
|
||||
.take(1000)
|
||||
.collect()
|
||||
|
||||
legacyStats.printStats("Legacy")
|
||||
improvedStats.printStats("Improved")
|
||||
}
|
||||
|
||||
private fun Set<BigInteger>.printStats(name: String) {
|
||||
val min = min()
|
||||
val max = max()
|
||||
|
||||
Log.d("GasPriceProviderIntegrationTest", """
|
||||
Stats for $name source
|
||||
Min: $min
|
||||
Max: $max
|
||||
Avg: ${average()}
|
||||
Max/Min ratio: ${max.divideToDecimal(min)}
|
||||
""")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.util.Log
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.LOG_TAG
|
||||
import io.novafoundation.nova.common.utils.firstLoaded
|
||||
import io.novafoundation.nova.common.utils.inBackground
|
||||
import io.novafoundation.nova.feature_account_api.di.AccountFeatureApi
|
||||
import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.ReferendumId
|
||||
import io.novafoundation.nova.feature_governance_api.data.network.blockhain.model.VoteType
|
||||
import io.novafoundation.nova.feature_governance_api.data.source.SupportedGovernanceOption
|
||||
import io.novafoundation.nova.feature_governance_api.di.GovernanceFeatureApi
|
||||
import io.novafoundation.nova.feature_governance_api.domain.referendum.filters.ReferendumType
|
||||
import io.novafoundation.nova.feature_governance_api.domain.referendum.filters.ReferendumTypeFilter
|
||||
import io.novafoundation.nova.feature_governance_impl.data.RealGovernanceAdditionalState
|
||||
import io.novafoundation.nova.runtime.ext.externalApi
|
||||
import io.novafoundation.nova.runtime.ext.utilityAsset
|
||||
import io.novafoundation.nova.runtime.multiNetwork.ChainWithAsset
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.FullChainAssetId
|
||||
import io.novasama.substrate_sdk_android.ss58.SS58Encoder.toAccountId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
|
||||
class GovernanceIntegrationTest : BaseIntegrationTest() {
|
||||
|
||||
private val accountApi = FeatureUtils.getFeature<AccountFeatureApi>(context, AccountFeatureApi::class.java)
|
||||
private val governanceApi = FeatureUtils.getFeature<GovernanceFeatureApi>(context, GovernanceFeatureApi::class.java)
|
||||
|
||||
@Test
|
||||
fun shouldRetrieveOnChainReferenda() = runTest {
|
||||
val chain = chain()
|
||||
val selectedGovernance = supportedGovernanceOption(chain, Chain.Governance.V1)
|
||||
|
||||
val onChainReferendaRepository = source(selectedGovernance).referenda
|
||||
|
||||
val referenda = onChainReferendaRepository.getAllOnChainReferenda(chain.id)
|
||||
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, referenda.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldRetrieveConvictionVotes() = runTest {
|
||||
val chain = chain()
|
||||
val selectedGovernance = supportedGovernanceOption(chain, Chain.Governance.V1)
|
||||
|
||||
val convictionVotingRepository = source(selectedGovernance).convictionVoting
|
||||
|
||||
val accountId = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY".toAccountId()
|
||||
|
||||
val votes = convictionVotingRepository.votingFor(accountId, chain.id)
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, votes.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldRetrieveTrackLocks() = runTest {
|
||||
val chain = chain()
|
||||
val selectedGovernance = supportedGovernanceOption(chain, Chain.Governance.V1)
|
||||
|
||||
val convictionVotingRepository = source(selectedGovernance).convictionVoting
|
||||
|
||||
val accountId = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY".toAccountId()
|
||||
|
||||
val fullChainAssetId = FullChainAssetId(chain.id, chain.utilityAsset.id)
|
||||
|
||||
val trackLocks = convictionVotingRepository.trackLocksFlow(accountId, fullChainAssetId).first()
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, trackLocks.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldRetrieveReferendaTracks() = runTest {
|
||||
val chain = chain()
|
||||
val selectedGovernance = supportedGovernanceOption(chain, Chain.Governance.V1)
|
||||
|
||||
val onChainReferendaRepository = source(selectedGovernance).referenda
|
||||
|
||||
val tracks = onChainReferendaRepository.getTracks(chain.id)
|
||||
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, tracks.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldRetrieveDomainReferendaPreviews() = runTest {
|
||||
val accountRepository = accountApi.provideAccountRepository()
|
||||
val referendaListInteractor = governanceApi.referendaListInteractor
|
||||
val updateSystem = governanceApi.governanceUpdateSystem
|
||||
|
||||
updateSystem.start()
|
||||
.inBackground()
|
||||
.launchIn(this)
|
||||
|
||||
val metaAccount = accountRepository.getSelectedMetaAccount()
|
||||
val accountId = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY".toAccountId()
|
||||
|
||||
val chain = chain()
|
||||
val selectedGovernance = supportedGovernanceOption(chain, Chain.Governance.V1)
|
||||
|
||||
val filterFlow: Flow<ReferendumTypeFilter> = flow {
|
||||
val referendaFilter = ReferendumTypeFilter(ReferendumType.ALL)
|
||||
emit(referendaFilter)
|
||||
}
|
||||
|
||||
val referendaByGroup = referendaListInteractor.referendaListStateFlow(metaAccount, accountId, selectedGovernance, this, filterFlow).firstLoaded()
|
||||
val referenda = referendaByGroup.groupedReferenda.values.flatten()
|
||||
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, referenda.joinToString("\n"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldRetrieveDomainReferendumDetails() = runTest {
|
||||
val referendumDetailsInteractor = governanceApi.referendumDetailsInteractor
|
||||
val updateSystem = governanceApi.governanceUpdateSystem
|
||||
|
||||
updateSystem.start()
|
||||
.inBackground()
|
||||
.launchIn(this)
|
||||
|
||||
val accountId = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY".toAccountId()
|
||||
val referendumId = ReferendumId(BigInteger.ZERO)
|
||||
val chain = chain()
|
||||
val selectedGovernance = supportedGovernanceOption(chain, Chain.Governance.V1)
|
||||
|
||||
val referendumDetails = referendumDetailsInteractor.referendumDetailsFlow(referendumId, selectedGovernance, accountId, CoroutineScope(Dispatchers.Main))
|
||||
.first()
|
||||
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, referendumDetails.toString())
|
||||
|
||||
val callDetails = referendumDetailsInteractor.detailsFor(
|
||||
preImage = referendumDetails?.onChainMetadata!!.preImage!!,
|
||||
chain = chain
|
||||
)
|
||||
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, callDetails.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldRetrieveVoters() = runTest {
|
||||
val interactor = governanceApi.referendumVotersInteractor
|
||||
|
||||
val referendumId = ReferendumId(BigInteger.ZERO)
|
||||
val referendumVoters = interactor.votersFlow(referendumId, VoteType.AYE)
|
||||
.first()
|
||||
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, referendumVoters.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldFetchDelegatesList() = runTest {
|
||||
val interactor = governanceApi.delegateListInteractor
|
||||
val updateSystem = governanceApi.governanceUpdateSystem
|
||||
|
||||
updateSystem.start()
|
||||
.inBackground()
|
||||
.launchIn(this)
|
||||
|
||||
val chain = kusama()
|
||||
val delegates = interactor.getDelegates(
|
||||
governanceOption = supportedGovernanceOption(chain, Chain.Governance.V2),
|
||||
scope = this
|
||||
)
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, delegates.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldFetchDelegateDetails() = runTest {
|
||||
val delegateAccountId = "DCZyhphXsRLcW84G9WmWEXtAA8DKGtVGSFZLJYty8Ajjyfa".toAccountId() // ChaosDAO
|
||||
|
||||
val interactor = governanceApi.delegateDetailsInteractor
|
||||
val updateSystem = governanceApi.governanceUpdateSystem
|
||||
|
||||
updateSystem.start()
|
||||
.inBackground()
|
||||
.launchIn(this)
|
||||
|
||||
val delegate = interactor.delegateDetailsFlow(delegateAccountId)
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, delegate.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldFetchChooseTrackData() = runTest {
|
||||
val interactor = governanceApi.newDelegationChooseTrackInteractor
|
||||
val updateSystem = governanceApi.governanceUpdateSystem
|
||||
|
||||
updateSystem.start()
|
||||
.inBackground()
|
||||
.launchIn(this)
|
||||
|
||||
val trackData = interactor.observeNewDelegationTrackData().first()
|
||||
|
||||
Log.d(
|
||||
this@GovernanceIntegrationTest.LOG_TAG,
|
||||
"""
|
||||
Available: ${trackData.trackPartition.available.size}
|
||||
Already voted: ${trackData.trackPartition.alreadyVoted.size}
|
||||
Already delegated: ${trackData.trackPartition.alreadyDelegated.size}
|
||||
Presets: ${trackData.presets}
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldFetchDelegators() = runTest {
|
||||
val delegateAddress = "DCZyhphXsRLcW84G9WmWEXtAA8DKGtVGSFZLJYty8Ajjyfa" // ChaosDAO
|
||||
|
||||
val interactor = governanceApi.delegateDelegatorsInteractor
|
||||
val updateSystem = governanceApi.governanceUpdateSystem
|
||||
|
||||
updateSystem.start()
|
||||
.inBackground()
|
||||
.launchIn(this)
|
||||
|
||||
val delegators = interactor.delegatorsFlow(delegateAddress.toAccountId()).first()
|
||||
|
||||
Log.d(this@GovernanceIntegrationTest.LOG_TAG, delegators.toString())
|
||||
}
|
||||
|
||||
private suspend fun source(supportedGovernance: SupportedGovernanceOption) = governanceApi.governanceSourceRegistry.sourceFor(supportedGovernance)
|
||||
|
||||
private fun supportedGovernanceOption(chain: Chain, governance: Chain.Governance) =
|
||||
SupportedGovernanceOption(
|
||||
ChainWithAsset(chain, chain.utilityAsset),
|
||||
RealGovernanceAdditionalState(
|
||||
governance,
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
private suspend fun chain(): Chain = chainRegistry.currentChains.map { chains ->
|
||||
chains.find { it.governance.isNotEmpty() }
|
||||
}
|
||||
.filterNotNull()
|
||||
.first()
|
||||
|
||||
private suspend fun kusama(): Chain = chainRegistry.currentChains.mapNotNull { chains ->
|
||||
chains.find { it.externalApi<Chain.ExternalApi.GovernanceDelegations>() != null }
|
||||
}.first()
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,60 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.feature_account_api.di.AccountFeatureApi
|
||||
import io.novafoundation.nova.feature_nft_api.NftFeatureApi
|
||||
import io.novafoundation.nova.feature_nft_api.data.model.isFullySynced
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeComponent
|
||||
import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
|
||||
class NftFullSyncIntegrationTest {
|
||||
|
||||
private val nftApi = FeatureUtils.getFeature<NftFeatureApi>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
NftFeatureApi::class.java
|
||||
)
|
||||
|
||||
private val accountApi = FeatureUtils.getFeature<AccountFeatureApi>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
AccountFeatureApi::class.java
|
||||
)
|
||||
|
||||
private val runtimeApi = FeatureUtils.getFeature<RuntimeComponent>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
RuntimeApi::class.java
|
||||
)
|
||||
|
||||
private val externalRequirementFlow = runtimeApi.externalRequirementFlow()
|
||||
|
||||
@Test
|
||||
fun testFullSyncIntegration(): Unit = runBlocking {
|
||||
externalRequirementFlow.emit(ChainConnection.ExternalRequirement.ALLOWED)
|
||||
|
||||
val metaAccount = accountApi.accountUseCase().getSelectedMetaAccount()
|
||||
|
||||
val nftRepository = nftApi.nftRepository
|
||||
|
||||
nftRepository.initialNftSync(metaAccount, true)
|
||||
|
||||
nftRepository.allNftFlow(metaAccount)
|
||||
.map { nfts -> nfts.filter { !it.isFullySynced } }
|
||||
.takeWhile { it.isNotEmpty() }
|
||||
.onEach { unsyncedNfts ->
|
||||
unsyncedNfts.forEach { nftRepository.fullNftSync(it) }
|
||||
}
|
||||
.onCompletion {
|
||||
print("Full sync done")
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.bindAccountId
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.bindBoolean
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.bindString
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.cast
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.getTyped
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.LOG_TAG
|
||||
import io.novafoundation.nova.common.utils.uniques
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeComponent
|
||||
import io.novafoundation.nova.runtime.ext.addressOf
|
||||
import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection
|
||||
import io.novafoundation.nova.runtime.storage.source.multi.MultiQueryBuilder
|
||||
import io.novafoundation.nova.runtime.storage.source.query.multi
|
||||
import io.novasama.substrate_sdk_android.runtime.AccountId
|
||||
import io.novasama.substrate_sdk_android.runtime.definitions.types.composite.Struct
|
||||
import io.novasama.substrate_sdk_android.runtime.metadata.storage
|
||||
import io.novasama.substrate_sdk_android.ss58.SS58Encoder.toAccountId
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
|
||||
data class UniquesClass(
|
||||
val id: BigInteger,
|
||||
val metadata: Metadata?,
|
||||
val details: Details
|
||||
) {
|
||||
data class Metadata(
|
||||
val deposit: BigInteger,
|
||||
val data: String,
|
||||
)
|
||||
|
||||
data class Details(
|
||||
val instances: BigInteger,
|
||||
val frozen: Boolean
|
||||
)
|
||||
}
|
||||
|
||||
data class UniquesInstance(
|
||||
val collection: UniquesClass,
|
||||
val id: BigInteger,
|
||||
val metadata: Metadata?,
|
||||
val details: Details
|
||||
) {
|
||||
|
||||
data class Metadata(
|
||||
val data: String,
|
||||
)
|
||||
|
||||
data class Details(
|
||||
val owner: String,
|
||||
val frozen: Boolean,
|
||||
)
|
||||
}
|
||||
|
||||
class NftUniquesIntegrationTest {
|
||||
|
||||
private val chainGenesis = "48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a"
|
||||
|
||||
private val runtimeApi = FeatureUtils.getFeature<RuntimeComponent>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
RuntimeApi::class.java
|
||||
)
|
||||
|
||||
private val chainRegistry = runtimeApi.chainRegistry()
|
||||
private val externalRequirementFlow = runtimeApi.externalRequirementFlow()
|
||||
|
||||
private val storageRemoteSource = runtimeApi.remoteStorageSource()
|
||||
|
||||
@Test
|
||||
fun testUniquesIntegration(): Unit = runBlocking {
|
||||
chainRegistry.currentChains.first() // wait till chains are ready
|
||||
externalRequirementFlow.emit(ChainConnection.ExternalRequirement.ALLOWED)
|
||||
|
||||
val chain = chainRegistry.getChain(chainGenesis)
|
||||
|
||||
val accountId = "JGKSibhyZgzY7jEe5a9gdybDEbqNNRSxYyJJmeeycbCbQ5v".toAccountId()
|
||||
|
||||
val instances = storageRemoteSource.query(chainGenesis) {
|
||||
val classesWithInstances = runtime.metadata.uniques().storage("Account").keys(accountId)
|
||||
.map { (_: AccountId, collection: BigInteger, instance: BigInteger) ->
|
||||
listOf(collection, instance)
|
||||
}
|
||||
|
||||
val classesIds = classesWithInstances.map { (collection, _) -> collection }.distinct()
|
||||
|
||||
val classDetailsDescriptor: MultiQueryBuilder.Descriptor<BigInteger, UniquesClass.Details>
|
||||
val classMetadatasDescriptor: MultiQueryBuilder.Descriptor<BigInteger, UniquesClass.Metadata?>
|
||||
val instancesDetailsDescriptor: MultiQueryBuilder.Descriptor<Pair<BigInteger, BigInteger>, UniquesInstance.Details>
|
||||
val instancesMetadataDescriptor: MultiQueryBuilder.Descriptor<Pair<BigInteger, BigInteger>, UniquesInstance.Metadata?>
|
||||
|
||||
val multiQueryResults = multi {
|
||||
classDetailsDescriptor = runtime.metadata.uniques().storage("Class").querySingleArgKeys(
|
||||
keysArgs = classesIds,
|
||||
keyExtractor = { it.component1<BigInteger>() },
|
||||
binding = { parsedValue ->
|
||||
val classDetailsStruct = parsedValue.cast<Struct.Instance>()
|
||||
|
||||
UniquesClass.Details(
|
||||
instances = classDetailsStruct.getTyped("instances"),
|
||||
frozen = classDetailsStruct.getTyped("isFrozen")
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
classMetadatasDescriptor = runtime.metadata.uniques().storage("ClassMetadataOf").querySingleArgKeys(
|
||||
keysArgs = classesIds,
|
||||
keyExtractor = { it.component1<BigInteger>() },
|
||||
binding = { parsedValue ->
|
||||
parsedValue?.cast<Struct.Instance>()?.let { classMetadataStruct ->
|
||||
UniquesClass.Metadata(
|
||||
deposit = classMetadataStruct.getTyped("deposit"),
|
||||
data = bindString(classMetadataStruct["data"])
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
instancesDetailsDescriptor = runtime.metadata.uniques().storage("Asset").queryKeys(
|
||||
keysArgs = classesWithInstances,
|
||||
keyExtractor = { it.component1<BigInteger>() to it.component2<BigInteger>() },
|
||||
binding = { parsedValue ->
|
||||
val instanceDetailsStruct = parsedValue.cast<Struct.Instance>()
|
||||
|
||||
UniquesInstance.Details(
|
||||
owner = chain.addressOf(bindAccountId(instanceDetailsStruct["owner"])),
|
||||
frozen = bindBoolean(instanceDetailsStruct["isFrozen"])
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
instancesMetadataDescriptor = runtime.metadata.uniques().storage("InstanceMetadataOf").queryKeys(
|
||||
keysArgs = classesWithInstances,
|
||||
keyExtractor = { it.component1<BigInteger>() to it.component2<BigInteger>() },
|
||||
binding = { parsedValue ->
|
||||
parsedValue?.cast<Struct.Instance>()?.let {
|
||||
UniquesInstance.Metadata(
|
||||
data = bindString(it["data"])
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val classDetails = multiQueryResults[classDetailsDescriptor]
|
||||
|
||||
val classMetadatas = multiQueryResults[classMetadatasDescriptor]
|
||||
|
||||
val instancesDetails = multiQueryResults[instancesDetailsDescriptor]
|
||||
|
||||
val instancesMetadatas = multiQueryResults[instancesMetadataDescriptor]
|
||||
|
||||
val classes = classesIds.associateWith { classId ->
|
||||
UniquesClass(
|
||||
id = classId,
|
||||
metadata = classMetadatas[classId],
|
||||
details = classDetails.getValue(classId)
|
||||
)
|
||||
}
|
||||
|
||||
classesWithInstances.map { (collectionId, instanceId) ->
|
||||
val instanceKey = collectionId to instanceId
|
||||
|
||||
UniquesInstance(
|
||||
collection = classes.getValue(collectionId),
|
||||
id = instanceId,
|
||||
metadata = instancesMetadatas[instanceKey],
|
||||
details = instancesDetails.getValue(instanceKey)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(LOG_TAG, instances.toString())
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.util.Log
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.Fraction
|
||||
import io.novafoundation.nova.common.utils.Perbill
|
||||
import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi
|
||||
import io.novafoundation.nova.feature_staking_api.domain.nominationPool.model.PoolId
|
||||
import io.novafoundation.nova.feature_staking_impl.data.StakingOption
|
||||
import io.novafoundation.nova.feature_staking_impl.data.StakingSharedState.OptionAdditionalData
|
||||
import io.novafoundation.nova.feature_staking_impl.di.StakingFeatureComponent
|
||||
import io.novafoundation.nova.feature_staking_impl.domain.nominationPools.common.rewards.NominationPoolRewardCalculator
|
||||
import io.novafoundation.nova.runtime.ext.utilityAsset
|
||||
import io.novafoundation.nova.runtime.multiNetwork.ChainWithAsset
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain.Asset.StakingType
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import org.junit.Test
|
||||
|
||||
class NominationPoolsRewardCalculatorIntegrationTest : BaseIntegrationTest() {
|
||||
|
||||
private val stakingFeatureComponent = FeatureUtils.getFeature<StakingFeatureComponent>(context, StakingFeatureApi::class.java)
|
||||
|
||||
private val nominationPoolRewardCalculatorFactory = stakingFeatureComponent.nominationPoolRewardCalculatorFactory
|
||||
private val stakingUpdateSystem = stakingFeatureComponent.stakingUpdateSystem
|
||||
private val stakingSharedState = stakingFeatureComponent.stakingSharedState
|
||||
|
||||
@Test
|
||||
fun testRewardCalculator() = runTest {
|
||||
val polkadot = chainRegistry.polkadot()
|
||||
val stakingOption = StakingOption(
|
||||
assetWithChain = ChainWithAsset(polkadot, polkadot.utilityAsset),
|
||||
additional = OptionAdditionalData(StakingType.NOMINATION_POOLS)
|
||||
)
|
||||
|
||||
stakingSharedState.setSelectedOption(stakingOption)
|
||||
|
||||
stakingUpdateSystem.start()
|
||||
.launchIn(this)
|
||||
|
||||
val rewardCalculator = nominationPoolRewardCalculatorFactory.create(stakingOption, sharedComputationScope = this)
|
||||
|
||||
Log.d("NominationPoolsRewardCalculatorIntegrationTest", "Max APY: ${rewardCalculator.maxAPY}")
|
||||
Log.d("NominationPoolsRewardCalculatorIntegrationTest", "APY for Nova Pool: ${rewardCalculator.apyFor(54)}")
|
||||
}
|
||||
|
||||
private fun NominationPoolRewardCalculator.apyFor(poolId: Int): Fraction? {
|
||||
return apyFor(PoolId(poolId))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.domain.ExtendedLoadingState
|
||||
import io.novafoundation.nova.common.utils.inBackground
|
||||
import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi
|
||||
import io.novafoundation.nova.feature_staking_api.domain.dashboard.model.AggregatedStakingDashboardOption
|
||||
import io.novafoundation.nova.feature_staking_api.domain.dashboard.model.StakingDashboard
|
||||
import io.novafoundation.nova.feature_staking_api.domain.dashboard.model.isSyncing
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import org.junit.Test
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class StakingDashboardIntegrationTest: BaseIntegrationTest() {
|
||||
|
||||
private val stakingApi = FeatureUtils.getFeature<StakingFeatureApi>(context, StakingFeatureApi::class.java)
|
||||
|
||||
private val interactor = stakingApi.dashboardInteractor
|
||||
|
||||
private val updateSystem = stakingApi.dashboardUpdateSystem
|
||||
|
||||
private val gson = GsonBuilder()
|
||||
.registerTypeHierarchyAdapter(AggregatedStakingDashboardOption::class.java, AggregatedStakingDashboardOptionDesirializer())
|
||||
.create()
|
||||
|
||||
@Test
|
||||
fun syncStakingDashboard() = runTest {
|
||||
updateSystem.start()
|
||||
.inBackground()
|
||||
.launchIn(this)
|
||||
|
||||
interactor.stakingDashboardFlow()
|
||||
.inBackground()
|
||||
.collect(::logDashboard)
|
||||
}
|
||||
|
||||
private fun logDashboard(dashboard: ExtendedLoadingState<StakingDashboard>) {
|
||||
if (dashboard !is ExtendedLoadingState.Loaded) return
|
||||
|
||||
val serialized = gson.toJson(dashboard)
|
||||
|
||||
val message = """
|
||||
Dashboard state:
|
||||
Syncing items: ${dashboard.data.syncingItemsCount()}
|
||||
$serialized
|
||||
""".trimIndent()
|
||||
|
||||
Log.d("StakingDashboardIntegrationTest", message)
|
||||
}
|
||||
|
||||
private class AggregatedStakingDashboardOptionDesirializer : JsonSerializer<AggregatedStakingDashboardOption<*>> {
|
||||
override fun serialize(src: AggregatedStakingDashboardOption<*>, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
|
||||
return JsonObject().apply {
|
||||
add("chain", JsonPrimitive(src.chain.name))
|
||||
add("stakingState", context.serialize(src.stakingState))
|
||||
add("syncing", context.serialize(src.syncingStage))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun StakingDashboard.syncingItemsCount(): Int {
|
||||
return withoutStake.count { it.syncingStage.isSyncing() } + hasStake.count { it.syncingStage.isSyncing() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.util.Log
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.LOG_TAG
|
||||
import io.novafoundation.nova.feature_staking_api.data.parachainStaking.turing.repository.AutomationAction
|
||||
import io.novafoundation.nova.feature_staking_api.data.parachainStaking.turing.repository.OptimalAutomationRequest
|
||||
import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi
|
||||
import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry
|
||||
import io.novafoundation.nova.runtime.multiNetwork.findChain
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
|
||||
class TuringAutomationIntegrationTest : BaseIntegrationTest() {
|
||||
|
||||
private val stakingApi = FeatureUtils.getFeature<StakingFeatureApi>(context, StakingFeatureApi::class.java)
|
||||
private val automationTasksRepository = stakingApi.turingAutomationRepository
|
||||
|
||||
@Test
|
||||
fun calculateOptimalAutoCompounding(){
|
||||
runBlocking {
|
||||
val chain = chainRegistry.findTuringChain()
|
||||
val request = OptimalAutomationRequest(
|
||||
collator = "6AEG2WKRVvZteWWT3aMkk2ZE21FvURqiJkYpXimukub8Zb9C",
|
||||
amount = BigInteger("1000000000000")
|
||||
)
|
||||
|
||||
val response = automationTasksRepository.calculateOptimalAutomation(chain.id, request)
|
||||
|
||||
Log.d(LOG_TAG, response.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun calculateAutoCompoundExecutionFees(){
|
||||
runBlocking {
|
||||
val chain = chainRegistry.findTuringChain()
|
||||
val fees = automationTasksRepository.getTimeAutomationFees(chain.id, AutomationAction.AUTO_COMPOUND_DELEGATED_STAKE, executions = 1)
|
||||
|
||||
Log.d(LOG_TAG, fees.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun ChainRegistry.findTuringChain() = findChain { it.name == "Turing" }!!
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package io.novafoundation.nova
|
||||
|
||||
import android.util.Log
|
||||
import io.novafoundation.nova.common.utils.LOG_TAG
|
||||
import io.novafoundation.nova.common.utils.second
|
||||
import io.novafoundation.nova.core.ethereum.Web3Api
|
||||
import io.novafoundation.nova.core.ethereum.log.Topic
|
||||
import io.novafoundation.nova.feature_wallet_api.data.network.blockhain.types.Balance
|
||||
import io.novafoundation.nova.runtime.ethereum.contract.base.querySingle
|
||||
import io.novafoundation.nova.runtime.ethereum.contract.erc20.Erc20Queries
|
||||
import io.novafoundation.nova.runtime.ethereum.contract.erc20.Erc20Standard
|
||||
import io.novafoundation.nova.runtime.ethereum.sendSuspend
|
||||
import io.novafoundation.nova.runtime.multiNetwork.getEthereumApiOrThrow
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.reactive.asFlow
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import org.web3j.abi.EventEncoder
|
||||
import org.web3j.abi.TypeEncoder
|
||||
import org.web3j.abi.datatypes.Address
|
||||
import org.web3j.protocol.core.DefaultBlockParameterName
|
||||
import java.math.BigInteger
|
||||
|
||||
class Erc20Transfer(
|
||||
val txHash: String,
|
||||
val blockNumber: String,
|
||||
val from: String,
|
||||
val to: String,
|
||||
val contract: String,
|
||||
val amount: BigInteger,
|
||||
)
|
||||
|
||||
class Web3jServiceIntegrationTest : BaseIntegrationTest() {
|
||||
|
||||
@Test
|
||||
fun shouldFetchBalance(): Unit = runBlocking {
|
||||
val web3j = moonbeamWeb3j()
|
||||
val balance = web3j.ethGetBalance("0xf977814e90da44bfa03b6295a0616a897441acec", DefaultBlockParameterName.LATEST).sendSuspend()
|
||||
Log.d(LOG_TAG, balance.balance.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldFetchComplexStructure(): Unit = runBlocking {
|
||||
val web3j = moonbeamWeb3j()
|
||||
val block = web3j.ethGetBlockByNumber(DefaultBlockParameterName.LATEST, true).sendSuspend()
|
||||
Log.d(LOG_TAG, block.block.hash)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldSubscribeToNewHeadEvents(): Unit = runBlocking {
|
||||
val web3j = moonbeamWeb3j()
|
||||
val newHead = web3j.newHeadsNotifications().asFlow().first()
|
||||
|
||||
Log.d(LOG_TAG, "New head appended to chain: ${newHead.params.result.hash}")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldSubscribeBalances(): Unit = runBlocking {
|
||||
val web3j = moonbeamWeb3j()
|
||||
val accountAddress = "0x4A43C16107591AE5Ec904e584ed4Bb05386F98f7"
|
||||
val moonbeamUsdc = "0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b"
|
||||
|
||||
val balanceUpdates = web3j.erc20BalanceFlow(accountAddress, moonbeamUsdc).take(2).toList()
|
||||
|
||||
error("Initial balance: ${balanceUpdates.first()}, new balance: ${balanceUpdates.second()}")
|
||||
}
|
||||
|
||||
private fun Web3Api.erc20BalanceFlow(account: String, contract: String): Flow<Balance> {
|
||||
return flow {
|
||||
val erc20 = Erc20Standard().querySingle(contract, web3j = this@erc20BalanceFlow)
|
||||
val initialBalance = erc20.balanceOfAsync(account).await()
|
||||
|
||||
emit(initialBalance)
|
||||
|
||||
val changes = accountErcTransfersFlow(account).map {
|
||||
erc20.balanceOfAsync(account).await()
|
||||
}
|
||||
|
||||
emitAll(changes)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun Web3Api.accountErcTransfersFlow(address: String): Flow<Erc20Transfer> {
|
||||
val addressTopic = TypeEncoder.encode(Address(address))
|
||||
|
||||
val transferEvent = Erc20Queries.TRANSFER_EVENT
|
||||
val transferEventSignature = EventEncoder.encode(transferEvent)
|
||||
val contractAddresses = emptyList<String>() // everything
|
||||
|
||||
val erc20SendTopic = listOf(
|
||||
Topic.Single(transferEventSignature), // zero-th topic is event signature
|
||||
Topic.AnyOf(addressTopic), // our account as `from`
|
||||
)
|
||||
|
||||
val erc20ReceiveTopic = listOf(
|
||||
Topic.Single(transferEventSignature), // zero-th topic is event signature
|
||||
Topic.Any, // anyone is `from`
|
||||
Topic.AnyOf(addressTopic) // out account as `to`
|
||||
)
|
||||
|
||||
val receiveTransferNotifications = logsNotifications(contractAddresses, erc20ReceiveTopic)
|
||||
val sendTransferNotifications = logsNotifications(contractAddresses, erc20SendTopic)
|
||||
|
||||
val transferNotifications = merge(receiveTransferNotifications, sendTransferNotifications)
|
||||
|
||||
return transferNotifications.map { logNotification ->
|
||||
val log = logNotification.params.result
|
||||
|
||||
val contract = log.address
|
||||
val event = Erc20Queries.parseTransferEvent(log)
|
||||
|
||||
Erc20Transfer(
|
||||
txHash = log.transactionHash,
|
||||
blockNumber = log.blockNumber,
|
||||
from = event.from.value,
|
||||
to = event.to.value,
|
||||
contract = contract,
|
||||
amount = event.amount.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun moonbeamWeb3j(): Web3Api {
|
||||
val moonbeamChainId = "fe58ea77779b7abda7da4ec526d14db9b1e9cd40a217c34892af80a9b332b76d"
|
||||
|
||||
return chainRegistry.getEthereumApiOrThrow(moonbeamChainId, Chain.Node.ConnectionType.WSS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package io.novafoundation.nova.balances
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.google.gson.Gson
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.AccountInfo
|
||||
import io.novafoundation.nova.common.data.network.runtime.binding.bindAccountInfo
|
||||
import io.novafoundation.nova.common.di.FeatureUtils
|
||||
import io.novafoundation.nova.common.utils.fromJson
|
||||
import io.novafoundation.nova.common.utils.hasModule
|
||||
import io.novafoundation.nova.common.utils.system
|
||||
import io.novafoundation.nova.core.model.CryptoType
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountLocal
|
||||
import io.novafoundation.nova.feature_account_api.data.ethereum.transaction.TransactionOrigin
|
||||
import io.novafoundation.nova.feature_account_api.di.AccountFeatureApi
|
||||
import io.novafoundation.nova.feature_account_api.domain.model.LightMetaAccount
|
||||
import io.novafoundation.nova.feature_account_api.domain.model.MetaAccount
|
||||
import io.novafoundation.nova.feature_account_impl.di.AccountFeatureComponent
|
||||
import io.novafoundation.nova.feature_account_impl.domain.account.model.DefaultMetaAccount
|
||||
import io.novafoundation.nova.runtime.BuildConfig.TEST_CHAINS_URL
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeComponent
|
||||
import io.novafoundation.nova.runtime.extrinsic.systemRemark
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
|
||||
import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection
|
||||
import io.novafoundation.nova.runtime.multiNetwork.getSocket
|
||||
import io.novasama.substrate_sdk_android.extensions.fromHex
|
||||
import io.novasama.substrate_sdk_android.runtime.metadata.storage
|
||||
import io.novasama.substrate_sdk_android.runtime.metadata.storageKey
|
||||
import io.novasama.substrate_sdk_android.wsrpc.networkStateFlow
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import java.math.BigInteger
|
||||
import java.math.BigInteger.ZERO
|
||||
import java.net.URL
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class BalancesIntegrationTest(
|
||||
private val testChainId: String,
|
||||
private val testChainName: String,
|
||||
private val testAccount: String
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{1}")
|
||||
fun data(): List<Array<String?>> {
|
||||
val arrayOfNetworks: Array<TestData> = Gson().fromJson(URL(TEST_CHAINS_URL).readText())
|
||||
return arrayOfNetworks.map { arrayOf(it.chainId, it.name, it.account) }
|
||||
}
|
||||
|
||||
class TestData(
|
||||
val chainId: String,
|
||||
val name: String,
|
||||
val account: String?
|
||||
)
|
||||
}
|
||||
|
||||
private val maxAmount = BigInteger.valueOf(10).pow(30)
|
||||
|
||||
private val runtimeApi = FeatureUtils.getFeature<RuntimeComponent>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
RuntimeApi::class.java
|
||||
)
|
||||
|
||||
private val accountApi = FeatureUtils.getFeature<AccountFeatureComponent>(
|
||||
ApplicationProvider.getApplicationContext<Context>(),
|
||||
AccountFeatureApi::class.java
|
||||
)
|
||||
|
||||
private val chainRegistry = runtimeApi.chainRegistry()
|
||||
private val externalRequirementFlow = runtimeApi.externalRequirementFlow()
|
||||
|
||||
private val remoteStorage = runtimeApi.remoteStorageSource()
|
||||
|
||||
private val extrinsicService = accountApi.extrinsicService()
|
||||
|
||||
@Before
|
||||
fun before() = runBlocking {
|
||||
externalRequirementFlow.emit(ChainConnection.ExternalRequirement.ALLOWED)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBalancesLoading() = runBlocking(Dispatchers.Default) {
|
||||
val chains = chainRegistry.getChain(testChainId)
|
||||
|
||||
val freeBalance = testBalancesInChainAsync(chains, testAccount)?.data?.free ?: error("Balance was null")
|
||||
|
||||
assertTrue("Free balance: $freeBalance is less than $maxAmount", maxAmount > freeBalance)
|
||||
assertTrue("Free balance: $freeBalance is greater than 0", ZERO < freeBalance)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFeeLoading() = runBlocking(Dispatchers.Default) {
|
||||
val chains = chainRegistry.getChain(testChainId)
|
||||
|
||||
testFeeLoadingAsync(chains)
|
||||
|
||||
Unit
|
||||
}
|
||||
|
||||
private suspend fun testBalancesInChainAsync(chain: Chain, currentAccount: String): AccountInfo? {
|
||||
return coroutineScope {
|
||||
try {
|
||||
withTimeout(80.seconds) {
|
||||
remoteStorage.query(
|
||||
chainId = chain.id,
|
||||
keyBuilder = { it.metadata.system().storage("Account").storageKey(it, currentAccount.fromHex()) },
|
||||
binding = { scale, runtime -> scale?.let { bindAccountInfo(scale, runtime) } }
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw Exception("Socket state: ${chainRegistry.getSocket(chain.id).networkStateFlow().first()}, error: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun testFeeLoadingAsync(chain: Chain) {
|
||||
return coroutineScope {
|
||||
withTimeout(80.seconds) {
|
||||
extrinsicService.estimateFee(chain, testTransactionOrigin()) {
|
||||
systemRemark(byteArrayOf(0))
|
||||
|
||||
val haveBatch = runtime.metadata.hasModule("Utility")
|
||||
if (haveBatch) {
|
||||
systemRemark(byteArrayOf(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun testTransactionOrigin(): TransactionOrigin = TransactionOrigin.Wallet(
|
||||
createTestMetaAccount()
|
||||
)
|
||||
|
||||
private fun createTestMetaAccount(): MetaAccount {
|
||||
val metaAccount = DefaultMetaAccount(
|
||||
id = 0,
|
||||
globallyUniqueId = MetaAccountLocal.generateGloballyUniqueId(),
|
||||
substratePublicKey = testAccount.fromHex(),
|
||||
substrateCryptoType = CryptoType.SR25519,
|
||||
substrateAccountId = testAccount.fromHex(),
|
||||
ethereumAddress = testAccount.fromHex(),
|
||||
ethereumPublicKey = testAccount.fromHex(),
|
||||
isSelected = true,
|
||||
name = "Test",
|
||||
type = LightMetaAccount.Type.WATCH_ONLY,
|
||||
status = LightMetaAccount.Status.ACTIVE,
|
||||
chainAccounts = emptyMap(),
|
||||
parentMetaId = null
|
||||
)
|
||||
return metaAccount
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">[Debug] Pezkuwi</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">[Dev] Pezkuwi</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,234 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<uses-permission
|
||||
android:name="com.google.android.gms.permission.AD_ID"
|
||||
tools:node="remove" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH"
|
||||
android:maxSdkVersion="30" />
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH_ADMIN"
|
||||
android:maxSdkVersion="30" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH_SCAN"
|
||||
tools:targetApi="s" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
|
||||
<application
|
||||
android:name="io.novafoundation.nova.app.App"
|
||||
android:allowBackup="false"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:supportsRtl="true"
|
||||
tools:replace="android:allowBackup,android:fullBackupContent,android:dataExtractionRules"
|
||||
tools:targetApi="s">
|
||||
|
||||
<activity
|
||||
android:name="io.novafoundation.nova.app.root.presentation.RootActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.NovaFoundation.Nova"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
|
||||
<intent-filter tools:ignore="AppLinkUrlError">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/json" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="true">
|
||||
<data
|
||||
android:host="buy-success"
|
||||
android:scheme="pezkuwi" />
|
||||
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<data
|
||||
android:host="@string/deep_linking_host"
|
||||
android:scheme="@string/deep_linking_scheme" />
|
||||
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="true">
|
||||
<data android:host="request" />
|
||||
<data android:scheme="pezkuwiwallet" />
|
||||
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="true">
|
||||
<data android:host="wc" />
|
||||
<data android:scheme="pezkuwiwallet" />
|
||||
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="true">
|
||||
<data
|
||||
android:pathPattern="/.*@2"
|
||||
android:scheme="wc" />
|
||||
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="http" />
|
||||
<data android:host="app.pezkuwichain.io" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="https"/>
|
||||
<data android:host="@string/branch_io_link_host"/>
|
||||
<data android:host="@string/branch_io_link_host_alternate"/>
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.journeyapps.barcodescanner.CaptureActivity"
|
||||
android:screenOrientation="fullSensor"
|
||||
android:theme="@style/Theme.NovaFoundation.Nova"
|
||||
tools:replace="android:theme,screenOrientation" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
|
||||
<receiver
|
||||
android:name="io.novafoundation.nova.feature_account_impl.presentation.exporting.json.ShareCompletedReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver
|
||||
android:name="io.novafoundation.nova.feature_ledger_impl.sdk.connection.usb.UsbLedgerConnection$UsbPermissionReceiver"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_USB" />
|
||||
|
||||
<service
|
||||
android:name="io.novafoundation.nova.feature_push_notifications.NovaFirebaseMessagingService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@drawable/ic_pezkuwi" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_color"
|
||||
android:resource="@color/android_system_accent" />
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_messaging_auto_init_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||
android:value="@string/default_notification_channel_id" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.novafoundation.nova.transactions_notification_channel_id"
|
||||
android:value="@string/transactions_notification_channel_id" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.novafoundation.nova.governance_notification_channel_id"
|
||||
android:value="@string/governance_notification_channel_id" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.novafoundation.nova.staking_notification_channel_id"
|
||||
android:value="@string/staking_notification_channel_id" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.novafoundation.nova.multisigs_notification_channel_id"
|
||||
android:value="@string/multisigs_notification_channel_id" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.branch.sdk.BranchKey"
|
||||
android:value="key_live_dsxlmUqNhbtOYX6e7cfgrpkbqsjGPYBf" />
|
||||
|
||||
<meta-data android:name="io.branch.sdk.TestMode" android:value="false" />
|
||||
|
||||
</application>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent>
|
||||
|
||||
<!-- Allow Google Pay feature in WebView -->
|
||||
<intent>
|
||||
<action android:name="org.chromium.intent.action.PAY" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="org.chromium.intent.action.IS_READY_TO_PAY" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
@@ -0,0 +1,100 @@
|
||||
package io.novafoundation.nova.app
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import com.walletconnect.android.Core
|
||||
import com.walletconnect.android.CoreClient
|
||||
import com.walletconnect.android.relay.ConnectionType
|
||||
import com.walletconnect.web3.wallet.client.Wallet
|
||||
import com.walletconnect.web3.wallet.client.Web3Wallet
|
||||
import io.novafoundation.nova.app.di.app.AppComponent
|
||||
import io.novafoundation.nova.app.di.deps.FeatureHolderManager
|
||||
import io.novafoundation.nova.common.di.CommonApi
|
||||
import io.novafoundation.nova.common.di.FeatureContainer
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
import io.novafoundation.nova.common.resources.LanguagesHolder
|
||||
import io.novafoundation.nova.common.utils.coroutines.RootScope
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.branchIo.BranchIOLinkHandler
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.BuildConfig
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val WC_REDIRECT_URL = "pezkuwiwallet://request"
|
||||
|
||||
open class App : Application(), FeatureContainer {
|
||||
|
||||
@Inject
|
||||
lateinit var featureHolderManager: FeatureHolderManager
|
||||
|
||||
private lateinit var appComponent: AppComponent
|
||||
|
||||
private val languagesHolder: LanguagesHolder = LanguagesHolder()
|
||||
|
||||
// App global scope using for processes that should work while app is alive
|
||||
private val rootScope = RootScope()
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
val contextManager = ContextManager.getInstanceOrInit(base, languagesHolder)
|
||||
super.attachBaseContext(contextManager.setLocale(base))
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
val contextManager = ContextManager.getInstanceOrInit(this, languagesHolder)
|
||||
contextManager.setLocale(this)
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
val contextManger = ContextManager.getInstanceOrInit(this, languagesHolder)
|
||||
|
||||
appComponent = io.novafoundation.nova.app.di.app.DaggerAppComponent
|
||||
.builder()
|
||||
.application(this)
|
||||
.contextManager(contextManger)
|
||||
.rootScope(rootScope)
|
||||
.build()
|
||||
|
||||
appComponent.inject(this)
|
||||
|
||||
BranchIOLinkHandler.Initializer.init(this)
|
||||
|
||||
initializeWalletConnect()
|
||||
}
|
||||
|
||||
override fun <T> getFeature(key: Class<*>): T {
|
||||
return featureHolderManager.getFeature<T>(key)!!
|
||||
}
|
||||
|
||||
override fun releaseFeature(key: Class<*>) {
|
||||
featureHolderManager.releaseFeature(key)
|
||||
}
|
||||
|
||||
override fun commonApi(): CommonApi {
|
||||
return appComponent
|
||||
}
|
||||
|
||||
private fun initializeWalletConnect() {
|
||||
val projectId = BuildConfig.WALLET_CONNECT_PROJECT_ID
|
||||
val relayUrl = "relay.walletconnect.com"
|
||||
val serverUrl = "wss://$relayUrl?projectId=$projectId"
|
||||
val connectionType = ConnectionType.MANUAL
|
||||
val appMetaData = Core.Model.AppMetaData(
|
||||
name = "Pezkuwi Wallet",
|
||||
description = "Next-gen wallet for Pezkuwichain and Polkadot ecosystem",
|
||||
url = "https://pezkuwichain.io/",
|
||||
icons = listOf("https://raw.githubusercontent.com/pezkuwichain/branding/master/logos/Pezkuwi_Wallet_Sun_Color.png"),
|
||||
redirect = WC_REDIRECT_URL
|
||||
)
|
||||
|
||||
CoreClient.initialize(relayServerUrl = serverUrl, connectionType = connectionType, application = this, metaData = appMetaData) { error ->
|
||||
// TODO maybe re-initialize client
|
||||
}
|
||||
|
||||
val initParams = Wallet.Params.Init(core = CoreClient)
|
||||
|
||||
Web3Wallet.initialize(initParams) { error ->
|
||||
// TODO maybe re-initialize client
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package io.novafoundation.nova.app.di.app
|
||||
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import io.novafoundation.nova.app.App
|
||||
import io.novafoundation.nova.app.di.app.navigation.NavigationModule
|
||||
import io.novafoundation.nova.app.di.deps.ComponentHolderModule
|
||||
import io.novafoundation.nova.common.di.CommonApi
|
||||
import io.novafoundation.nova.common.di.modules.CommonModule
|
||||
import io.novafoundation.nova.common.di.modules.NetworkModule
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
import io.novafoundation.nova.common.utils.coroutines.RootScope
|
||||
|
||||
@ApplicationScope
|
||||
@Component(
|
||||
modules = [
|
||||
AppModule::class,
|
||||
CommonModule::class,
|
||||
NetworkModule::class,
|
||||
NavigationModule::class,
|
||||
ComponentHolderModule::class,
|
||||
FeatureManagerModule::class
|
||||
]
|
||||
)
|
||||
interface AppComponent : CommonApi {
|
||||
|
||||
@Component.Builder
|
||||
interface Builder {
|
||||
|
||||
@BindsInstance
|
||||
fun application(application: App): Builder
|
||||
|
||||
@BindsInstance
|
||||
fun contextManager(contextManager: ContextManager): Builder
|
||||
|
||||
@BindsInstance
|
||||
fun rootScope(rootScope: RootScope): Builder
|
||||
|
||||
fun build(): AppComponent
|
||||
}
|
||||
|
||||
fun inject(app: App)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.novafoundation.nova.app.di.app
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.App
|
||||
import io.novafoundation.nova.app.root.presentation.common.RealBuildTypeProvider
|
||||
import io.novafoundation.nova.app.root.presentation.common.RootActivityIntentProvider
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.interfaces.ActivityIntentProvider
|
||||
import io.novafoundation.nova.common.interfaces.BuildTypeProvider
|
||||
|
||||
@Module
|
||||
class AppModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideContext(application: App): Context {
|
||||
return application
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideRootActivityIntentProvider(context: Context): ActivityIntentProvider = RootActivityIntentProvider(context)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideBuildTypeProvider(): BuildTypeProvider = RealBuildTypeProvider()
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.app.di.app
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.di.deps.FeatureHolderManager
|
||||
import io.novafoundation.nova.common.di.FeatureApiHolder
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
|
||||
@Module
|
||||
class FeatureManagerModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideFeatureHolderManager(featureApiHolderMap: @JvmSuppressWildcards Map<Class<*>, FeatureApiHolder>): FeatureHolderManager {
|
||||
return FeatureHolderManager(featureApiHolderMap)
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.accountmigration.AccountMigrationNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_account_migration.presentation.AccountMigrationRouter
|
||||
|
||||
@Module
|
||||
class AccountMigrationNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): AccountMigrationRouter = AccountMigrationNavigator(
|
||||
navigationHoldersRegistry = navigationHoldersRegistry
|
||||
)
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.account.PolkadotVaultVariantSignCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.account.ScanSeedCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.account.SelectAddressCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.account.SelectMultipleWalletsCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.account.SelectSingleWalletCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.account.SelectWalletCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.cloudBackup.ChangeBackupPasswordCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.cloudBackup.RestoreBackupPasswordCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.cloudBackup.SyncWalletsBackupPasswordCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.pincode.PinCodeTwoFactorVerificationCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.sequrity.verification.PinCodeTwoFactorVerificationCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectAddress.SelectAddressCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectMultipleWalletsCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.ChangeBackupPasswordCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.RestoreBackupPasswordCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectWallet.SelectWalletCommunicator
|
||||
import io.novafoundation.nova.feature_account_impl.data.signer.paritySigner.PolkadotVaultVariantSignCommunicator
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.createPassword.SyncWalletsBackupPasswordCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectSingleWallet.SelectSingleWalletCommunicator
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.seedScan.ScanSeedCommunicator
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
|
||||
@Module
|
||||
class AccountNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun providePinCodeTwoFactorVerificationCommunicator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): PinCodeTwoFactorVerificationCommunicator = PinCodeTwoFactorVerificationCommunicatorImpl(navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectWalletCommunicator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): SelectWalletCommunicator = SelectWalletCommunicatorImpl(navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideParitySignerCommunicator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): PolkadotVaultVariantSignCommunicator = PolkadotVaultVariantSignCommunicatorImpl(navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectAddressCommunicator(
|
||||
router: AssetsRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): SelectAddressCommunicator = SelectAddressCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideScanSeedCommunicator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): ScanSeedCommunicator = ScanSeedCommunicatorImpl(navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectSingleWalletCommunicator(
|
||||
router: AssetsRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): SelectSingleWalletCommunicator = SelectSingleWalletCommunicatorImpl(router)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectMultipleWalletsCommunicator(
|
||||
router: AssetsRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): SelectMultipleWalletsCommunicator = SelectMultipleWalletsCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideAccountRouter(navigator: Navigator): AccountRouter = navigator
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun providePushGovernanceSettingsCommunicator(
|
||||
router: AccountRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): SyncWalletsBackupPasswordCommunicator = SyncWalletsBackupPasswordCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideChangeBackupPasswordCommunicator(
|
||||
router: AccountRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): ChangeBackupPasswordCommunicator = ChangeBackupPasswordCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideRestoreBackupPasswordCommunicator(
|
||||
router: AccountRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): RestoreBackupPasswordCommunicator = RestoreBackupPasswordCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.topup.TopUpAddressCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_assets.presentation.topup.TopUpAddressCommunicator
|
||||
|
||||
@Module
|
||||
class AssetNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideTopUpAddressCommunicator(navigationHoldersRegistry: NavigationHoldersRegistry): TopUpAddressCommunicator {
|
||||
return TopUpAddressCommunicatorImpl(navigationHoldersRegistry)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.buy.BuyNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_buy_impl.presentation.BuyRouter
|
||||
|
||||
@Module
|
||||
class BuyNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry): BuyRouter =
|
||||
BuyNavigator(navigationHoldersRegistry)
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.chainMigration.ChainMigrationNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_ahm_impl.presentation.ChainMigrationRouter
|
||||
|
||||
@Module
|
||||
class ChainMigrationNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry): ChainMigrationRouter =
|
||||
ChainMigrationNavigator(navigationHoldersRegistry)
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.cloudBackup.CloudBackupNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_cloud_backup_impl.presentation.CloudBackupRouter
|
||||
|
||||
@Module
|
||||
class CloudBackupNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry): CloudBackupRouter =
|
||||
CloudBackupNavigator(navigationHoldersRegistry)
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.wallet.CurrencyNavigator
|
||||
import io.novafoundation.nova.app.root.presentation.RootRouter
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_currency_api.presentation.CurrencyRouter
|
||||
|
||||
@Module
|
||||
class CurrencyNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(
|
||||
rootRouter: RootRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
): CurrencyRouter = CurrencyNavigator(rootRouter, navigationHoldersRegistry)
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.dApp.DAppNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.dApp.DAppSearchCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.search.DAppSearchCommunicator
|
||||
|
||||
@Module
|
||||
class DAppNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): DAppRouter = DAppNavigator(navigationHoldersRegistry)
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideSearchDappCommunicator(navigationHoldersRegistry: NavigationHoldersRegistry): DAppSearchCommunicator {
|
||||
return DAppSearchCommunicatorImpl(navigationHoldersRegistry)
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.externalSign.ExternalSignCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.externalSign.ExternalSignNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.utils.sequrity.AutomaticInteractionGate
|
||||
import io.novafoundation.nova.feature_external_sign_api.model.ExternalSignCommunicator
|
||||
import io.novafoundation.nova.feature_external_sign_impl.ExternalSignRouter
|
||||
|
||||
@Module
|
||||
class ExternalSignNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry): ExternalSignRouter =
|
||||
ExternalSignNavigator(navigationHoldersRegistry)
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideSignExtrinsicCommunicator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
automaticInteractionGate: AutomaticInteractionGate,
|
||||
): ExternalSignCommunicator {
|
||||
return ExternalSignCommunicatorImpl(navigationHoldersRegistry, automaticInteractionGate)
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.gift.GiftNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.GiftRouter
|
||||
|
||||
@Module
|
||||
class GiftNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(commonDelegate: Navigator, navigationHoldersRegistry: NavigationHoldersRegistry): GiftRouter =
|
||||
GiftNavigator(commonDelegate, navigationHoldersRegistry)
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.governance.GovernanceNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.governance.SelectTracksCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.governance.TinderGovVoteCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectTracksCommunicator
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter
|
||||
import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter
|
||||
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteCommunicator
|
||||
|
||||
@Module
|
||||
class GovernanceNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
commonNavigator: Navigator,
|
||||
contextManager: ContextManager,
|
||||
dAppRouter: DAppRouter
|
||||
): GovernanceRouter = GovernanceNavigator(navigationHoldersRegistry, commonNavigator, contextManager, dAppRouter)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectTracksCommunicator(
|
||||
router: GovernanceRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): SelectTracksCommunicator = SelectTracksCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideTinderGovVoteCommunicator(
|
||||
router: GovernanceRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): TinderGovVoteCommunicator = TinderGovVoteCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.ledger.LedgerNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.ledger.LedgerSignCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.ledger.SelectLedgerAddressCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.sign.LedgerSignCommunicator
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
import io.novafoundation.nova.feature_ledger_impl.presentation.LedgerRouter
|
||||
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.SelectLedgerAddressInterScreenCommunicator
|
||||
|
||||
@Module
|
||||
class LedgerNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideSelectLedgerAddressCommunicator(navigationHoldersRegistry: NavigationHoldersRegistry): SelectLedgerAddressInterScreenCommunicator {
|
||||
return SelectLedgerAddressCommunicatorImpl(navigationHoldersRegistry)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideLedgerSignerCommunicator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): LedgerSignCommunicator = LedgerSignCommunicatorImpl(navigationHoldersRegistry)
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(router: AccountRouter, navigationHoldersRegistry: NavigationHoldersRegistry): LedgerRouter =
|
||||
LedgerNavigator(router, navigationHoldersRegistry)
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.multisig.MultisigOperationsNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_multisig_operations.presentation.MultisigOperationsRouter
|
||||
|
||||
@Module
|
||||
class MultisigNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideOperationsRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
commonDelegate: Navigator
|
||||
): MultisigOperationsRouter = MultisigOperationsNavigator(navigationHoldersRegistry, commonDelegate)
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.di.app.navigation.staking.StakingNavigationModule
|
||||
import io.novafoundation.nova.app.root.navigation.holders.RootNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.holders.SplitScreenNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.presentation.RootRouter
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.navigation.DelayedNavigationRouter
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.CrowdloanRouter
|
||||
import io.novafoundation.nova.feature_onboarding_impl.OnboardingRouter
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.WalletConnectRouter
|
||||
import io.novafoundation.nova.splash.SplashRouter
|
||||
|
||||
@Module(
|
||||
includes = [
|
||||
AccountNavigationModule::class,
|
||||
AssetNavigationModule::class,
|
||||
DAppNavigationModule::class,
|
||||
NftNavigationModule::class,
|
||||
StakingNavigationModule::class,
|
||||
LedgerNavigationModule::class,
|
||||
CurrencyNavigationModule::class,
|
||||
GovernanceNavigationModule::class,
|
||||
WalletConnectNavigationModule::class,
|
||||
VoteNavigationModule::class,
|
||||
VersionsNavigationModule::class,
|
||||
ExternalSignNavigationModule::class,
|
||||
SettingsNavigationModule::class,
|
||||
SwapNavigationModule::class,
|
||||
BuyNavigationModule::class,
|
||||
PushNotificationsNavigationModule::class,
|
||||
CloudBackupNavigationModule::class,
|
||||
AssetNavigationModule::class,
|
||||
AccountMigrationNavigationModule::class,
|
||||
MultisigNavigationModule::class,
|
||||
ChainMigrationNavigationModule::class,
|
||||
WalletNavigationModule::class,
|
||||
GiftNavigationModule::class
|
||||
]
|
||||
)
|
||||
class NavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideMainNavigatorHolder(
|
||||
contextManager: ContextManager
|
||||
): SplitScreenNavigationHolder = SplitScreenNavigationHolder(contextManager)
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideDappNavigatorHolder(
|
||||
contextManager: ContextManager
|
||||
): RootNavigationHolder = RootNavigationHolder(contextManager)
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideNavigationHoldersRegistry(
|
||||
rootNavigatorHolder: RootNavigationHolder,
|
||||
splitScreenNavigationHolder: SplitScreenNavigationHolder,
|
||||
): NavigationHoldersRegistry {
|
||||
return NavigationHoldersRegistry(splitScreenNavigationHolder, rootNavigatorHolder)
|
||||
}
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideNavigator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
walletConnectRouter: WalletConnectRouter
|
||||
): Navigator = Navigator(navigationHoldersRegistry, walletConnectRouter)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideRootRouter(navigator: Navigator): RootRouter = navigator
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideSplashRouter(navigator: Navigator): SplashRouter = navigator
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideOnboardingRouter(navigator: Navigator): OnboardingRouter = navigator
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideAssetsRouter(navigator: Navigator): AssetsRouter = navigator
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideCrowdloanRouter(navigator: Navigator): CrowdloanRouter = navigator
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideDelayedNavigationRouter(navigator: Navigator): DelayedNavigationRouter = navigator
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.nft.NftNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_nft_impl.NftRouter
|
||||
|
||||
@Module
|
||||
class NftNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry): NftRouter =
|
||||
NftNavigator(navigationHoldersRegistry)
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.push.PushGovernanceSettingsCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.push.PushMultisigSettingsCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.push.PushNotificationsNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.push.PushStakingSettingsCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_push_notifications.PushNotificationsRouter
|
||||
import io.novafoundation.nova.feature_push_notifications.presentation.governance.PushGovernanceSettingsCommunicator
|
||||
import io.novafoundation.nova.feature_push_notifications.presentation.multisigs.PushMultisigSettingsCommunicator
|
||||
import io.novafoundation.nova.feature_push_notifications.presentation.staking.PushStakingSettingsCommunicator
|
||||
|
||||
@Module
|
||||
class PushNotificationsNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry): PushNotificationsRouter =
|
||||
PushNotificationsNavigator(navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun providePushGovernanceSettingsCommunicator(
|
||||
router: PushNotificationsRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): PushGovernanceSettingsCommunicator = PushGovernanceSettingsCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun providePushStakingSettingsCommunicator(
|
||||
router: PushNotificationsRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): PushStakingSettingsCommunicator = PushStakingSettingsCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun providePushMultisigSettingsCommunicator(
|
||||
router: PushNotificationsRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
): PushMultisigSettingsCommunicator = PushMultisigSettingsCommunicatorImpl(router, navigationHoldersRegistry)
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.settings.SettingsNavigator
|
||||
import io.novafoundation.nova.app.root.presentation.RootRouter
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_settings_impl.SettingsRouter
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.WalletConnectRouter
|
||||
|
||||
@Module
|
||||
class SettingsNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(
|
||||
rootRouter: RootRouter,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
walletConnectRouter: WalletConnectRouter,
|
||||
navigator: Navigator,
|
||||
): SettingsRouter = SettingsNavigator(navigationHoldersRegistry, rootRouter, walletConnectRouter, navigator)
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.swap.SwapNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_swap_impl.presentation.SwapRouter
|
||||
|
||||
@Module
|
||||
class SwapNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
commonDelegate: Navigator
|
||||
): SwapRouter = SwapNavigator(navigationHoldersRegistry, commonDelegate)
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.versions.VersionsNavigator
|
||||
import io.novafoundation.nova.common.data.network.AppLinksProvider
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
import io.novafoundation.nova.feature_versions_api.presentation.VersionsRouter
|
||||
|
||||
@Module
|
||||
class VersionsNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
contextManager: ContextManager,
|
||||
appLinksProvider: AppLinksProvider
|
||||
): VersionsRouter = VersionsNavigator(navigationHoldersRegistry, contextManager, appLinksProvider.storeUrl)
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.vote.VoteNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_vote.presentation.VoteRouter
|
||||
|
||||
@Module
|
||||
class VoteNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideVoteRouter(navigator: Navigator): VoteRouter = VoteNavigator(navigator)
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.walletConnect.ApproveSessionCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.walletConnect.WalletConnectNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.utils.sequrity.AutomaticInteractionGate
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.WalletConnectRouter
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.presentation.sessions.approve.ApproveSessionCommunicator
|
||||
|
||||
@Module
|
||||
class WalletConnectNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideApproveSessionCommunicator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
automaticInteractionGate: AutomaticInteractionGate,
|
||||
): ApproveSessionCommunicator = ApproveSessionCommunicatorImpl(navigationHoldersRegistry, automaticInteractionGate)
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry): WalletConnectRouter =
|
||||
WalletConnectNavigator(navigationHoldersRegistry)
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.wallet.WalletNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_wallet_impl.presentation.WalletRouter
|
||||
|
||||
@Module
|
||||
class WalletNavigationModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Provides
|
||||
fun provideRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
commonDelegate: Navigator
|
||||
): WalletRouter = WalletNavigator(commonDelegate, navigationHoldersRegistry)
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation.staking
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.mythos.MythosStakingNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.mythos.SelectMythCollatorSettingsInterScreenCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.mythos.SelectMythosCollatorInterScreenCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.MythosStakingRouter
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.StakingDashboardRouter
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.mythos.SelectMythosInterScreenCommunicator
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.mythos.start.selectCollatorSettings.SelectMythCollatorSettingsInterScreenCommunicator
|
||||
|
||||
@Module
|
||||
class MythosStakingNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideMythosStakingRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
stakingDashboardRouter: StakingDashboardRouter,
|
||||
): MythosStakingRouter {
|
||||
return MythosStakingNavigator(navigationHoldersRegistry, stakingDashboardRouter)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectCollatorCommunicator(navigationHoldersRegistry: NavigationHoldersRegistry): SelectMythosInterScreenCommunicator {
|
||||
return SelectMythosCollatorInterScreenCommunicatorImpl(navigationHoldersRegistry)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectSettingsCollatorCommunicator(navigationHoldersRegistry: NavigationHoldersRegistry): SelectMythCollatorSettingsInterScreenCommunicator {
|
||||
return SelectMythCollatorSettingsInterScreenCommunicatorImpl(navigationHoldersRegistry)
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation.staking
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.nominationPools.NominationPoolsStakingNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.NominationPoolsRouter
|
||||
|
||||
@Module
|
||||
class NominationPoolsStakingNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideRouter(navigationHoldersRegistry: NavigationHoldersRegistry, navigator: Navigator): NominationPoolsRouter {
|
||||
return NominationPoolsStakingNavigator(navigationHoldersRegistry, navigator)
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation.staking
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.parachain.ParachainStakingNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.parachain.SelectCollatorInterScreenCommunicatorImpl
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.parachain.SelectCollatorSettingsInterScreenCommunicatorImpl
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.ParachainStakingRouter
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.parachainStaking.collator.common.SelectCollatorInterScreenCommunicator
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.parachainStaking.collator.settings.SelectCollatorSettingsInterScreenCommunicator
|
||||
|
||||
@Module
|
||||
class ParachainStakingNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideParachainStakingRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
navigator: Navigator
|
||||
): ParachainStakingRouter {
|
||||
return ParachainStakingNavigator(navigationHoldersRegistry, navigator)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectCollatorCommunicator(navigationHoldersRegistry: NavigationHoldersRegistry): SelectCollatorInterScreenCommunicator {
|
||||
return SelectCollatorInterScreenCommunicatorImpl(navigationHoldersRegistry)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideSelectCollatorSettingsCommunicator(navigationHoldersRegistry: NavigationHoldersRegistry): SelectCollatorSettingsInterScreenCommunicator {
|
||||
return SelectCollatorSettingsInterScreenCommunicatorImpl(navigationHoldersRegistry)
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation.staking
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.relaychain.RelayStakingNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.StakingDashboardRouter
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.StakingRouter
|
||||
|
||||
@Module
|
||||
class RelayStakingNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideRelayStakingRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
navigator: Navigator,
|
||||
dashboardRouter: StakingDashboardRouter,
|
||||
dAppRouter: DAppRouter
|
||||
): StakingRouter {
|
||||
return RelayStakingNavigator(navigationHoldersRegistry, navigator, dashboardRouter, dAppRouter)
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package io.novafoundation.nova.app.di.app.navigation.staking
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.StakingDashboardNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.StartMultiStakingNavigator
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.StakingDashboardRouter
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.StartMultiStakingRouter
|
||||
|
||||
@Module(
|
||||
includes = [
|
||||
ParachainStakingNavigationModule::class,
|
||||
RelayStakingNavigationModule::class,
|
||||
NominationPoolsStakingNavigationModule::class,
|
||||
MythosStakingNavigationModule::class
|
||||
]
|
||||
)
|
||||
class StakingNavigationModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideStakingDashboardNavigator(navigationHoldersRegistry: NavigationHoldersRegistry): StakingDashboardNavigator {
|
||||
return StakingDashboardNavigator(navigationHoldersRegistry)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideStakingDashboardRouter(relayStakingNavigator: StakingDashboardNavigator): StakingDashboardRouter = relayStakingNavigator
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideStartMultiStakingRouter(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
dashboardRouter: StakingDashboardRouter,
|
||||
commonNavigator: Navigator
|
||||
): StartMultiStakingRouter {
|
||||
return StartMultiStakingNavigator(navigationHoldersRegistry, dashboardRouter, commonNavigator)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
package io.novafoundation.nova.app.di.deps
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
import io.novafoundation.nova.app.App
|
||||
import io.novafoundation.nova.app.root.di.RootApi
|
||||
import io.novafoundation.nova.app.root.di.RootFeatureHolder
|
||||
import io.novafoundation.nova.caip.di.CaipApi
|
||||
import io.novafoundation.nova.caip.di.CaipFeatureHolder
|
||||
import io.novafoundation.nova.common.di.FeatureApiHolder
|
||||
import io.novafoundation.nova.common.di.FeatureContainer
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.core_db.di.DbApi
|
||||
import io.novafoundation.nova.core_db.di.DbHolder
|
||||
import io.novafoundation.nova.feature_account_api.di.AccountFeatureApi
|
||||
import io.novafoundation.nova.feature_account_impl.di.AccountFeatureHolder
|
||||
import io.novafoundation.nova.feature_account_migration.di.AccountMigrationFeatureApi
|
||||
import io.novafoundation.nova.feature_account_migration.di.AccountMigrationFeatureHolder
|
||||
import io.novafoundation.nova.feature_ahm_api.di.ChainMigrationFeatureApi
|
||||
import io.novafoundation.nova.feature_ahm_impl.di.ChainMigrationFeatureHolder
|
||||
import io.novafoundation.nova.feature_assets.di.AssetsFeatureApi
|
||||
import io.novafoundation.nova.feature_assets.di.AssetsFeatureHolder
|
||||
import io.novafoundation.nova.feature_banners_api.di.BannersFeatureApi
|
||||
import io.novafoundation.nova.feature_banners_impl.di.BannersFeatureHolder
|
||||
import io.novafoundation.nova.feature_buy_api.di.BuyFeatureApi
|
||||
import io.novafoundation.nova.feature_buy_impl.di.BuyFeatureHolder
|
||||
import io.novafoundation.nova.feature_cloud_backup_api.di.CloudBackupFeatureApi
|
||||
import io.novafoundation.nova.feature_cloud_backup_impl.di.CloudBackupFeatureHolder
|
||||
import io.novafoundation.nova.feature_crowdloan_api.di.CrowdloanFeatureApi
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.di.CrowdloanFeatureHolder
|
||||
import io.novafoundation.nova.feature_currency_api.di.CurrencyFeatureApi
|
||||
import io.novafoundation.nova.feature_currency_impl.di.CurrencyFeatureHolder
|
||||
import io.novafoundation.nova.feature_dapp_api.di.DAppFeatureApi
|
||||
import io.novafoundation.nova.feature_dapp_impl.di.DAppFeatureHolder
|
||||
import io.novafoundation.nova.feature_deep_linking.di.DeepLinkingFeatureApi
|
||||
import io.novafoundation.nova.feature_deep_linking.di.DeepLinkingFeatureHolder
|
||||
import io.novafoundation.nova.feature_external_sign_api.di.ExternalSignFeatureApi
|
||||
import io.novafoundation.nova.feature_external_sign_impl.di.ExternalSignFeatureHolder
|
||||
import io.novafoundation.nova.feature_gift_api.di.GiftFeatureApi
|
||||
import io.novafoundation.nova.feature_gift_impl.di.GiftFeatureHolder
|
||||
import io.novafoundation.nova.feature_governance_api.di.GovernanceFeatureApi
|
||||
import io.novafoundation.nova.feature_governance_impl.di.GovernanceFeatureHolder
|
||||
import io.novafoundation.nova.feature_ledger_api.di.LedgerFeatureApi
|
||||
import io.novafoundation.nova.feature_ledger_core.LedgerCoreHolder
|
||||
import io.novafoundation.nova.feature_ledger_core.di.LedgerCoreApi
|
||||
import io.novafoundation.nova.feature_ledger_impl.di.LedgerFeatureHolder
|
||||
import io.novafoundation.nova.feature_multisig_operations.di.MultisigOperationsFeatureApi
|
||||
import io.novafoundation.nova.feature_multisig_operations.di.MultisigOperationsFeatureHolder
|
||||
import io.novafoundation.nova.feature_nft_api.NftFeatureApi
|
||||
import io.novafoundation.nova.feature_nft_impl.di.NftFeatureHolder
|
||||
import io.novafoundation.nova.feature_onboarding_api.di.OnboardingFeatureApi
|
||||
import io.novafoundation.nova.feature_onboarding_impl.di.OnboardingFeatureHolder
|
||||
import io.novafoundation.nova.feature_proxy_api.di.ProxyFeatureApi
|
||||
import io.novafoundation.nova.feature_proxy_impl.di.ProxyFeatureHolder
|
||||
import io.novafoundation.nova.feature_push_notifications.di.PushNotificationsFeatureApi
|
||||
import io.novafoundation.nova.feature_push_notifications.di.PushNotificationsFeatureHolder
|
||||
import io.novafoundation.nova.feature_settings_api.SettingsFeatureApi
|
||||
import io.novafoundation.nova.feature_settings_impl.di.SettingsFeatureHolder
|
||||
import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi
|
||||
import io.novafoundation.nova.feature_staking_impl.di.StakingFeatureHolder
|
||||
import io.novafoundation.nova.feature_swap_api.di.SwapFeatureApi
|
||||
import io.novafoundation.nova.feature_swap_core.di.SwapCoreHolder
|
||||
import io.novafoundation.nova.feature_swap_core_api.di.SwapCoreApi
|
||||
import io.novafoundation.nova.feature_swap_impl.di.SwapFeatureHolder
|
||||
import io.novafoundation.nova.feature_versions_api.di.VersionsFeatureApi
|
||||
import io.novafoundation.nova.feature_versions_impl.di.VersionsFeatureHolder
|
||||
import io.novafoundation.nova.feature_vote.di.VoteFeatureApi
|
||||
import io.novafoundation.nova.feature_vote.di.VoteFeatureHolder
|
||||
import io.novafoundation.nova.feature_wallet_api.di.WalletFeatureApi
|
||||
import io.novafoundation.nova.feature_wallet_connect_api.di.WalletConnectFeatureApi
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.di.WalletConnectFeatureHolder
|
||||
import io.novafoundation.nova.feature_wallet_impl.di.WalletFeatureHolder
|
||||
import io.novafoundation.nova.feature_xcm_api.di.XcmFeatureApi
|
||||
import io.novafoundation.nova.feature_xcm_impl.di.XcmFeatureHolder
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeHolder
|
||||
import io.novafoundation.nova.splash.di.SplashFeatureApi
|
||||
import io.novafoundation.nova.splash.di.SplashFeatureHolder
|
||||
import io.novafoundation.nova.web3names.di.Web3NamesApi
|
||||
import io.novafoundation.nova.web3names.di.Web3NamesHolder
|
||||
|
||||
@Module
|
||||
interface ComponentHolderModule {
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
fun provideFeatureContainer(application: App): FeatureContainer
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(SplashFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideSplashFeatureHolder(splashFeatureHolder: SplashFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(DbApi::class)
|
||||
@IntoMap
|
||||
fun provideDbFeature(dbHolder: DbHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(OnboardingFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideOnboardingFeature(onboardingFeatureHolder: OnboardingFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(DAppFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideDAppFeature(dAppFeatureHolder: DAppFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(LedgerFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideLedgerFeature(accountFeatureHolder: LedgerFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(LedgerCoreApi::class)
|
||||
@IntoMap
|
||||
fun provideLedgerCore(accountFeatureHolder: LedgerCoreHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(GovernanceFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideGovernanceFeature(accountFeatureHolder: GovernanceFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(AccountFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideAccountFeature(accountFeatureHolder: AccountFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(AssetsFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideAssetsFeature(holder: AssetsFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(VoteFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideVoteFeature(holder: VoteFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(WalletFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideWalletFeature(walletFeatureHolder: WalletFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(CurrencyFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideCurrencyFeature(currencyFeatureHolder: CurrencyFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(RootApi::class)
|
||||
@IntoMap
|
||||
fun provideMainFeature(accountFeatureHolder: RootFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(StakingFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideStakingFeature(holder: StakingFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(RuntimeApi::class)
|
||||
@IntoMap
|
||||
fun provideRuntimeFeature(runtimeHolder: RuntimeHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(Web3NamesApi::class)
|
||||
@IntoMap
|
||||
fun provideWeb3Names(web3NamesHolder: Web3NamesHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(CrowdloanFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideCrowdloanFeature(holder: CrowdloanFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(NftFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideNftFeature(holder: NftFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(VersionsFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideVersionsFeature(holder: VersionsFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(CaipApi::class)
|
||||
@IntoMap
|
||||
fun provideCaipFeature(holder: CaipFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(ExternalSignFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideExternalSignFeature(holder: ExternalSignFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(WalletConnectFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideWalletConnectFeature(holder: WalletConnectFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(SettingsFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideSettingsFeature(holder: SettingsFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(SwapFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideSwapFeature(holder: SwapFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(BuyFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideBuyFeature(holder: BuyFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(PushNotificationsFeatureApi::class)
|
||||
@IntoMap
|
||||
fun providePushNotificationsFeature(holder: PushNotificationsFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(ProxyFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideProxyFeature(holder: ProxyFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(DeepLinkingFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideDeepLinkingFeatureHolder(holder: DeepLinkingFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(CloudBackupFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideCloudBackupFeatureHolder(holder: CloudBackupFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(SwapCoreApi::class)
|
||||
@IntoMap
|
||||
fun provideSwapCoreFeatureHolder(holder: SwapCoreHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(BannersFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideBannersFeatureApi(holder: BannersFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(XcmFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideXcmFeatureHolder(holder: XcmFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(MultisigOperationsFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideMultisigOperationsFeatureHolder(holder: MultisigOperationsFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(AccountMigrationFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideAccountMigrationFeatureHolder(holder: AccountMigrationFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(ChainMigrationFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideChainMigrationFeatureHolder(holder: ChainMigrationFeatureHolder): FeatureApiHolder
|
||||
|
||||
@ApplicationScope
|
||||
@Binds
|
||||
@ClassKey(GiftFeatureApi::class)
|
||||
@IntoMap
|
||||
fun provideGiftFeature(giftFeatureHolder: GiftFeatureHolder): FeatureApiHolder
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.app.di.deps
|
||||
|
||||
import io.novafoundation.nova.common.di.FeatureApiHolder
|
||||
|
||||
class FeatureHolderManager(
|
||||
private val mFeatureHolders: Map<Class<*>, FeatureApiHolder>
|
||||
) {
|
||||
|
||||
fun <T> getFeature(key: Class<*>): T? {
|
||||
val featureApiHolder = mFeatureHolders[key] ?: throw IllegalStateException()
|
||||
return featureApiHolder.getFeatureApi<T>()
|
||||
}
|
||||
|
||||
fun releaseFeature(key: Class<*>) {
|
||||
val featureApiHolder = mFeatureHolders[key] ?: throw IllegalStateException()
|
||||
featureApiHolder.releaseFeatureApi()
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package io.novafoundation.nova.app.root.di
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.multibindings.IntoSet
|
||||
import io.novafoundation.nova.app.root.presentation.common.FirebaseServiceInitializer
|
||||
import io.novafoundation.nova.common.di.scope.FeatureScope
|
||||
import io.novafoundation.nova.common.interfaces.CompoundExternalServiceInitializer
|
||||
import io.novafoundation.nova.common.interfaces.ExternalServiceInitializer
|
||||
|
||||
@Module
|
||||
class ExternalServiceInitializersModule {
|
||||
|
||||
@Provides
|
||||
@IntoSet
|
||||
fun provideFirebaseServiceInitializer(
|
||||
context: Context
|
||||
): ExternalServiceInitializer {
|
||||
return FirebaseServiceInitializer(context)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
fun provideCompoundExternalServiceInitializer(
|
||||
initializers: Set<@JvmSuppressWildcards ExternalServiceInitializer>
|
||||
): ExternalServiceInitializer {
|
||||
return CompoundExternalServiceInitializer(initializers)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package io.novafoundation.nova.app.root.di
|
||||
|
||||
interface RootApi
|
||||
@@ -0,0 +1,103 @@
|
||||
package io.novafoundation.nova.app.root.di
|
||||
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import io.novafoundation.nova.app.root.navigation.holders.RootNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.holders.SplitScreenNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.StakingDashboardNavigator
|
||||
import io.novafoundation.nova.app.root.presentation.RootRouter
|
||||
import io.novafoundation.nova.app.root.presentation.di.RootActivityComponent
|
||||
import io.novafoundation.nova.app.root.presentation.main.di.MainFragmentComponent
|
||||
import io.novafoundation.nova.app.root.presentation.splitScreen.di.SplitScreenFragmentComponent
|
||||
import io.novafoundation.nova.common.di.CommonApi
|
||||
import io.novafoundation.nova.common.di.scope.FeatureScope
|
||||
import io.novafoundation.nova.common.navigation.DelayedNavigationRouter
|
||||
import io.novafoundation.nova.core_db.di.DbApi
|
||||
import io.novafoundation.nova.feature_account_api.di.AccountFeatureApi
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
import io.novafoundation.nova.feature_account_migration.di.AccountMigrationFeatureApi
|
||||
import io.novafoundation.nova.feature_ahm_api.di.ChainMigrationFeatureApi
|
||||
import io.novafoundation.nova.feature_assets.di.AssetsFeatureApi
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
import io.novafoundation.nova.feature_buy_api.di.BuyFeatureApi
|
||||
import io.novafoundation.nova.feature_crowdloan_api.di.CrowdloanFeatureApi
|
||||
import io.novafoundation.nova.feature_currency_api.di.CurrencyFeatureApi
|
||||
import io.novafoundation.nova.feature_dapp_api.di.DAppFeatureApi
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter
|
||||
import io.novafoundation.nova.feature_deep_linking.di.DeepLinkingFeatureApi
|
||||
import io.novafoundation.nova.feature_gift_api.di.GiftFeatureApi
|
||||
import io.novafoundation.nova.feature_governance_api.di.GovernanceFeatureApi
|
||||
import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter
|
||||
import io.novafoundation.nova.feature_ledger_api.di.LedgerFeatureApi
|
||||
import io.novafoundation.nova.feature_multisig_operations.di.MultisigOperationsFeatureApi
|
||||
import io.novafoundation.nova.feature_push_notifications.di.PushNotificationsFeatureApi
|
||||
import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.StakingRouter
|
||||
import io.novafoundation.nova.feature_versions_api.di.VersionsFeatureApi
|
||||
import io.novafoundation.nova.feature_wallet_api.di.WalletFeatureApi
|
||||
import io.novafoundation.nova.feature_wallet_connect_api.di.WalletConnectFeatureApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
|
||||
@Component(
|
||||
dependencies = [
|
||||
RootDependencies::class
|
||||
],
|
||||
modules = [
|
||||
RootFeatureModule::class
|
||||
]
|
||||
)
|
||||
@FeatureScope
|
||||
interface RootComponent {
|
||||
|
||||
fun mainActivityComponentFactory(): RootActivityComponent.Factory
|
||||
|
||||
fun splitScreenFragmentComponentFactory(): SplitScreenFragmentComponent.Factory
|
||||
|
||||
fun mainFragmentComponentFactory(): MainFragmentComponent.Factory
|
||||
|
||||
@Component.Factory
|
||||
interface Factory {
|
||||
|
||||
fun create(
|
||||
@BindsInstance splitScreenNavigationHolder: SplitScreenNavigationHolder,
|
||||
@BindsInstance rootNavigationHolder: RootNavigationHolder,
|
||||
@BindsInstance rootRouter: RootRouter,
|
||||
@BindsInstance governanceRouter: GovernanceRouter,
|
||||
@BindsInstance dAppRouter: DAppRouter,
|
||||
@BindsInstance assetsRouter: AssetsRouter,
|
||||
@BindsInstance accountRouter: AccountRouter,
|
||||
@BindsInstance stakingRouter: StakingRouter,
|
||||
@BindsInstance stakingDashboardNavigator: StakingDashboardNavigator,
|
||||
@BindsInstance delayedNavigationRouter: DelayedNavigationRouter,
|
||||
deps: RootDependencies
|
||||
): RootComponent
|
||||
}
|
||||
|
||||
@Component(
|
||||
dependencies = [
|
||||
AccountFeatureApi::class,
|
||||
WalletFeatureApi::class,
|
||||
StakingFeatureApi::class,
|
||||
CrowdloanFeatureApi::class,
|
||||
AssetsFeatureApi::class,
|
||||
CurrencyFeatureApi::class,
|
||||
GovernanceFeatureApi::class,
|
||||
DAppFeatureApi::class,
|
||||
DbApi::class,
|
||||
CommonApi::class,
|
||||
RuntimeApi::class,
|
||||
VersionsFeatureApi::class,
|
||||
WalletConnectFeatureApi::class,
|
||||
PushNotificationsFeatureApi::class,
|
||||
DeepLinkingFeatureApi::class,
|
||||
LedgerFeatureApi::class,
|
||||
BuyFeatureApi::class,
|
||||
DeepLinkingFeatureApi::class,
|
||||
AccountMigrationFeatureApi::class,
|
||||
MultisigOperationsFeatureApi::class,
|
||||
ChainMigrationFeatureApi::class,
|
||||
GiftFeatureApi::class
|
||||
]
|
||||
)
|
||||
interface RootFeatureDependenciesComponent : RootDependencies
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package io.novafoundation.nova.app.root.di
|
||||
|
||||
import android.content.Context
|
||||
import coil.ImageLoader
|
||||
import io.novafoundation.nova.common.data.network.AppLinksProvider
|
||||
import io.novafoundation.nova.common.mixin.actionAwaitable.ActionAwaitableMixin
|
||||
import io.novafoundation.nova.common.mixin.api.NetworkStateMixin
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
import io.novafoundation.nova.common.resources.ResourceManager
|
||||
import io.novafoundation.nova.common.sequrity.SafeModeService
|
||||
import io.novafoundation.nova.common.utils.DialogMessageManager
|
||||
import io.novafoundation.nova.common.utils.ToastMessageManager
|
||||
import io.novafoundation.nova.common.utils.coroutines.RootScope
|
||||
import io.novafoundation.nova.common.utils.network.DeviceNetworkStateObserver
|
||||
import io.novafoundation.nova.common.utils.sequrity.AutomaticInteractionGate
|
||||
import io.novafoundation.nova.common.utils.sequrity.BackgroundAccessObserver
|
||||
import io.novafoundation.nova.common.utils.systemCall.SystemCallExecutor
|
||||
import io.novafoundation.nova.common.view.bottomSheet.action.ActionBottomSheetLauncher
|
||||
import io.novafoundation.nova.common.view.bottomSheet.action.ActionBottomSheetLauncherFactory
|
||||
import io.novafoundation.nova.core_db.dao.BrowserTabsDao
|
||||
import io.novafoundation.nova.feature_account_api.data.events.MetaAccountChangesEventBus
|
||||
import io.novafoundation.nova.feature_account_api.data.externalAccounts.ExternalAccountsSyncService
|
||||
import io.novafoundation.nova.feature_account_api.data.multisig.MultisigPendingOperationsService
|
||||
import io.novafoundation.nova.feature_account_api.data.multisig.validation.MultisigExtrinsicValidationRequestBus
|
||||
import io.novafoundation.nova.feature_account_api.data.proxy.validation.ProxyExtrinsicValidationRequestBus
|
||||
import io.novafoundation.nova.feature_account_api.di.deeplinks.AccountDeepLinks
|
||||
import io.novafoundation.nova.feature_account_api.domain.account.common.EncryptionDefaults
|
||||
import io.novafoundation.nova.feature_account_api.domain.cloudBackup.ApplyLocalSnapshotToCloudBackupUseCase
|
||||
import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository
|
||||
import io.novafoundation.nova.feature_account_migration.di.deeplinks.AccountMigrationDeepLinks
|
||||
import io.novafoundation.nova.feature_ahm_api.data.repository.ChainMigrationRepository
|
||||
import io.novafoundation.nova.feature_ahm_api.data.repository.MigrationInfoRepository
|
||||
import io.novafoundation.nova.feature_ahm_api.di.deeplinks.ChainMigrationDeepLinks
|
||||
import io.novafoundation.nova.feature_ahm_api.domain.ChainMigrationDetailsSelectToShowUseCase
|
||||
import io.novafoundation.nova.feature_assets.data.network.BalancesUpdateSystem
|
||||
import io.novafoundation.nova.feature_assets.di.modules.deeplinks.AssetDeepLinks
|
||||
import io.novafoundation.nova.feature_buy_api.di.deeplinks.BuyDeepLinks
|
||||
import io.novafoundation.nova.feature_crowdloan_api.data.repository.CrowdloanRepository
|
||||
import io.novafoundation.nova.feature_crowdloan_api.domain.contributions.ContributionsInteractor
|
||||
import io.novafoundation.nova.feature_currency_api.domain.CurrencyInteractor
|
||||
import io.novafoundation.nova.feature_dapp_api.data.repository.BrowserTabExternalRepository
|
||||
import io.novafoundation.nova.feature_dapp_api.data.repository.DAppMetadataRepository
|
||||
import io.novafoundation.nova.feature_dapp_api.di.deeplinks.DAppDeepLinks
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.PendingDeepLinkProvider
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.branchIo.BranchIoLinkConverter
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.common.DeepLinkingPreferences
|
||||
import io.novafoundation.nova.feature_gift_api.di.GiftDeepLinks
|
||||
import io.novafoundation.nova.feature_governance_api.data.MutableGovernanceState
|
||||
import io.novafoundation.nova.feature_governance_api.di.deeplinks.GovernanceDeepLinks
|
||||
import io.novafoundation.nova.feature_multisig_operations.di.deeplink.MultisigDeepLinks
|
||||
import io.novafoundation.nova.feature_push_notifications.domain.interactor.PushNotificationsInteractor
|
||||
import io.novafoundation.nova.feature_push_notifications.domain.interactor.WelcomePushNotificationsInteractor
|
||||
import io.novafoundation.nova.feature_push_notifications.presentation.multisigsWarning.MultisigPushNotificationsAlertMixinFactory
|
||||
import io.novafoundation.nova.feature_staking_api.di.deeplinks.StakingDeepLinks
|
||||
import io.novafoundation.nova.feature_staking_api.domain.api.StakingRepository
|
||||
import io.novafoundation.nova.feature_versions_api.domain.UpdateNotificationsInteractor
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.interfaces.WalletRepository
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.validation.MultisigExtrinsicValidationFactory
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.validation.ProxyHaveEnoughFeeValidationFactory
|
||||
import io.novafoundation.nova.feature_wallet_connect_api.di.deeplinks.WalletConnectDeepLinks
|
||||
import io.novafoundation.nova.feature_wallet_connect_api.domain.sessions.WalletConnectSessionsUseCase
|
||||
import io.novafoundation.nova.feature_wallet_connect_api.presentation.WalletConnectService
|
||||
import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry
|
||||
import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
interface RootDependencies {
|
||||
|
||||
val stakingDeepLinks: StakingDeepLinks
|
||||
|
||||
val accountDeepLinks: AccountDeepLinks
|
||||
|
||||
val dAppDeepLinks: DAppDeepLinks
|
||||
|
||||
val governanceDeepLinks: GovernanceDeepLinks
|
||||
|
||||
val buyDeepLinks: BuyDeepLinks
|
||||
|
||||
val assetDeepLinks: AssetDeepLinks
|
||||
|
||||
val giftDeepLinks: GiftDeepLinks
|
||||
|
||||
val chainMigrationDeepLinks: ChainMigrationDeepLinks
|
||||
|
||||
val walletConnectDeepLinks: WalletConnectDeepLinks
|
||||
|
||||
val systemCallExecutor: SystemCallExecutor
|
||||
|
||||
val contextManager: ContextManager
|
||||
|
||||
val walletConnectService: WalletConnectService
|
||||
|
||||
val imageLoader: ImageLoader
|
||||
|
||||
val automaticInteractionGate: AutomaticInteractionGate
|
||||
|
||||
val walletConnectSessionsUseCase: WalletConnectSessionsUseCase
|
||||
|
||||
val pushNotificationsInteractor: PushNotificationsInteractor
|
||||
|
||||
val welcomePushNotificationsInteractor: WelcomePushNotificationsInteractor
|
||||
|
||||
val applyLocalSnapshotToCloudBackupUseCase: ApplyLocalSnapshotToCloudBackupUseCase
|
||||
|
||||
val actionBottomSheetLauncherFactory: ActionBottomSheetLauncherFactory
|
||||
|
||||
val tabsDao: BrowserTabsDao
|
||||
|
||||
val balancesUpdateSystem: BalancesUpdateSystem
|
||||
|
||||
val actionAwaitableMixinFactory: ActionAwaitableMixin.Factory
|
||||
|
||||
val browserTabExternalRepository: BrowserTabExternalRepository
|
||||
|
||||
val externalAccountsSyncService: ExternalAccountsSyncService
|
||||
|
||||
val multisigPendingOperationsService: MultisigPendingOperationsService
|
||||
|
||||
val accountMigrationDeepLinks: AccountMigrationDeepLinks
|
||||
|
||||
val multisigDeepLinks: MultisigDeepLinks
|
||||
|
||||
val deepLinkingPreferences: DeepLinkingPreferences
|
||||
|
||||
val branchIoLinkConverter: BranchIoLinkConverter
|
||||
|
||||
val pendingDeepLinkProvider: PendingDeepLinkProvider
|
||||
|
||||
val multisigExtrinsicValidationRequestBus: MultisigExtrinsicValidationRequestBus
|
||||
|
||||
val multisigExtrinsicValidationFactory: MultisigExtrinsicValidationFactory
|
||||
|
||||
val actionBottomSheetLauncher: ActionBottomSheetLauncher
|
||||
|
||||
val multisigPushNotificationsAlertMixinFactory: MultisigPushNotificationsAlertMixinFactory
|
||||
|
||||
val chainMigrationDetailsSelectToShowUseCase: ChainMigrationDetailsSelectToShowUseCase
|
||||
|
||||
val deviceNetworkStateObserver: DeviceNetworkStateObserver
|
||||
|
||||
fun updateNotificationsInteractor(): UpdateNotificationsInteractor
|
||||
|
||||
fun contributionsInteractor(): ContributionsInteractor
|
||||
|
||||
fun crowdloanRepository(): CrowdloanRepository
|
||||
|
||||
fun networkStateMixin(): NetworkStateMixin
|
||||
|
||||
fun externalRequirementsFlow(): MutableStateFlow<ChainConnection.ExternalRequirement>
|
||||
|
||||
fun accountRepository(): AccountRepository
|
||||
|
||||
fun walletRepository(): WalletRepository
|
||||
|
||||
fun appLinksProvider(): AppLinksProvider
|
||||
|
||||
fun resourceManager(): ResourceManager
|
||||
|
||||
fun currencyInteractor(): CurrencyInteractor
|
||||
|
||||
fun stakingRepository(): StakingRepository
|
||||
|
||||
fun chainRegistry(): ChainRegistry
|
||||
|
||||
fun backgroundAccessObserver(): BackgroundAccessObserver
|
||||
|
||||
fun safeModeService(): SafeModeService
|
||||
|
||||
fun rootScope(): RootScope
|
||||
|
||||
fun governanceStateUpdater(): MutableGovernanceState
|
||||
|
||||
fun dappMetadataRepository(): DAppMetadataRepository
|
||||
|
||||
fun encryptionDefaults(): EncryptionDefaults
|
||||
|
||||
fun proxyExtrinsicValidationRequestBus(): ProxyExtrinsicValidationRequestBus
|
||||
|
||||
fun metaAccountChangesRequestBus(): MetaAccountChangesEventBus
|
||||
|
||||
fun proxyHaveEnoughFeeValidationFactory(): ProxyHaveEnoughFeeValidationFactory
|
||||
|
||||
fun context(): Context
|
||||
|
||||
fun toastMessageManager(): ToastMessageManager
|
||||
|
||||
fun dialogMessageManager(): DialogMessageManager
|
||||
|
||||
fun chainMigrationRepository(): ChainMigrationRepository
|
||||
|
||||
fun migrationInfoRepository(): MigrationInfoRepository
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package io.novafoundation.nova.app.root.di
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.holders.RootNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.holders.SplitScreenNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.staking.StakingDashboardNavigator
|
||||
import io.novafoundation.nova.common.di.FeatureApiHolder
|
||||
import io.novafoundation.nova.common.di.FeatureContainer
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.common.navigation.DelayedNavigationRouter
|
||||
import io.novafoundation.nova.core_db.di.DbApi
|
||||
import io.novafoundation.nova.feature_account_api.di.AccountFeatureApi
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
import io.novafoundation.nova.feature_account_migration.di.AccountMigrationFeatureApi
|
||||
import io.novafoundation.nova.feature_ahm_api.di.ChainMigrationFeatureApi
|
||||
import io.novafoundation.nova.feature_assets.di.AssetsFeatureApi
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
import io.novafoundation.nova.feature_buy_api.di.BuyFeatureApi
|
||||
import io.novafoundation.nova.feature_crowdloan_api.di.CrowdloanFeatureApi
|
||||
import io.novafoundation.nova.feature_currency_api.di.CurrencyFeatureApi
|
||||
import io.novafoundation.nova.feature_dapp_api.di.DAppFeatureApi
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter
|
||||
import io.novafoundation.nova.feature_deep_linking.di.DeepLinkingFeatureApi
|
||||
import io.novafoundation.nova.feature_gift_api.di.GiftFeatureApi
|
||||
import io.novafoundation.nova.feature_governance_api.di.GovernanceFeatureApi
|
||||
import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter
|
||||
import io.novafoundation.nova.feature_ledger_api.di.LedgerFeatureApi
|
||||
import io.novafoundation.nova.feature_multisig_operations.di.MultisigOperationsFeatureApi
|
||||
import io.novafoundation.nova.feature_push_notifications.di.PushNotificationsFeatureApi
|
||||
import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi
|
||||
import io.novafoundation.nova.feature_staking_impl.presentation.StakingRouter
|
||||
import io.novafoundation.nova.feature_versions_api.di.VersionsFeatureApi
|
||||
import io.novafoundation.nova.feature_wallet_api.di.WalletFeatureApi
|
||||
import io.novafoundation.nova.feature_wallet_connect_api.di.WalletConnectFeatureApi
|
||||
import io.novafoundation.nova.runtime.di.RuntimeApi
|
||||
import javax.inject.Inject
|
||||
|
||||
@ApplicationScope
|
||||
class RootFeatureHolder @Inject constructor(
|
||||
private val splitScreenNavigationHolder: SplitScreenNavigationHolder,
|
||||
private val rootNavigationHolder: RootNavigationHolder,
|
||||
private val navigator: Navigator,
|
||||
private val governanceRouter: GovernanceRouter,
|
||||
private val dAppRouter: DAppRouter,
|
||||
private val accountRouter: AccountRouter,
|
||||
private val assetsRouter: AssetsRouter,
|
||||
private val stakingRouter: StakingRouter,
|
||||
private val stakingDashboardNavigator: StakingDashboardNavigator,
|
||||
private val delayedNavRouter: DelayedNavigationRouter,
|
||||
featureContainer: FeatureContainer
|
||||
) : FeatureApiHolder(featureContainer) {
|
||||
|
||||
override fun initializeDependencies(): Any {
|
||||
val rootFeatureDependencies = DaggerRootComponent_RootFeatureDependenciesComponent.builder()
|
||||
.commonApi(commonApi())
|
||||
.dbApi(getFeature(DbApi::class.java))
|
||||
.accountFeatureApi(getFeature(AccountFeatureApi::class.java))
|
||||
.walletFeatureApi(getFeature(WalletFeatureApi::class.java))
|
||||
.stakingFeatureApi(getFeature(StakingFeatureApi::class.java))
|
||||
.assetsFeatureApi(getFeature(AssetsFeatureApi::class.java))
|
||||
.currencyFeatureApi(getFeature(CurrencyFeatureApi::class.java))
|
||||
.crowdloanFeatureApi(getFeature(CrowdloanFeatureApi::class.java))
|
||||
.governanceFeatureApi(getFeature(GovernanceFeatureApi::class.java))
|
||||
.dAppFeatureApi(getFeature(DAppFeatureApi::class.java))
|
||||
.runtimeApi(getFeature(RuntimeApi::class.java))
|
||||
.versionsFeatureApi(getFeature(VersionsFeatureApi::class.java))
|
||||
.walletConnectFeatureApi(getFeature(WalletConnectFeatureApi::class.java))
|
||||
.pushNotificationsFeatureApi(getFeature(PushNotificationsFeatureApi::class.java))
|
||||
.deepLinkingFeatureApi(getFeature(DeepLinkingFeatureApi::class.java))
|
||||
.ledgerFeatureApi(getFeature(LedgerFeatureApi::class.java))
|
||||
.buyFeatureApi(getFeature(BuyFeatureApi::class.java))
|
||||
.deepLinkingFeatureApi(getFeature(DeepLinkingFeatureApi::class.java))
|
||||
.accountMigrationFeatureApi(getFeature(AccountMigrationFeatureApi::class.java))
|
||||
.multisigOperationsFeatureApi(getFeature(MultisigOperationsFeatureApi::class.java))
|
||||
.chainMigrationFeatureApi(getFeature(ChainMigrationFeatureApi::class.java))
|
||||
.giftFeatureApi(getFeature(GiftFeatureApi::class.java))
|
||||
.build()
|
||||
|
||||
return DaggerRootComponent.factory()
|
||||
.create(
|
||||
splitScreenNavigationHolder,
|
||||
rootNavigationHolder,
|
||||
navigator,
|
||||
governanceRouter,
|
||||
dAppRouter,
|
||||
assetsRouter,
|
||||
accountRouter,
|
||||
stakingRouter,
|
||||
stakingDashboardNavigator,
|
||||
delayedNavRouter,
|
||||
rootFeatureDependencies
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package io.novafoundation.nova.app.root.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.app.root.di.busHandler.RequestBusHandlerModule
|
||||
import io.novafoundation.nova.app.root.di.deeplink.DeepLinksModule
|
||||
import io.novafoundation.nova.app.root.domain.RootInteractor
|
||||
import io.novafoundation.nova.common.di.scope.FeatureScope
|
||||
import io.novafoundation.nova.feature_account_api.data.externalAccounts.ExternalAccountsSyncService
|
||||
import io.novafoundation.nova.feature_account_api.data.multisig.MultisigPendingOperationsService
|
||||
import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository
|
||||
import io.novafoundation.nova.feature_ahm_api.data.repository.ChainMigrationRepository
|
||||
import io.novafoundation.nova.feature_ahm_api.data.repository.MigrationInfoRepository
|
||||
import io.novafoundation.nova.feature_assets.data.network.BalancesUpdateSystem
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.interfaces.WalletRepository
|
||||
|
||||
@Module(
|
||||
includes = [
|
||||
RequestBusHandlerModule::class,
|
||||
ExternalServiceInitializersModule::class,
|
||||
DeepLinksModule::class
|
||||
]
|
||||
)
|
||||
class RootFeatureModule {
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
fun provideRootInteractor(
|
||||
walletRepository: WalletRepository,
|
||||
accountRepository: AccountRepository,
|
||||
balancesUpdateSystem: BalancesUpdateSystem,
|
||||
multisigPendingOperationsService: MultisigPendingOperationsService,
|
||||
externalAccountsSyncService: ExternalAccountsSyncService,
|
||||
chainMigrationRepository: ChainMigrationRepository,
|
||||
migrationInfoRepository: MigrationInfoRepository
|
||||
): RootInteractor {
|
||||
return RootInteractor(
|
||||
updateSystem = balancesUpdateSystem,
|
||||
walletRepository = walletRepository,
|
||||
accountRepository = accountRepository,
|
||||
multisigPendingOperationsService = multisigPendingOperationsService,
|
||||
externalAccountsSyncService = externalAccountsSyncService,
|
||||
chainMigrationRepository = chainMigrationRepository,
|
||||
migrationInfoRepository = migrationInfoRepository
|
||||
)
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package io.novafoundation.nova.app.root.di.busHandler
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.multibindings.IntoSet
|
||||
import io.novafoundation.nova.app.root.presentation.RootRouter
|
||||
import io.novafoundation.nova.app.root.presentation.requestBusHandler.CloudBackupSyncRequestBusHandler
|
||||
import io.novafoundation.nova.app.root.presentation.requestBusHandler.CompoundRequestBusHandler
|
||||
import io.novafoundation.nova.app.root.presentation.requestBusHandler.MultisigExtrinsicValidationRequestBusHandler
|
||||
import io.novafoundation.nova.app.root.presentation.requestBusHandler.ProxyExtrinsicValidationRequestBusHandler
|
||||
import io.novafoundation.nova.app.root.presentation.requestBusHandler.PushSettingsSyncRequestBusHandler
|
||||
import io.novafoundation.nova.app.root.presentation.requestBusHandler.RequestBusHandler
|
||||
import io.novafoundation.nova.common.di.scope.FeatureScope
|
||||
import io.novafoundation.nova.common.resources.ResourceManager
|
||||
import io.novafoundation.nova.common.utils.sequrity.AutomaticInteractionGate
|
||||
import io.novafoundation.nova.common.view.bottomSheet.action.ActionBottomSheetLauncher
|
||||
import io.novafoundation.nova.feature_account_api.data.proxy.validation.ProxyExtrinsicValidationRequestBus
|
||||
import io.novafoundation.nova.feature_account_api.data.events.MetaAccountChangesEventBus
|
||||
import io.novafoundation.nova.feature_account_api.data.multisig.validation.MultisigExtrinsicValidationRequestBus
|
||||
import io.novafoundation.nova.feature_account_api.domain.cloudBackup.ApplyLocalSnapshotToCloudBackupUseCase
|
||||
import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository
|
||||
import io.novafoundation.nova.feature_push_notifications.domain.interactor.PushNotificationsInteractor
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.validation.MultisigExtrinsicValidationFactory
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.validation.ProxyHaveEnoughFeeValidationFactory
|
||||
|
||||
@Module
|
||||
class RequestBusHandlerModule {
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
@IntoSet
|
||||
fun providePushSettingsSyncRequestBusHandler(
|
||||
metaAccountChangesEventBus: MetaAccountChangesEventBus,
|
||||
pushNotificationsInteractor: PushNotificationsInteractor
|
||||
): RequestBusHandler {
|
||||
return PushSettingsSyncRequestBusHandler(
|
||||
metaAccountChangesEventBus,
|
||||
pushNotificationsInteractor
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
@IntoSet
|
||||
fun provideProxyExtrinsicValidationRequestBusHandler(
|
||||
proxyProxyExtrinsicValidationRequestBus: ProxyExtrinsicValidationRequestBus,
|
||||
proxyHaveEnoughFeeValidationFactory: ProxyHaveEnoughFeeValidationFactory
|
||||
): RequestBusHandler {
|
||||
return ProxyExtrinsicValidationRequestBusHandler(
|
||||
proxyProxyExtrinsicValidationRequestBus,
|
||||
proxyHaveEnoughFeeValidationFactory
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
@IntoSet
|
||||
fun provideMultisigExtrinsicValidationRequestBusHandler(
|
||||
multisigExtrinsicValidationRequestBus: MultisigExtrinsicValidationRequestBus,
|
||||
multisigExtrinsicValidationFactory: MultisigExtrinsicValidationFactory
|
||||
): RequestBusHandler {
|
||||
return MultisigExtrinsicValidationRequestBusHandler(
|
||||
multisigExtrinsicValidationRequestBus,
|
||||
multisigExtrinsicValidationFactory
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
@IntoSet
|
||||
fun provideCloudBackupSyncRequestBusHandler(
|
||||
rootRouter: RootRouter,
|
||||
resourceManager: ResourceManager,
|
||||
metaAccountChangesEventBus: MetaAccountChangesEventBus,
|
||||
applyLocalSnapshotToCloudBackupUseCase: ApplyLocalSnapshotToCloudBackupUseCase,
|
||||
accountRepository: AccountRepository,
|
||||
actionBottomSheetLauncher: ActionBottomSheetLauncher,
|
||||
automaticInteractionGate: AutomaticInteractionGate
|
||||
): RequestBusHandler {
|
||||
return CloudBackupSyncRequestBusHandler(
|
||||
rootRouter,
|
||||
resourceManager,
|
||||
metaAccountChangesEventBus,
|
||||
applyLocalSnapshotToCloudBackupUseCase,
|
||||
accountRepository,
|
||||
actionBottomSheetLauncher,
|
||||
automaticInteractionGate
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
fun provideCompoundRequestBusHandler(
|
||||
handlers: Set<@JvmSuppressWildcards RequestBusHandler>
|
||||
): CompoundRequestBusHandler {
|
||||
return CompoundRequestBusHandler(handlers)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package io.novafoundation.nova.app.root.di.deeplink
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.common.di.scope.FeatureScope
|
||||
import io.novafoundation.nova.feature_account_api.di.deeplinks.AccountDeepLinks
|
||||
import io.novafoundation.nova.feature_account_migration.di.deeplinks.AccountMigrationDeepLinks
|
||||
import io.novafoundation.nova.feature_ahm_api.di.deeplinks.ChainMigrationDeepLinks
|
||||
import io.novafoundation.nova.feature_assets.di.modules.deeplinks.AssetDeepLinks
|
||||
import io.novafoundation.nova.feature_buy_api.di.deeplinks.BuyDeepLinks
|
||||
import io.novafoundation.nova.feature_dapp_api.di.deeplinks.DAppDeepLinks
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.DeepLinkHandler
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.PendingDeepLinkProvider
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.RootDeepLinkHandler
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.branchIo.BranchIOLinkHandler
|
||||
import io.novafoundation.nova.feature_deep_linking.presentation.handling.branchIo.BranchIoLinkConverter
|
||||
import io.novafoundation.nova.feature_gift_api.di.GiftDeepLinks
|
||||
import io.novafoundation.nova.feature_governance_api.di.deeplinks.GovernanceDeepLinks
|
||||
import io.novafoundation.nova.feature_multisig_operations.di.deeplink.MultisigDeepLinks
|
||||
import io.novafoundation.nova.feature_staking_api.di.deeplinks.StakingDeepLinks
|
||||
import io.novafoundation.nova.feature_wallet_connect_api.di.deeplinks.WalletConnectDeepLinks
|
||||
|
||||
@Module
|
||||
class DeepLinksModule {
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
fun provideDeepLinkHandlers(
|
||||
stakingDeepLinks: StakingDeepLinks,
|
||||
accountDeepLinks: AccountDeepLinks,
|
||||
dAppDeepLinks: DAppDeepLinks,
|
||||
governanceDeepLinks: GovernanceDeepLinks,
|
||||
buyDeepLinks: BuyDeepLinks,
|
||||
assetDeepLinks: AssetDeepLinks,
|
||||
walletConnectDeepLinks: WalletConnectDeepLinks,
|
||||
accountMigrationDeepLinks: AccountMigrationDeepLinks,
|
||||
multisigDeepLinks: MultisigDeepLinks,
|
||||
chainMigrationDeepLinks: ChainMigrationDeepLinks,
|
||||
giftDeepLinks: GiftDeepLinks
|
||||
): List<@JvmWildcard DeepLinkHandler> {
|
||||
return buildList {
|
||||
addAll(stakingDeepLinks.deepLinkHandlers)
|
||||
addAll(accountDeepLinks.deepLinkHandlers)
|
||||
addAll(dAppDeepLinks.deepLinkHandlers)
|
||||
addAll(governanceDeepLinks.deepLinkHandlers)
|
||||
addAll(buyDeepLinks.deepLinkHandlers)
|
||||
addAll(assetDeepLinks.deepLinkHandlers)
|
||||
addAll(walletConnectDeepLinks.deepLinkHandlers)
|
||||
addAll(accountMigrationDeepLinks.deepLinkHandlers)
|
||||
addAll(multisigDeepLinks.deepLinkHandlers)
|
||||
addAll(chainMigrationDeepLinks.deepLinkHandlers)
|
||||
addAll(giftDeepLinks.deepLinkHandlers)
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
fun provideRootDeepLinkHandler(
|
||||
pendingDeepLinkProvider: PendingDeepLinkProvider,
|
||||
nestedHandlers: @JvmWildcard List<DeepLinkHandler>
|
||||
): RootDeepLinkHandler {
|
||||
return RootDeepLinkHandler(
|
||||
pendingDeepLinkProvider,
|
||||
nestedHandlers
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@FeatureScope
|
||||
fun provideBranchIOLinkHandler(
|
||||
branchIoLinkConverter: BranchIoLinkConverter
|
||||
): BranchIOLinkHandler {
|
||||
return BranchIOLinkHandler(branchIoLinkConverter)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package io.novafoundation.nova.app.root.domain
|
||||
|
||||
import io.novafoundation.nova.common.data.memory.ComputationalScope
|
||||
import io.novafoundation.nova.core.updater.Updater
|
||||
import io.novafoundation.nova.feature_account_api.data.externalAccounts.ExternalAccountsSyncService
|
||||
import io.novafoundation.nova.feature_account_api.data.multisig.MultisigPendingOperationsService
|
||||
import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository
|
||||
import io.novafoundation.nova.feature_ahm_api.data.repository.ChainMigrationRepository
|
||||
import io.novafoundation.nova.feature_ahm_api.data.repository.MigrationInfoRepository
|
||||
import io.novafoundation.nova.feature_assets.data.network.BalancesUpdateSystem
|
||||
import io.novafoundation.nova.feature_wallet_api.domain.interfaces.WalletRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class RootInteractor(
|
||||
private val updateSystem: BalancesUpdateSystem,
|
||||
private val walletRepository: WalletRepository,
|
||||
private val accountRepository: AccountRepository,
|
||||
private val multisigPendingOperationsService: MultisigPendingOperationsService,
|
||||
private val externalAccountsSyncService: ExternalAccountsSyncService,
|
||||
private val chainMigrationRepository: ChainMigrationRepository,
|
||||
private val migrationInfoRepository: MigrationInfoRepository
|
||||
) {
|
||||
|
||||
fun runBalancesUpdate(): Flow<Updater.SideEffect> = updateSystem.start()
|
||||
|
||||
suspend fun updatePhishingAddresses() {
|
||||
runCatching {
|
||||
walletRepository.updatePhishingAddresses()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun isAccountSelected(): Boolean {
|
||||
return accountRepository.isAccountSelected()
|
||||
}
|
||||
|
||||
suspend fun isPinCodeSet(): Boolean {
|
||||
return accountRepository.isCodeSet()
|
||||
}
|
||||
|
||||
fun syncExternalAccounts() {
|
||||
externalAccountsSyncService.sync()
|
||||
}
|
||||
|
||||
context(ComputationalScope)
|
||||
fun syncPendingMultisigOperations(): Flow<Unit> {
|
||||
return multisigPendingOperationsService.performMultisigOperationsSync()
|
||||
}
|
||||
|
||||
suspend fun cacheBalancesForChainMigrationDetection() {
|
||||
chainMigrationRepository.cacheBalancesForChainMigrationDetection()
|
||||
}
|
||||
|
||||
suspend fun loadMigrationDetailsConfigs() {
|
||||
migrationInfoRepository.loadConfigs()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.novafoundation.nova.app.root.domain
|
||||
|
||||
import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository
|
||||
import io.novafoundation.nova.feature_dapp_api.data.model.SimpleTabModel
|
||||
import io.novafoundation.nova.feature_dapp_api.data.repository.BrowserTabExternalRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
|
||||
class SplitScreenInteractor(
|
||||
private val repository: BrowserTabExternalRepository,
|
||||
private val accountRepository: AccountRepository
|
||||
) {
|
||||
|
||||
fun observeTabNamesById(): Flow<List<SimpleTabModel>> {
|
||||
return accountRepository.selectedMetaAccountFlow()
|
||||
.flatMapLatest { repository.observeTabsWithNames(it.id) }
|
||||
}
|
||||
|
||||
suspend fun removeAllTabs() {
|
||||
val metaAccount = accountRepository.getSelectedMetaAccount()
|
||||
repository.removeTabsForMetaAccount(metaAccount.id)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.novafoundation.nova.app.root.navigation
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.navigation.NavBackStackEntry
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraph
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.delayedNavigation.NavComponentDelayedNavigation
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.presentation.splitScreen.SplitScreenFragment
|
||||
import io.novafoundation.nova.app.root.presentation.splitScreen.SplitScreenPayload
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
fun NavController.getBackStackEntryBefore(@IdRes id: Int): NavBackStackEntry {
|
||||
val initial = getBackStackEntry(id)
|
||||
val backStack = backStack.toList()
|
||||
|
||||
val initialIndex = backStack.indexOf(initial)
|
||||
|
||||
var previousIndex = initialIndex - 1
|
||||
|
||||
// ignore nav graphs
|
||||
while (previousIndex > 0 && backStack[previousIndex].destination is NavGraph) {
|
||||
previousIndex--
|
||||
}
|
||||
|
||||
return backStack[previousIndex]
|
||||
}
|
||||
|
||||
fun BaseNavigator.openSplitScreenWithInstantAction(actionId: Int, nestedActionExtras: Bundle? = null) {
|
||||
val delayedNavigation = NavComponentDelayedNavigation(actionId, nestedActionExtras)
|
||||
|
||||
val splitScreenPayload = SplitScreenPayload.InstantNavigationOnAttach(delayedNavigation)
|
||||
navigationBuilder().action(R.id.action_open_split_screen)
|
||||
.setArgs(SplitScreenFragment.createPayload(splitScreenPayload))
|
||||
.navigateInRoot()
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package io.novafoundation.nova.app.root.navigation
|
||||
|
||||
import io.novafoundation.nova.common.navigation.InterScreenCommunicator
|
||||
import io.novafoundation.nova.common.utils.singleReplaySharedFlow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
abstract class FlowInterScreenCommunicator<I : Any, O : Any> :
|
||||
InterScreenCommunicator<I, O>,
|
||||
CoroutineScope by CoroutineScope(Dispatchers.Main) {
|
||||
|
||||
private var response: O? = null
|
||||
|
||||
override val responseFlow = singleReplaySharedFlow<O>()
|
||||
|
||||
private var _request: I? = null
|
||||
|
||||
override val latestResponse: O?
|
||||
get() = response
|
||||
|
||||
override val lastState: O?
|
||||
get() = latestResponse
|
||||
|
||||
override val lastInput: I?
|
||||
get() = _request
|
||||
|
||||
abstract fun dispatchRequest(request: I)
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun openRequest(request: I) {
|
||||
_request = request
|
||||
response = null
|
||||
responseFlow.resetReplayCache()
|
||||
|
||||
dispatchRequest(request)
|
||||
}
|
||||
|
||||
override fun respond(response: O) {
|
||||
launch {
|
||||
this@FlowInterScreenCommunicator.response = response
|
||||
responseFlow.emit(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package io.novafoundation.nova.app.root.navigation
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.navigation.NavBackStackEntry
|
||||
import androidx.navigation.NavController
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.builder.NavigationBuilderRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.navigationBuilder
|
||||
import io.novafoundation.nova.common.navigation.InterScreenCommunicator
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import java.util.UUID
|
||||
|
||||
abstract class NavStackInterScreenCommunicator<I : Parcelable, O : Parcelable>(
|
||||
private val navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : InterScreenCommunicator<I, O> {
|
||||
|
||||
private val responseKey = UUID.randomUUID().toString()
|
||||
private val requestKey = UUID.randomUUID().toString()
|
||||
|
||||
protected val navController: NavController
|
||||
get() = navigationHoldersRegistry.firstAttachedNavController!!
|
||||
|
||||
// from requester - retrieve from current entry
|
||||
override val latestResponse: O?
|
||||
get() = navController.currentBackStackEntry!!.savedStateHandle
|
||||
.get(responseKey)
|
||||
|
||||
// from responder - retrieve from previous (requester) entry
|
||||
override val lastState: O?
|
||||
get() = navController.previousBackStackEntry!!.savedStateHandle
|
||||
.get(responseKey)
|
||||
|
||||
override val responseFlow: Flow<O>
|
||||
get() = createResponseFlow()
|
||||
|
||||
// from responder - retrieve from previous (requester) entry
|
||||
override val lastInput: I?
|
||||
get() = navController.previousBackStackEntry!!.savedStateHandle
|
||||
.get(requestKey)
|
||||
|
||||
@CallSuper
|
||||
override fun openRequest(request: I) {
|
||||
saveRequest(request)
|
||||
}
|
||||
|
||||
fun clearedResponseFlow(): Flow<O> {
|
||||
navController.currentBackStackEntry!!.savedStateHandle.apply {
|
||||
remove<O>(requestKey)
|
||||
remove<O>(responseKey)
|
||||
}
|
||||
return createResponseFlow()
|
||||
}
|
||||
|
||||
override fun respond(response: O) {
|
||||
// previousBackStackEntry since we want to report to previous screen
|
||||
saveResultTo(navController.previousBackStackEntry!!, response)
|
||||
}
|
||||
|
||||
protected fun saveResultTo(backStackEntry: NavBackStackEntry, response: O) {
|
||||
backStackEntry.savedStateHandle.set(responseKey, response)
|
||||
}
|
||||
|
||||
private fun saveRequest(request: I) {
|
||||
navController.currentBackStackEntry!!.savedStateHandle.set(requestKey, request)
|
||||
}
|
||||
|
||||
private fun createResponseFlow(): Flow<O> {
|
||||
return navController.currentBackStackEntry!!.savedStateHandle
|
||||
.getLiveData<O>(responseKey)
|
||||
.asFlow()
|
||||
}
|
||||
|
||||
protected fun navigationBuilder(): NavigationBuilderRegistry {
|
||||
return navigationHoldersRegistry.navigationBuilder()
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package io.novafoundation.nova.app.root.navigation.delayedNavigation
|
||||
|
||||
import io.novafoundation.nova.common.navigation.DelayedNavigation
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
object BackDelayedNavigation : DelayedNavigation
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package io.novafoundation.nova.app.root.navigation.delayedNavigation
|
||||
|
||||
import android.os.Bundle
|
||||
import io.novafoundation.nova.common.navigation.DelayedNavigation
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
class NavComponentDelayedNavigation(val globalActionId: Int, val extras: Bundle? = null) : DelayedNavigation
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package io.novafoundation.nova.app.root.navigation.holders
|
||||
|
||||
import androidx.navigation.NavController
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
|
||||
abstract class NavigationHolder(val contextManager: ContextManager) {
|
||||
|
||||
var navController: NavController? = null
|
||||
private set
|
||||
|
||||
fun isControllerAttached(): Boolean {
|
||||
return navController != null
|
||||
}
|
||||
|
||||
fun attach(navController: NavController) {
|
||||
this.navController = navController
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches the current navController only if it matches the one provided.
|
||||
* This check ensures that if a new screen with a navController is attached,
|
||||
* it doesn't lose its navController when the previous screen calls detach.
|
||||
* By verifying equality, we prevent unintended detachment.
|
||||
*/
|
||||
fun detachNavController(navController: NavController) {
|
||||
if (this.navController == navController) {
|
||||
this.navController = null
|
||||
}
|
||||
}
|
||||
|
||||
fun detach() {
|
||||
navController = null
|
||||
}
|
||||
|
||||
fun finishApp() {
|
||||
contextManager.getActivity()?.finish()
|
||||
}
|
||||
|
||||
fun executeBack() {
|
||||
val popped = navController!!.popBackStack()
|
||||
|
||||
if (!popped) {
|
||||
contextManager.getActivity()!!.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package io.novafoundation.nova.app.root.navigation.holders
|
||||
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
|
||||
class RootNavigationHolder(contextManager: ContextManager) : NavigationHolder(contextManager)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package io.novafoundation.nova.app.root.navigation.holders
|
||||
|
||||
import io.novafoundation.nova.common.resources.ContextManager
|
||||
|
||||
class SplitScreenNavigationHolder(contextManager: ContextManager) : NavigationHolder(contextManager)
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigationFragment
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
|
||||
class MainNavHostFragment : NovaNavHostFragment() {
|
||||
|
||||
override val containerId: Int = R.id.mainNavHost
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigationFragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.DialogFragmentNavigator
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.AddFragmentNavigator
|
||||
|
||||
abstract class NovaNavHostFragment : NavHostFragment() {
|
||||
|
||||
abstract val containerId: Int
|
||||
|
||||
@SuppressLint("MissingSuperCall")
|
||||
override fun onCreateNavController(navController: NavController) {
|
||||
navController.navigatorProvider.addNavigator(DialogFragmentNavigator(requireContext(), childFragmentManager))
|
||||
val addFragmentNavigator = AddFragmentNavigator(requireContext(), childFragmentManager, containerId)
|
||||
|
||||
navController.navigatorProvider.addNavigator(addFragmentNavigator)
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigationFragment
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
|
||||
class RootNavHostFragment : NovaNavHostFragment() {
|
||||
|
||||
override val containerId: Int = R.id.rootNavHost
|
||||
}
|
||||
+352
@@ -0,0 +1,352 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.navigation.NavDestination;
|
||||
import androidx.navigation.NavOptions;
|
||||
import androidx.navigation.Navigator;
|
||||
import androidx.navigation.NavigatorProvider;
|
||||
import androidx.navigation.fragment.FragmentNavigator;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.novafoundation.nova.app.R;
|
||||
|
||||
/**
|
||||
* This is an improved version (aka copy-paste with fixes) of
|
||||
* {@link androidx.navigation.fragment.FragmentNavigator} which allows not only to replace old
|
||||
* fragment with new one, but also add new and hide old one.
|
||||
* The difference with original implementation from google library is in navigate() method (
|
||||
* <code>if (destination.shouldUseAdd) ...</code> )and in modified Destination subclass
|
||||
* which includes <code>shouldUseAdd</code> flag
|
||||
*/
|
||||
@Navigator.Name("fragment")
|
||||
public class AddFragmentNavigator extends Navigator<AddFragmentNavigator.Destination> {
|
||||
private static final String TAG = "FragmentNavigator";
|
||||
private static final String KEY_BACK_STACK_IDS = "androidx-nav-fragment:navigator:backStackIds";
|
||||
|
||||
private final Context mContext;
|
||||
private final FragmentManager mFragmentManager;
|
||||
private final int mContainerId;
|
||||
private ArrayDeque<Integer> mBackStack = new ArrayDeque<>();
|
||||
|
||||
public AddFragmentNavigator(@NonNull Context context, @NonNull FragmentManager manager,
|
||||
int containerId) {
|
||||
mContext = context;
|
||||
mFragmentManager = manager;
|
||||
mContainerId = containerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* This method must call
|
||||
* {@link FragmentTransaction#setPrimaryNavigationFragment(Fragment)}
|
||||
* if the pop succeeded so that the newly visible Fragment can be retrieved with
|
||||
* {@link FragmentManager#getPrimaryNavigationFragment()}.
|
||||
* <p>
|
||||
* Note that the default implementation pops the Fragment
|
||||
* asynchronously, so the newly visible Fragment from the back stack
|
||||
* is not instantly available after this call completes.
|
||||
*/
|
||||
@Override
|
||||
public boolean popBackStack() {
|
||||
if (mBackStack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (mFragmentManager.isStateSaved()) {
|
||||
Log.i(TAG, "Ignoring popBackStack() call: FragmentManager has already"
|
||||
+ " saved its state");
|
||||
return false;
|
||||
}
|
||||
mFragmentManager.popBackStack(
|
||||
generateBackStackName(mBackStack.size(), mBackStack.peekLast()),
|
||||
FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
mBackStack.removeLast();
|
||||
return true;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AddFragmentNavigator.Destination createDestination() {
|
||||
return new AddFragmentNavigator.Destination(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates the Fragment via the FragmentManager's
|
||||
* {@link androidx.fragment.app.FragmentFactory}.
|
||||
* Note that this method is <strong>not</strong> responsible for calling
|
||||
* {@link Fragment#setArguments(Bundle)} on the returned Fragment instance.
|
||||
*
|
||||
* @param context Context providing the correct {@link ClassLoader}
|
||||
* @param fragmentManager FragmentManager the Fragment will be added to
|
||||
* @param className The Fragment to instantiate
|
||||
* @param args The Fragment's arguments, if any
|
||||
* @return A new fragment instance.
|
||||
* @deprecated Set a custom {@link androidx.fragment.app.FragmentFactory} via
|
||||
* {@link FragmentManager#setFragmentFactory(androidx.fragment.app.FragmentFactory)} to control
|
||||
* instantiation of Fragments.
|
||||
*/
|
||||
@SuppressWarnings("DeprecatedIsStillUsed") // needed to maintain forward compatibility
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public Fragment instantiateFragment(@NonNull Context context,
|
||||
@NonNull FragmentManager fragmentManager,
|
||||
@NonNull String className, @SuppressWarnings("unused") @Nullable Bundle args) {
|
||||
return fragmentManager.getFragmentFactory().instantiate(
|
||||
context.getClassLoader(), className);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* This method should always call
|
||||
* {@link FragmentTransaction#setPrimaryNavigationFragment(Fragment)}
|
||||
* so that the Fragment associated with the new destination can be retrieved with
|
||||
* {@link FragmentManager#getPrimaryNavigationFragment()}.
|
||||
* <p>
|
||||
* Note that the default implementation commits the new Fragment
|
||||
* asynchronously, so the new Fragment is not instantly available
|
||||
* after this call completes.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") /* Using instantiateFragment for forward compatibility */
|
||||
@Nullable
|
||||
@Override
|
||||
public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args,
|
||||
@Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {
|
||||
if (mFragmentManager.isStateSaved()) {
|
||||
Log.i(TAG, "Ignoring navigate() call: FragmentManager has already"
|
||||
+ " saved its state");
|
||||
return null;
|
||||
}
|
||||
String className = destination.getClassName();
|
||||
if (className.charAt(0) == '.') {
|
||||
className = mContext.getPackageName() + className;
|
||||
}
|
||||
final Fragment frag = instantiateFragment(mContext, mFragmentManager,
|
||||
className, args);
|
||||
frag.setArguments(args);
|
||||
final FragmentTransaction ft = mFragmentManager.beginTransaction();
|
||||
|
||||
int enterAnim = navOptions != null ? navOptions.getEnterAnim() : -1;
|
||||
int exitAnim = navOptions != null ? navOptions.getExitAnim() : -1;
|
||||
int popEnterAnim = navOptions != null ? navOptions.getPopEnterAnim() : -1;
|
||||
int popExitAnim = navOptions != null ? navOptions.getPopExitAnim() : -1;
|
||||
if (enterAnim != -1 || exitAnim != -1 || popEnterAnim != -1 || popExitAnim != -1) {
|
||||
enterAnim = enterAnim != -1 ? enterAnim : 0;
|
||||
exitAnim = exitAnim != -1 ? exitAnim : 0;
|
||||
popEnterAnim = popEnterAnim != -1 ? popEnterAnim : 0;
|
||||
popExitAnim = popExitAnim != -1 ? popExitAnim : 0;
|
||||
ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim);
|
||||
}
|
||||
|
||||
if (destination.shouldUseAdd) {
|
||||
List<Fragment> fragments = mFragmentManager.getFragments();
|
||||
for (Fragment fragment : fragments) {
|
||||
if (fragment.isHidden()) continue;
|
||||
|
||||
ft.hide(fragment);
|
||||
}
|
||||
ft.add(mContainerId, frag);
|
||||
} else {
|
||||
ft.replace(mContainerId, frag);
|
||||
}
|
||||
ft.setPrimaryNavigationFragment(frag);
|
||||
|
||||
final @IdRes int destId = destination.getId();
|
||||
final boolean initialNavigation = mBackStack.isEmpty();
|
||||
// TODO Build first class singleTop behavior for fragments
|
||||
final boolean isSingleTopReplacement = navOptions != null && !initialNavigation
|
||||
&& navOptions.shouldLaunchSingleTop()
|
||||
&& mBackStack.peekLast() == destId;
|
||||
|
||||
boolean isAdded;
|
||||
if (initialNavigation) {
|
||||
isAdded = true;
|
||||
} else if (isSingleTopReplacement) {
|
||||
// Single Top means we only want one instance on the back stack
|
||||
if (mBackStack.size() > 1) {
|
||||
// If the Fragment to be replaced is on the FragmentManager's
|
||||
// back stack, a simple replace() isn't enough so we
|
||||
// remove it from the back stack and put our replacement
|
||||
// on the back stack in its place
|
||||
mFragmentManager.popBackStack(
|
||||
generateBackStackName(mBackStack.size(), mBackStack.peekLast()),
|
||||
FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
ft.addToBackStack(generateBackStackName(mBackStack.size(), destId));
|
||||
}
|
||||
isAdded = false;
|
||||
} else {
|
||||
ft.addToBackStack(generateBackStackName(mBackStack.size() + 1, destId));
|
||||
isAdded = true;
|
||||
}
|
||||
if (navigatorExtras instanceof FragmentNavigator.Extras) {
|
||||
FragmentNavigator.Extras extras = (FragmentNavigator.Extras) navigatorExtras;
|
||||
for (Map.Entry<View, String> sharedElement : extras.getSharedElements().entrySet()) {
|
||||
ft.addSharedElement(sharedElement.getKey(), sharedElement.getValue());
|
||||
}
|
||||
}
|
||||
ft.setReorderingAllowed(true);
|
||||
ft.commit();
|
||||
// The commit succeeded, update our view of the world
|
||||
if (isAdded) {
|
||||
mBackStack.add(destId);
|
||||
return destination;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Bundle onSaveState() {
|
||||
Bundle b = new Bundle();
|
||||
int[] backStack = new int[mBackStack.size()];
|
||||
int index = 0;
|
||||
for (Integer id : mBackStack) {
|
||||
backStack[index++] = id;
|
||||
}
|
||||
b.putIntArray(KEY_BACK_STACK_IDS, backStack);
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreState(@Nullable Bundle savedState) {
|
||||
if (savedState != null) {
|
||||
int[] backStack = savedState.getIntArray(KEY_BACK_STACK_IDS);
|
||||
if (backStack != null) {
|
||||
mBackStack.clear();
|
||||
for (int destId : backStack) {
|
||||
mBackStack.add(destId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String generateBackStackName(int backStackIndex, int destId) {
|
||||
return backStackIndex + "-" + destId;
|
||||
}
|
||||
|
||||
@NavDestination.ClassType(Fragment.class)
|
||||
public static class Destination extends NavDestination {
|
||||
|
||||
private String mClassName;
|
||||
private boolean shouldUseAdd;
|
||||
|
||||
/**
|
||||
* Construct a new fragment destination. This destination is not valid until you set the
|
||||
* Fragment via {@link #setClassName(String)}.
|
||||
*
|
||||
* @param navigatorProvider The {@link androidx.navigation.NavController} which this destination
|
||||
* will be associated with.
|
||||
*/
|
||||
public Destination(@NonNull NavigatorProvider navigatorProvider) {
|
||||
this(navigatorProvider.getNavigator(AddFragmentNavigator.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new fragment destination. This destination is not valid until you set the
|
||||
* Fragment via {@link #setClassName(String)}.
|
||||
*
|
||||
* @param fragmentNavigator The {@link FragmentNavigator} which this destination
|
||||
* will be associated with. Generally retrieved via a
|
||||
* {@link androidx.navigation.NavController}'s
|
||||
* {@link NavigatorProvider#getNavigator(Class)} method.
|
||||
*/
|
||||
public Destination(@NonNull Navigator<? extends Destination> fragmentNavigator) {
|
||||
super(fragmentNavigator);
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
public void onInflate(@NonNull Context context, @NonNull AttributeSet attrs) {
|
||||
super.onInflate(context, attrs);
|
||||
TypedArray fragmentNavigatorArray = context.getResources().obtainAttributes(attrs,
|
||||
R.styleable.FragmentNavigator);
|
||||
String className = fragmentNavigatorArray.getString(R.styleable.FragmentNavigator_android_name);
|
||||
if (className != null) {
|
||||
setClassName(className);
|
||||
}
|
||||
fragmentNavigatorArray.recycle();
|
||||
|
||||
TypedArray novaNavigatorArray = context.getResources().obtainAttributes(attrs,
|
||||
R.styleable.AddFragmentNavigator);
|
||||
|
||||
Boolean useAdd = novaNavigatorArray.getBoolean(R.styleable.AddFragmentNavigator_useAdd, false);
|
||||
setUseAdd(useAdd);
|
||||
novaNavigatorArray.recycle();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public final Destination setUseAdd(@NonNull Boolean useAdd) {
|
||||
this.shouldUseAdd = useAdd;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Fragment's class name associated with this destination
|
||||
*
|
||||
* @throws IllegalStateException when no Fragment class was set.
|
||||
*/
|
||||
@NonNull
|
||||
public final boolean shouldUseAdd() {
|
||||
return shouldUseAdd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Fragment class name associated with this destination
|
||||
*
|
||||
* @param className The class name of the Fragment to show when you navigate to this
|
||||
* destination
|
||||
* @return this {@link androidx.navigation.fragment.FragmentNavigator.Destination}
|
||||
*/
|
||||
@NonNull
|
||||
public final Destination setClassName(@NonNull String className) {
|
||||
mClassName = className;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Fragment's class name associated with this destination
|
||||
*
|
||||
* @throws IllegalStateException when no Fragment class was set.
|
||||
*/
|
||||
@NonNull
|
||||
public final String getClassName() {
|
||||
if (mClassName == null) {
|
||||
throw new IllegalStateException("Fragment class was not set");
|
||||
}
|
||||
return mClassName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(super.toString());
|
||||
sb.append(" class=");
|
||||
if (mClassName == null) {
|
||||
sb.append("null");
|
||||
} else {
|
||||
sb.append(mClassName);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.builder.NavigationBuilderRegistry
|
||||
import io.novafoundation.nova.common.navigation.ReturnableRouter
|
||||
|
||||
abstract class BaseNavigator(
|
||||
private val navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : ReturnableRouter {
|
||||
|
||||
val currentBackStackEntry
|
||||
get() = navigationHoldersRegistry.firstAttachedNavController
|
||||
?.currentBackStackEntry
|
||||
|
||||
val previousBackStackEntry
|
||||
get() = navigationHoldersRegistry.firstAttachedNavController
|
||||
?.previousBackStackEntry
|
||||
|
||||
val currentDestination
|
||||
get() = navigationHoldersRegistry.firstAttachedNavController
|
||||
?.currentDestination
|
||||
|
||||
override fun back() {
|
||||
navigationHoldersRegistry.firstAttachedHolder.executeBack()
|
||||
}
|
||||
|
||||
fun finishApp() {
|
||||
navigationHoldersRegistry.firstAttachedHolder.finishApp()
|
||||
}
|
||||
|
||||
fun navigationBuilder(): NavigationBuilderRegistry {
|
||||
return navigationHoldersRegistry.navigationBuilder()
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators
|
||||
|
||||
import androidx.navigation.NavController
|
||||
import io.novafoundation.nova.app.root.navigation.holders.NavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.holders.RootNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.holders.SplitScreenNavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.builder.NavigationBuilderRegistry
|
||||
|
||||
class NavigationHoldersRegistry(
|
||||
val splitScreenNavigationHolder: SplitScreenNavigationHolder,
|
||||
val rootNavigationHolder: RootNavigationHolder
|
||||
) {
|
||||
|
||||
private val holders = listOf(splitScreenNavigationHolder, rootNavigationHolder)
|
||||
|
||||
val firstAttachedHolder: NavigationHolder
|
||||
get() = holders.first { it.isControllerAttached() }
|
||||
|
||||
val firstAttachedNavController: NavController?
|
||||
get() = firstAttachedHolder.navController
|
||||
}
|
||||
|
||||
fun NavigationHoldersRegistry.navigationBuilder(): NavigationBuilderRegistry {
|
||||
return NavigationBuilderRegistry(this)
|
||||
}
|
||||
@@ -0,0 +1,973 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.navigation.NavOptions
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.delayedNavigation.BackDelayedNavigation
|
||||
import io.novafoundation.nova.app.root.navigation.delayedNavigation.NavComponentDelayedNavigation
|
||||
import io.novafoundation.nova.app.root.navigation.openSplitScreenWithInstantAction
|
||||
import io.novafoundation.nova.app.root.presentation.RootRouter
|
||||
import io.novafoundation.nova.common.navigation.DelayedNavigation
|
||||
import io.novafoundation.nova.common.navigation.DelayedNavigationRouter
|
||||
import io.novafoundation.nova.common.utils.getParcelableCompat
|
||||
import io.novafoundation.nova.common.utils.postToUiThread
|
||||
import io.novafoundation.nova.feature_account_api.domain.model.PolkadotVaultVariant
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.account.add.AddAccountPayload
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.account.add.ImportAccountPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.account.advancedEncryption.AdvancedEncryptionFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.account.advancedEncryption.AdvancedEncryptionModePayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.account.details.WalletDetailsFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.cloudBackup.createPassword.createWallet.CreateBackupPasswordPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.cloudBackup.createPassword.createWallet.CreateWalletBackupPasswordFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.exporting.ExportPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.exporting.json.ExportJsonFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.exporting.seed.ExportSeedFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.importing.ImportAccountFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.legacyAddress.ChainAddressSelectorFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.legacyAddress.ChainAddressSelectorPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.manualBackup.accounts.ManualBackupSelectAccountFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.manualBackup.accounts.ManualBackupSelectAccountPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.manualBackup.common.ManualBackupCommonPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.manualBackup.secrets.advanced.ManualBackupAdvancedSecretsFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.manualBackup.secrets.main.ManualBackupSecretsFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.manualBackup.warning.ManualBackupWarningFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.mnemonic.backup.BackupMnemonicFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.mnemonic.backup.BackupMnemonicPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.mnemonic.confirm.ConfirmMnemonicFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.mnemonic.confirm.ConfirmMnemonicPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.node.details.NodeDetailsFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.connect.ParitySignerAccountPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.connect.ParitySignerStartPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.connect.finish.FinishImportParitySignerFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.connect.preview.PreviewImportParitySignerFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.connect.scan.ScanImportParitySignerFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.connect.start.StartImportParitySignerFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.sign.scan.ScanSignParitySignerFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.sign.scan.model.ScanSignParitySignerPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.pincode.PinCodeAction
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.pincode.PincodeFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.pincode.ToolbarConfiguration
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.startCreateWallet.StartCreateWalletFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.startCreateWallet.StartCreateWalletPayload
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.startCreateWallet.StartCreateWalletPayload.FlowType
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.watchOnly.change.ChangeWatchAccountFragment
|
||||
import io.novafoundation.nova.feature_ahm_impl.presentation.migrationDetails.ChainMigrationDetailsFragment
|
||||
import io.novafoundation.nova.feature_ahm_impl.presentation.migrationDetails.ChainMigrationDetailsPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
import io.novafoundation.nova.feature_assets.presentation.balance.detail.BalanceDetailFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.flow.network.NetworkFlowFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.flow.network.NetworkFlowPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.model.OperationParcelizeModel
|
||||
import io.novafoundation.nova.feature_assets.presentation.receive.ReceiveFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.send.TransferDraft
|
||||
import io.novafoundation.nova.feature_assets.presentation.send.amount.SelectSendFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.send.amount.SendPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.send.confirm.ConfirmSendFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.swap.asset.AssetSwapFlowFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.swap.asset.SwapFlowPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.swap.network.NetworkSwapFlowFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.swap.network.NetworkSwapFlowPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.tokens.add.enterInfo.AddTokenEnterInfoFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.tokens.add.enterInfo.AddTokenEnterInfoPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.tokens.manage.chain.ManageChainTokensFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.tokens.manage.chain.ManageChainTokensPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.trade.common.TradeProviderFlowType
|
||||
import io.novafoundation.nova.feature_assets.presentation.trade.provider.TradeProviderListFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.trade.provider.TradeProviderListPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.trade.webInterface.OnSuccessfulTradeStrategyType
|
||||
import io.novafoundation.nova.feature_assets.presentation.trade.webInterface.TradeWebFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.trade.webInterface.TradeWebPayload
|
||||
import io.novafoundation.nova.feature_assets.presentation.transaction.detail.extrinsic.ExtrinsicDetailFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.transaction.detail.reward.direct.RewardDetailFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.transaction.detail.reward.pool.PoolRewardDetailFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.transaction.detail.swap.SwapDetailFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.transaction.detail.transfer.TransferDetailFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.transaction.filter.TransactionHistoryFilterFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.transaction.filter.TransactionHistoryFilterPayload
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.CrowdloanRouter
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.confirm.ConfirmContributeFragment
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.confirm.parcel.ConfirmContributePayload
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.custom.BonusPayload
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.custom.CustomContributeFragment
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.custom.model.CustomContributePayload
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.custom.moonbeam.terms.MoonbeamCrowdloanTermsFragment
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.select.CrowdloanContributeFragment
|
||||
import io.novafoundation.nova.feature_crowdloan_impl.presentation.contribute.select.parcel.ContributePayload
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.amount.SelectGiftAmountFragment
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.amount.SelectGiftAmountPayload
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.gifts.GiftsFragment
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.gifts.GiftsPayload
|
||||
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.generic.selectLedger.AddEvmAccountSelectGenericLedgerFragment
|
||||
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.generic.selectLedger.AddEvmAccountSelectGenericLedgerPayload
|
||||
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.legacy.selectLedger.AddChainAccountSelectLedgerFragment
|
||||
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.legacy.selectLedger.AddChainAccountSelectLedgerPayload
|
||||
import io.novafoundation.nova.feature_ledger_impl.presentation.account.common.selectLedger.SelectLedgerPayload
|
||||
import io.novafoundation.nova.feature_multisig_operations.presentation.created.MultisigCreatedBottomSheet
|
||||
import io.novafoundation.nova.feature_multisig_operations.presentation.created.MultisigCreatedPayload
|
||||
import io.novafoundation.nova.feature_onboarding_impl.OnboardingRouter
|
||||
import io.novafoundation.nova.feature_onboarding_impl.presentation.welcome.WelcomeFragment
|
||||
import io.novafoundation.nova.feature_swap_api.presentation.model.SwapSettingsPayload
|
||||
import io.novafoundation.nova.feature_swap_impl.presentation.main.SwapMainSettingsFragment
|
||||
import io.novafoundation.nova.feature_wallet_api.presentation.model.AssetPayload
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.WalletConnectRouter
|
||||
import io.novafoundation.nova.feature_wallet_connect_impl.presentation.sessions.list.WalletConnectSessionsPayload
|
||||
import io.novafoundation.nova.splash.SplashRouter
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class Navigator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
private val walletConnectDelegate: WalletConnectRouter
|
||||
) : BaseNavigator(navigationHoldersRegistry),
|
||||
SplashRouter,
|
||||
OnboardingRouter,
|
||||
AccountRouter,
|
||||
AssetsRouter,
|
||||
RootRouter,
|
||||
CrowdloanRouter,
|
||||
DelayedNavigationRouter {
|
||||
|
||||
override fun openWelcomeScreen() {
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.accountsFragment, R.id.action_walletManagment_to_welcome)
|
||||
.addCase(R.id.splashFragment, R.id.action_splash_to_onboarding)
|
||||
.setArgs(WelcomeFragment.bundle(false))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openInitialCheckPincode() {
|
||||
val action = PinCodeAction.Check(NavComponentDelayedNavigation(R.id.action_open_split_screen), ToolbarConfiguration())
|
||||
|
||||
navigationBuilder().action(R.id.action_splash_to_pin)
|
||||
.setArgs(PincodeFragment.getPinCodeBundle(action))
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openCreateFirstWallet() {
|
||||
navigationBuilder().action(R.id.action_welcomeFragment_to_startCreateWallet)
|
||||
.setArgs(StartCreateWalletFragment.bundle(StartCreateWalletPayload(FlowType.FIRST_WALLET)))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openMain() {
|
||||
navigationBuilder().action(R.id.action_open_split_screen)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openAfterPinCode(delayedNavigation: DelayedNavigation) {
|
||||
when (delayedNavigation) {
|
||||
is NavComponentDelayedNavigation -> {
|
||||
val navOptions = NavOptions.Builder()
|
||||
.setPopUpTo(R.id.pincodeFragment, true)
|
||||
.setEnterAnim(R.anim.fragment_open_enter)
|
||||
.setExitAnim(R.anim.fragment_open_exit)
|
||||
.setPopEnterAnim(R.anim.fragment_close_enter)
|
||||
.setPopExitAnim(R.anim.fragment_close_exit)
|
||||
.build()
|
||||
|
||||
navigationBuilder().action(delayedNavigation.globalActionId)
|
||||
.setArgs(delayedNavigation.extras)
|
||||
.setNavOptions(navOptions)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
is BackDelayedNavigation -> back()
|
||||
}
|
||||
}
|
||||
|
||||
override fun openCreatePincode() {
|
||||
val args = buildCreatePinBundle()
|
||||
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.splashFragment, R.id.action_splash_to_pin)
|
||||
.addCase(R.id.importAccountFragment, R.id.action_importAccountFragment_to_pincodeFragment)
|
||||
.addCase(R.id.confirmMnemonicFragment, R.id.action_confirmMnemonicFragment_to_pincodeFragment)
|
||||
.addCase(R.id.createWatchWalletFragment, R.id.action_watchWalletFragment_to_pincodeFragment)
|
||||
.addCase(R.id.finishImportParitySignerFragment, R.id.action_finishImportParitySignerFragment_to_pincodeFragment)
|
||||
.addCase(R.id.finishImportLedgerFragment, R.id.action_finishImportLedgerFragment_to_pincodeFragment)
|
||||
.addCase(R.id.createCloudBackupPasswordFragment, R.id.action_createCloudBackupPasswordFragment_to_pincodeFragment)
|
||||
.addCase(R.id.restoreCloudBackupFragment, R.id.action_restoreCloudBackupFragment_to_pincodeFragment)
|
||||
.addCase(R.id.finishImportGenericLedgerFragment, R.id.action_finishImportGenericLedgerFragment_to_pincodeFragment)
|
||||
.setArgs(args)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openAdvancedSettings(payload: AdvancedEncryptionModePayload) {
|
||||
navigationBuilder().action(R.id.action_open_advancedEncryptionFragment)
|
||||
.setArgs(AdvancedEncryptionFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openConfirmMnemonicOnCreate(confirmMnemonicPayload: ConfirmMnemonicPayload) {
|
||||
navigationBuilder().action(R.id.action_backupMnemonicFragment_to_confirmMnemonicFragment)
|
||||
.setArgs(ConfirmMnemonicFragment.getBundle(confirmMnemonicPayload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openImportAccountScreen(payload: ImportAccountPayload) {
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.splashFragment, R.id.action_splashFragment_to_import_nav_graph)
|
||||
.setFallbackCase(R.id.action_import_nav_graph)
|
||||
.setArgs(ImportAccountFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openMnemonicScreen(accountName: String?, addAccountPayload: AddAccountPayload) {
|
||||
val payload = BackupMnemonicPayload.Create(accountName, addAccountPayload)
|
||||
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.welcomeFragment, R.id.action_welcomeFragment_to_mnemonic_nav_graph)
|
||||
.addCase(R.id.startCreateWalletFragment, R.id.action_startCreateWalletFragment_to_mnemonic_nav_graph)
|
||||
.addCase(R.id.walletDetailsFragment, R.id.action_accountDetailsFragment_to_mnemonic_nav_graph)
|
||||
.setArgs(BackupMnemonicFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openContribute(payload: ContributePayload) {
|
||||
val bundle = CrowdloanContributeFragment.getBundle(payload)
|
||||
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.mainFragment, R.id.action_mainFragment_to_crowdloanContributeFragment)
|
||||
.addCase(R.id.moonbeamCrowdloanTermsFragment, R.id.action_moonbeamCrowdloanTermsFragment_to_crowdloanContributeFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
@Deprecated("TODO: Use communicator api instead")
|
||||
override val customBonusFlow: Flow<BonusPayload?>
|
||||
get() = currentBackStackEntry!!.savedStateHandle
|
||||
.getLiveData<BonusPayload?>(CrowdloanContributeFragment.KEY_BONUS_LIVE_DATA)
|
||||
.asFlow()
|
||||
|
||||
@Deprecated("TODO: Use communicator api instead")
|
||||
override val latestCustomBonus: BonusPayload?
|
||||
get() = currentBackStackEntry!!.savedStateHandle
|
||||
.get(CrowdloanContributeFragment.KEY_BONUS_LIVE_DATA)
|
||||
|
||||
override fun openCustomContribute(payload: CustomContributePayload) {
|
||||
navigationBuilder().action(R.id.action_crowdloanContributeFragment_to_customContributeFragment)
|
||||
.setArgs(CustomContributeFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
@Deprecated("TODO: Use communicator api instead")
|
||||
override fun setCustomBonus(payload: BonusPayload) {
|
||||
previousBackStackEntry!!.savedStateHandle.set(CrowdloanContributeFragment.KEY_BONUS_LIVE_DATA, payload)
|
||||
}
|
||||
|
||||
override fun openConfirmContribute(payload: ConfirmContributePayload) {
|
||||
navigationBuilder().action(R.id.action_crowdloanContributeFragment_to_confirmContributeFragment)
|
||||
.setArgs(ConfirmContributeFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun returnToMain() {
|
||||
navigationBuilder().action(R.id.back_to_main)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openMoonbeamFlow(payload: ContributePayload) {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_moonbeamCrowdloanTermsFragment)
|
||||
.setArgs(MoonbeamCrowdloanTermsFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAddAccount(payload: AddAccountPayload) {
|
||||
navigationBuilder().action(R.id.action_open_onboarding)
|
||||
.setArgs(WelcomeFragment.bundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openFilter(payload: TransactionHistoryFilterPayload) {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_filterFragment)
|
||||
.setArgs(TransactionHistoryFilterFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSend(payload: SendPayload, initialRecipientAddress: String?) {
|
||||
val extras = SelectSendFragment.getBundle(payload, initialRecipientAddress)
|
||||
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.sendFlowFragment, R.id.action_sendFlow_to_send)
|
||||
.addCase(R.id.sendFlowNetworkFragment, R.id.action_sendFlowNetwork_to_send)
|
||||
.setFallbackCase(R.id.action_open_send)
|
||||
.setArgs(extras)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openConfirmTransfer(transferDraft: TransferDraft) {
|
||||
val bundle = ConfirmSendFragment.getBundle(transferDraft)
|
||||
|
||||
navigationBuilder().action(R.id.action_chooseAmountFragment_to_confirmTransferFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openTransferDetail(transaction: OperationParcelizeModel.Transfer) {
|
||||
val bundle = TransferDetailFragment.getBundle(transaction)
|
||||
|
||||
navigationBuilder().action(R.id.open_transfer_detail)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openRewardDetail(reward: OperationParcelizeModel.Reward) {
|
||||
val bundle = RewardDetailFragment.getBundle(reward)
|
||||
|
||||
navigationBuilder().action(R.id.open_reward_detail)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openPoolRewardDetail(reward: OperationParcelizeModel.PoolReward) {
|
||||
val bundle = PoolRewardDetailFragment.getBundle(reward)
|
||||
|
||||
navigationBuilder().action(R.id.open_pool_reward_detail)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSwapDetail(swap: OperationParcelizeModel.Swap) {
|
||||
val bundle = SwapDetailFragment.getBundle(swap)
|
||||
|
||||
navigationBuilder().action(R.id.open_swap_detail)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openExtrinsicDetail(extrinsic: OperationParcelizeModel.Extrinsic) {
|
||||
navigationBuilder().action(R.id.open_extrinsic_detail)
|
||||
.setArgs(ExtrinsicDetailFragment.getBundle(extrinsic))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openWallets() {
|
||||
navigationBuilder().action(R.id.action_open_accounts)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSwitchWallet() {
|
||||
navigationBuilder().action(R.id.action_open_switch_wallet)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openDelegatedAccountsUpdates() {
|
||||
navigationBuilder().action(R.id.action_switchWalletFragment_to_delegatedAccountUpdates)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSelectAddress(arguments: Bundle) {
|
||||
navigationBuilder().action(R.id.action_open_select_address)
|
||||
.setArgs(arguments)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSelectSingleWallet(arguments: Bundle) {
|
||||
navigationBuilder().action(R.id.action_open_select_single_wallet)
|
||||
.setArgs(arguments)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSelectMultipleWallets(arguments: Bundle) {
|
||||
navigationBuilder().action(R.id.action_open_select_multiple_wallets)
|
||||
.setArgs(arguments)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openNodes() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_nodesFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openReceive(assetPayload: AssetPayload) {
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.receiveFlowFragment, R.id.action_receiveFlow_to_receive)
|
||||
.addCase(R.id.receiveFlowNetworkFragment, R.id.action_receiveFlowNetwork_to_receive)
|
||||
.setFallbackCase(R.id.action_open_receive)
|
||||
.setArgs(ReceiveFragment.getBundle(assetPayload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAssetSearch() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_assetSearchFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openManageTokens() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_manageTokensGraph)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openManageChainTokens(payload: ManageChainTokensPayload) {
|
||||
val args = ManageChainTokensFragment.getBundle(payload)
|
||||
navigationBuilder().action(R.id.action_manageTokensFragment_to_manageChainTokensFragment)
|
||||
.setArgs(args)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAddTokenSelectChain() {
|
||||
navigationBuilder().action(R.id.action_manageTokensFragment_to_addTokenSelectChainFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSendFlow() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_sendFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openReceiveFlow() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_receiveFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openBuyFlow() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_buyFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSellFlow() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_sellFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSelectGiftAmount(assetPayload: AssetPayload) {
|
||||
navigationBuilder().action(R.id.action_selectGiftAmount)
|
||||
.setArgs(SelectGiftAmountFragment.createPayload(SelectGiftAmountPayload(assetPayload)))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openBuyFlowFromSendFlow() {
|
||||
navigationBuilder().action(R.id.action_sendFlow_to_buyFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAddTokenEnterInfo(payload: AddTokenEnterInfoPayload) {
|
||||
val args = AddTokenEnterInfoFragment.getBundle(payload)
|
||||
navigationBuilder().action(R.id.action_addTokenSelectChainFragment_to_addTokenEnterInfoFragment)
|
||||
.setArgs(args)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun finishAddTokenFlow() {
|
||||
navigationBuilder().action(R.id.finish_add_token_flow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openWalletConnectSessions(metaId: Long) {
|
||||
walletConnectDelegate.openWalletConnectSessions(WalletConnectSessionsPayload(metaId = metaId))
|
||||
}
|
||||
|
||||
override fun openWalletConnectScan() {
|
||||
walletConnectDelegate.openScanPairingQrCode()
|
||||
}
|
||||
|
||||
override fun closeSendFlow() {
|
||||
navigationBuilder().action(R.id.action_close_send_flow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openNovaCard() {
|
||||
navigationBuilder().action(R.id.action_open_novaCard)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAwaitingCardCreation() {
|
||||
navigationBuilder().action(R.id.action_open_awaiting_card_creation)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun closeNovaCard() {
|
||||
navigationBuilder().action(R.id.action_close_nova_card_from_waiting_dialog)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSendNetworks(payload: NetworkFlowPayload) {
|
||||
navigationBuilder().action(R.id.action_sendFlow_to_sendFlowNetwork)
|
||||
.setArgs(NetworkFlowFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openReceiveNetworks(payload: NetworkFlowPayload) {
|
||||
navigationBuilder().action(R.id.action_receiveFlow_to_receiveFlowNetwork)
|
||||
.setArgs(NetworkFlowFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSwapNetworks(payload: NetworkSwapFlowPayload) {
|
||||
navigationBuilder().action(R.id.action_selectAssetSwapFlowFragment_to_swapFlowNetworkFragment)
|
||||
.setArgs(NetworkSwapFlowFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openBuyNetworks(payload: NetworkFlowPayload) {
|
||||
navigationBuilder().action(R.id.action_buyFlow_to_buyFlowNetwork)
|
||||
.setArgs(NetworkFlowFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSellNetworks(payload: NetworkFlowPayload) {
|
||||
navigationBuilder().action(R.id.action_sellFlow_to_sellFlowNetwork)
|
||||
.setArgs(NetworkFlowFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openGiftsNetworks(payload: NetworkFlowPayload) {
|
||||
navigationBuilder().action(R.id.action_giftsFlow_to_giftsFlowNetwork)
|
||||
.setArgs(NetworkFlowFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openBuyProviders(
|
||||
chainId: String,
|
||||
chainAssetId: Int
|
||||
) {
|
||||
val payload = TradeProviderListPayload(chainId, chainAssetId, TradeProviderFlowType.BUY, OnSuccessfulTradeStrategyType.OPEN_ASSET)
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.buyFlowFragment, R.id.action_buyFlow_to_tradeProvidersFragment)
|
||||
.addCase(R.id.buyFlowNetworkFragment, R.id.action_buyFlowNetworks_to_tradeProvidersFragment)
|
||||
.setFallbackCase(R.id.action_tradeProvidersFragment)
|
||||
.setArgs(TradeProviderListFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSellProviders(
|
||||
chainId: String,
|
||||
chainAssetId: Int
|
||||
) {
|
||||
val payload = TradeProviderListPayload(chainId, chainAssetId, TradeProviderFlowType.SELL, OnSuccessfulTradeStrategyType.OPEN_ASSET)
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.sellFlowFragment, R.id.action_sellFlow_to_tradeProvidersFragment)
|
||||
.addCase(R.id.sellFlowNetworkFragment, R.id.action_sellFlowNetworks_to_tradeProvidersFragment)
|
||||
.setFallbackCase(R.id.action_tradeProvidersFragment)
|
||||
.setArgs(TradeProviderListFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openTradeWebInterface(payload: TradeWebPayload) {
|
||||
navigationBuilder().action(R.id.action_tradeWebFragment)
|
||||
.setArgs(TradeWebFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openChainAddressSelector(chainId: String, accountId: ByteArray) {
|
||||
val payload = ChainAddressSelectorPayload(chainId, accountId)
|
||||
|
||||
navigationBuilder().action(R.id.action_openUnifiedAddressDialog)
|
||||
.setArgs(ChainAddressSelectorFragment.getBundle(payload))
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun closeChainAddressesSelector() {
|
||||
navigationBuilder().action(R.id.action_closeChainAddressesFragment)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openAddGenericEvmAddressSelectLedger(metaId: Long) {
|
||||
val payload = AddEvmAccountSelectGenericLedgerPayload(metaId)
|
||||
|
||||
navigationBuilder().action(R.id.action_accountDetailsFragment_to_addEvmAccountGenericLedgerGraph)
|
||||
.setArgs(AddEvmAccountSelectGenericLedgerFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun returnToMainSwapScreen() {
|
||||
navigationBuilder().action(R.id.action_return_to_swap_settings)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSwapFlow() {
|
||||
val payload = SwapFlowPayload.InitialSelecting
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_swapFlow)
|
||||
.setArgs(AssetSwapFlowFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSwapSetupAmount(swapSettingsPayload: SwapSettingsPayload) {
|
||||
navigationBuilder().action(R.id.action_open_swapSetupAmount)
|
||||
.setArgs(SwapMainSettingsFragment.getBundle(swapSettingsPayload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun returnToMainScreen() {
|
||||
navigationBuilder().action(R.id.action_returnToMainScreen)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun finishSelectAndOpenSwapSetupAmount(swapSettingsPayload: SwapSettingsPayload) {
|
||||
navigationBuilder().action(R.id.action_finish_and_open_swap_settings)
|
||||
.setArgs(SwapMainSettingsFragment.getBundle(swapSettingsPayload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openNfts() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_nfts_nav_graph)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun nonCancellableVerify() {
|
||||
if (currentDestination?.id == R.id.splashFragment) {
|
||||
return
|
||||
}
|
||||
|
||||
val action = PinCodeAction.CheckAfterInactivity(BackDelayedNavigation, ToolbarConfiguration())
|
||||
val bundle = PincodeFragment.getPinCodeBundle(action)
|
||||
|
||||
if (currentDestination?.id == R.id.pincodeFragment) {
|
||||
val arguments = currentBackStackEntry!!.arguments!!.getParcelableCompat<PinCodeAction>(PincodeFragment.KEY_PINCODE_ACTION)
|
||||
if (arguments is PinCodeAction.Change) {
|
||||
navigationBuilder().action(R.id.action_pin_code_access_recovery)
|
||||
.setArgs(bundle)
|
||||
.navigateInRoot()
|
||||
}
|
||||
} else {
|
||||
navigationBuilder().action(R.id.action_pin_code_access_recovery)
|
||||
.setArgs(bundle)
|
||||
.navigateInRoot()
|
||||
}
|
||||
}
|
||||
|
||||
override fun openUpdateNotifications() {
|
||||
navigationBuilder().action(R.id.action_open_update_notifications)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openPushWelcome() {
|
||||
navigationBuilder().action(R.id.action_open_pushNotificationsWelcome)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openCloudBackupSettings() {
|
||||
navigationBuilder().action(R.id.action_open_cloudBackupSettings)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openChainMigrationDetails(chainId: String) {
|
||||
navigationBuilder().action(R.id.action_open_chain_migration_details)
|
||||
.setArgs(ChainMigrationDetailsFragment.createPayload(ChainMigrationDetailsPayload(chainId)))
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun returnToWallet() {
|
||||
// to achieve smooth animation
|
||||
postToUiThread {
|
||||
navigationBuilder().action(R.id.action_return_to_wallet)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
}
|
||||
|
||||
override fun openWalletDetails(metaId: Long) {
|
||||
val extras = WalletDetailsFragment.getBundle(metaId)
|
||||
navigationBuilder().action(R.id.action_open_account_details)
|
||||
.setArgs(extras)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openClaimContribution() {
|
||||
navigationBuilder()
|
||||
.action(R.id.action_userContributionsFragment_to_claimContributionFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openNodeDetails(nodeId: Int) {
|
||||
val extras = NodeDetailsFragment.getBundle(nodeId)
|
||||
navigationBuilder().action(R.id.action_nodesFragment_to_nodeDetailsFragment)
|
||||
.setArgs(extras)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAssetDetails(assetPayload: AssetPayload) {
|
||||
val bundle = BalanceDetailFragment.getBundle(assetPayload)
|
||||
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.mainFragment, R.id.action_mainFragment_to_balanceDetailFragment)
|
||||
.addCase(R.id.assetSearchFragment, R.id.action_assetSearchFragment_to_balanceDetailFragment)
|
||||
.addCase(R.id.confirmTransferFragment, R.id.action_confirmTransferFragment_to_balanceDetailFragment)
|
||||
.addCase(R.id.tradeWebFragment, R.id.action_tradeWebFragment_to_balanceDetailFragment)
|
||||
.addCase(R.id.balanceDetailFragment, R.id.action_balanceDetailFragment_to_balanceDetailFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAssetDetailsFromDeepLink(payload: AssetPayload) {
|
||||
openSplitScreenWithInstantAction(R.id.action_mainFragment_to_balanceDetailFragment, BalanceDetailFragment.getBundle(payload))
|
||||
}
|
||||
|
||||
override fun openGifts() {
|
||||
navigationBuilder().action(R.id.action_open_gifts)
|
||||
.setArgs(GiftsFragment.createPayload(GiftsPayload.AllAssets))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openGiftsByAsset(assetPayload: AssetPayload) {
|
||||
navigationBuilder().action(R.id.action_open_gifts)
|
||||
.setArgs(GiftsFragment.createPayload(GiftsPayload.ByAsset(assetPayload)))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun finishTradeOperation() {
|
||||
navigationBuilder().action(R.id.action_finishTradeOperation)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAddNode() {
|
||||
navigationBuilder().action(R.id.action_nodesFragment_to_addNodeFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openChangeWatchAccount(payload: AddAccountPayload.ChainAccount) {
|
||||
val bundle = ChangeWatchAccountFragment.getBundle(payload)
|
||||
|
||||
navigationBuilder().action(R.id.action_accountDetailsFragment_to_changeWatchAccountFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openCreateWallet(payload: StartCreateWalletPayload) {
|
||||
navigationBuilder().action(R.id.action_open_create_new_wallet)
|
||||
.setArgs(StartCreateWalletFragment.bundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openUserContributions() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_userContributionsGraph)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun getExportMnemonicDelayedNavigation(exportPayload: ExportPayload.ChainAccount): DelayedNavigation {
|
||||
val payload = BackupMnemonicPayload.Confirm(exportPayload.chainId, exportPayload.metaId)
|
||||
val extras = BackupMnemonicFragment.getBundle(payload)
|
||||
|
||||
return NavComponentDelayedNavigation(R.id.action_open_mnemonic_nav_graph, extras)
|
||||
}
|
||||
|
||||
override fun getExportSeedDelayedNavigation(exportPayload: ExportPayload.ChainAccount): DelayedNavigation {
|
||||
val extras = ExportSeedFragment.getBundle(exportPayload)
|
||||
|
||||
return NavComponentDelayedNavigation(R.id.action_export_seed, extras)
|
||||
}
|
||||
|
||||
override fun getExportJsonDelayedNavigation(exportPayload: ExportPayload): DelayedNavigation {
|
||||
val extras = ExportJsonFragment.getBundle(exportPayload)
|
||||
|
||||
return NavComponentDelayedNavigation(R.id.action_export_json, extras)
|
||||
}
|
||||
|
||||
override fun exportJsonAction(exportPayload: ExportPayload) {
|
||||
val extras = ExportJsonFragment.getBundle(exportPayload)
|
||||
|
||||
navigationBuilder().action(R.id.action_export_json)
|
||||
.setArgs(extras)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun finishExportFlow() {
|
||||
navigationBuilder().action(R.id.finish_export_flow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openScanImportParitySigner(payload: ParitySignerStartPayload) {
|
||||
val args = ScanImportParitySignerFragment.getBundle(payload)
|
||||
|
||||
navigationBuilder().action(R.id.action_startImportParitySignerFragment_to_scanImportParitySignerFragment)
|
||||
.setArgs(args)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openPreviewImportParitySigner(payload: ParitySignerAccountPayload) {
|
||||
val bundle = PreviewImportParitySignerFragment.getBundle(payload)
|
||||
|
||||
navigationBuilder().action(R.id.action_scanImportParitySignerFragment_to_previewImportParitySignerFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openFinishImportParitySigner(payload: ParitySignerAccountPayload) {
|
||||
val bundle = FinishImportParitySignerFragment.getBundle(payload)
|
||||
|
||||
navigationBuilder().action(R.id.action_previewImportParitySignerFragment_to_finishImportParitySignerFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openScanParitySignerSignature(payload: ScanSignParitySignerPayload) {
|
||||
val bundle = ScanSignParitySignerFragment.getBundle(payload)
|
||||
|
||||
navigationBuilder().action(R.id.action_showSignParitySignerFragment_to_scanSignParitySignerFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun finishParitySignerFlow() {
|
||||
navigationBuilder().action(R.id.action_finish_parity_signer_flow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAddLedgerChainAccountFlow(addAccountPayload: AddAccountPayload.ChainAccount) {
|
||||
val payload = AddChainAccountSelectLedgerPayload(addAccountPayload, SelectLedgerPayload.ConnectionMode.ALL)
|
||||
val bundle = AddChainAccountSelectLedgerFragment.getBundle(payload)
|
||||
|
||||
navigationBuilder().action(R.id.action_accountDetailsFragment_to_addLedgerAccountGraph)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openCreateCloudBackupPassword(walletName: String) {
|
||||
val bundle = CreateWalletBackupPasswordFragment.getBundle(CreateBackupPasswordPayload(walletName))
|
||||
|
||||
navigationBuilder().action(R.id.action_startCreateWalletFragment_to_createCloudBackupPasswordFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun restoreCloudBackup() {
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.importWalletOptionsFragment, R.id.action_importWalletOptionsFragment_to_restoreCloudBackup)
|
||||
.addCase(R.id.startCreateWalletFragment, R.id.action_startCreateWalletFragment_to_resotreCloudBackupFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSyncWalletsBackupPassword() {
|
||||
navigationBuilder().action(R.id.action_cloudBackupSettings_to_syncWalletsBackupPasswordFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openChangeBackupPasswordFlow() {
|
||||
navigationBuilder().action(R.id.action_cloudBackupSettings_to_checkCloudBackupPasswordFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openRestoreBackupPassword() {
|
||||
navigationBuilder().action(R.id.action_cloudBackupSettings_to_restoreCloudBackupPasswordFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openChangeBackupPassword() {
|
||||
navigationBuilder().action(R.id.action_checkCloudBackupPasswordFragment_to_changeBackupPasswordFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openManualBackupSelectAccount(metaId: Long) {
|
||||
val bundle = ManualBackupSelectAccountFragment.bundle(ManualBackupSelectAccountPayload(metaId))
|
||||
|
||||
navigationBuilder().action(R.id.action_manualBackupSelectWalletFragment_to_manualBackupSelectAccountFragment)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openManualBackupConditions(payload: ManualBackupCommonPayload) {
|
||||
val bundle = ManualBackupWarningFragment.bundle(payload)
|
||||
|
||||
val pinCodePayload = PinCodeAction.Check(
|
||||
NavComponentDelayedNavigation(R.id.action_manualBackupPincodeFragment_to_manualBackupWarning, bundle),
|
||||
ToolbarConfiguration()
|
||||
)
|
||||
val pinCodeBundle = PincodeFragment.getPinCodeBundle(pinCodePayload)
|
||||
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.manualBackupSelectWallet, R.id.action_manualBackupSelectWallet_to_pincode_check)
|
||||
.addCase(R.id.manualBackupSelectAccount, R.id.action_manualBackupSelectAccount_to_pincode_check)
|
||||
.setArgs(pinCodeBundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openManualBackupSecrets(payload: ManualBackupCommonPayload) {
|
||||
val bundle = ManualBackupSecretsFragment.bundle(payload)
|
||||
navigationBuilder().action(R.id.action_manualBackupWarning_to_manualBackupSecrets)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openManualBackupAdvancedSecrets(payload: ManualBackupCommonPayload) {
|
||||
val bundle = ManualBackupAdvancedSecretsFragment.bundle(payload)
|
||||
navigationBuilder().action(R.id.action_manualBackupSecrets_to_manualBackupAdvancedSecrets)
|
||||
.setArgs(bundle)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openCreateWatchWallet() {
|
||||
navigationBuilder().action(R.id.action_importWalletOptionsFragment_to_createWatchWalletFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openStartImportParitySigner() {
|
||||
openStartImportPolkadotVault(PolkadotVaultVariant.PARITY_SIGNER)
|
||||
}
|
||||
|
||||
override fun openStartImportPolkadotVault() {
|
||||
openStartImportPolkadotVault(PolkadotVaultVariant.POLKADOT_VAULT)
|
||||
}
|
||||
|
||||
override fun openImportOptionsScreen() {
|
||||
navigationBuilder().cases()
|
||||
.addCase(R.id.welcomeFragment, R.id.action_welcomeFragment_to_importWalletOptionsFragment)
|
||||
.setFallbackCase(R.id.action_importWalletOptionsFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openStartImportLegacyLedger() {
|
||||
navigationBuilder().action(R.id.action_importWalletOptionsFragment_to_import_legacy_ledger_graph)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openStartImportGenericLedger() {
|
||||
navigationBuilder().action(R.id.action_importWalletOptionsFragment_to_import_generic_ledger_graph)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun withPinCodeCheckRequired(
|
||||
delayedNavigation: DelayedNavigation,
|
||||
createMode: Boolean,
|
||||
pinCodeTitleRes: Int?,
|
||||
) {
|
||||
val action = if (createMode) {
|
||||
PinCodeAction.Create(delayedNavigation)
|
||||
} else {
|
||||
PinCodeAction.Check(delayedNavigation, ToolbarConfiguration(pinCodeTitleRes, true))
|
||||
}
|
||||
|
||||
navigationBuilder().action(R.id.open_pincode_check)
|
||||
.setArgs(PincodeFragment.getPinCodeBundle(action))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
private fun openStartImportPolkadotVault(variant: PolkadotVaultVariant) {
|
||||
val args = StartImportParitySignerFragment.getBundle(ParitySignerStartPayload(variant))
|
||||
|
||||
navigationBuilder().action(R.id.action_importWalletOptionsFragment_to_import_parity_signer_graph)
|
||||
.setArgs(args)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
private fun buildCreatePinBundle(): Bundle {
|
||||
val delayedNavigation = NavComponentDelayedNavigation(R.id.action_open_split_screen)
|
||||
val action = PinCodeAction.Create(delayedNavigation)
|
||||
return PincodeFragment.getPinCodeBundle(action)
|
||||
}
|
||||
|
||||
override fun runDelayedNavigation(delayedNavigation: DelayedNavigation) {
|
||||
when (delayedNavigation) {
|
||||
BackDelayedNavigation -> back()
|
||||
is NavComponentDelayedNavigation -> {
|
||||
navigationBuilder().action(delayedNavigation.globalActionId)
|
||||
.setArgs(delayedNavigation.extras)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun finishTopUp() {
|
||||
navigationBuilder().action(R.id.action_finishTopUpFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openPendingMultisigOperations() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_multisigPendingOperationsFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openMainWithFinishMultisigTransaction(accountWasSwitched: Boolean) {
|
||||
val payload = MultisigCreatedBottomSheet.createPayload(MultisigCreatedPayload(accountWasSwitched))
|
||||
openSplitScreenWithInstantAction(R.id.action_open_multisigCreatedDialog, nestedActionExtras = payload)
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.account
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.getBackStackEntryBefore
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_api.domain.model.PolkadotVaultVariant
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.sign.SignInterScreenCommunicator.Request
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.sign.SignInterScreenCommunicator.Response
|
||||
import io.novafoundation.nova.feature_account_impl.data.signer.paritySigner.PolkadotVaultVariantSignCommunicator
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.sign.show.ShowSignParitySignerFragment
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.paritySigner.sign.show.ShowSignParitySignerPayload
|
||||
|
||||
class PolkadotVaultVariantSignCommunicatorImpl(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : NavStackInterScreenCommunicator<Request, Response>(navigationHoldersRegistry), PolkadotVaultVariantSignCommunicator {
|
||||
|
||||
private var usedPolkadotVaultVariant: PolkadotVaultVariant? = null
|
||||
|
||||
override fun respond(response: Response) {
|
||||
val requester = navController.getBackStackEntryBefore(R.id.showSignParitySignerFragment)
|
||||
|
||||
saveResultTo(requester, response)
|
||||
}
|
||||
|
||||
override fun setUsedVariant(variant: PolkadotVaultVariant) {
|
||||
usedPolkadotVaultVariant = variant
|
||||
}
|
||||
|
||||
override fun openRequest(request: Request) {
|
||||
super.openRequest(request)
|
||||
|
||||
val payload = ShowSignParitySignerPayload(request, requireNotNull(usedPolkadotVaultVariant))
|
||||
val bundle = ShowSignParitySignerFragment.getBundle(payload)
|
||||
navController.navigate(R.id.action_open_sign_parity_signer, bundle)
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.account
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.navigationBuilder
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.seedScan.ScanSeedCommunicator
|
||||
|
||||
class ScanSeedCommunicatorImpl(
|
||||
private val navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : NavStackInterScreenCommunicator<ScanSeedCommunicator.Request, ScanSeedCommunicator.Response>(navigationHoldersRegistry),
|
||||
ScanSeedCommunicator {
|
||||
|
||||
override fun openRequest(request: ScanSeedCommunicator.Request) {
|
||||
super.openRequest(request)
|
||||
|
||||
navigationHoldersRegistry.navigationBuilder().action(R.id.action_scan_seed)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.account
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectAddress.SelectAddressCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectAddress.SelectAddressRequester
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectAddress.SelectAddressResponder
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.account.list.selectAddress.SelectAddressBottomSheet
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
|
||||
class SelectAddressCommunicatorImpl(private val router: AssetsRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
|
||||
NavStackInterScreenCommunicator<SelectAddressRequester.Request, SelectAddressResponder.Response>(navigationHoldersRegistry),
|
||||
SelectAddressCommunicator {
|
||||
|
||||
override fun openRequest(request: SelectAddressRequester.Request) {
|
||||
super.openRequest(request)
|
||||
|
||||
router.openSelectAddress(SelectAddressBottomSheet.getBundle(request))
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.account
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectMultipleWalletsCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectMultipleWalletsRequester
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectMultipleWalletsResponder
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.account.list.multipleSelecting.SelectMultipleWalletsFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
|
||||
class SelectMultipleWalletsCommunicatorImpl(private val router: AssetsRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
|
||||
NavStackInterScreenCommunicator<SelectMultipleWalletsRequester.Request, SelectMultipleWalletsResponder.Response>(navigationHoldersRegistry),
|
||||
SelectMultipleWalletsCommunicator {
|
||||
|
||||
override fun openRequest(request: SelectMultipleWalletsRequester.Request) {
|
||||
super.openRequest(request)
|
||||
|
||||
router.openSelectMultipleWallets(SelectMultipleWalletsFragment.getBundle(request))
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.account
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.FlowInterScreenCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectSingleWallet.SelectSingleWalletCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectSingleWallet.SelectSingleWalletRequester
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectSingleWallet.SelectSingleWalletResponder
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.account.list.singleSelecting.SelectSingleWalletFragment
|
||||
import io.novafoundation.nova.feature_assets.presentation.AssetsRouter
|
||||
|
||||
class SelectSingleWalletCommunicatorImpl(private val router: AssetsRouter) :
|
||||
FlowInterScreenCommunicator<SelectSingleWalletRequester.Request, SelectSingleWalletResponder.Response>(),
|
||||
SelectSingleWalletCommunicator {
|
||||
|
||||
override fun dispatchRequest(request: SelectSingleWalletRequester.Request) {
|
||||
router.openSelectSingleWallet(SelectSingleWalletFragment.createPayload(request))
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.account
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectWallet.SelectWalletCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectWallet.SelectWalletCommunicator.Payload
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.mixin.selectWallet.SelectWalletCommunicator.Response
|
||||
|
||||
class SelectWalletCommunicatorImpl(
|
||||
private val navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : NavStackInterScreenCommunicator<Payload, Response>(navigationHoldersRegistry), SelectWalletCommunicator {
|
||||
|
||||
override fun openRequest(request: Payload) {
|
||||
super.openRequest(request)
|
||||
|
||||
navController.navigate(R.id.action_open_select_wallet)
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.accountmigration
|
||||
|
||||
import android.os.Bundle
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.delayedNavigation.NavComponentDelayedNavigation
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.pincode.PinCodeAction
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.pincode.PincodeFragment
|
||||
import io.novafoundation.nova.feature_account_migration.presentation.AccountMigrationRouter
|
||||
import io.novafoundation.nova.feature_account_migration.presentation.pairing.AccountMigrationPairingFragment
|
||||
import io.novafoundation.nova.feature_account_migration.presentation.pairing.AccountMigrationPairingPayload
|
||||
|
||||
class AccountMigrationNavigator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : BaseNavigator(navigationHoldersRegistry), AccountMigrationRouter {
|
||||
|
||||
override fun openAccountMigrationPairing(scheme: String) {
|
||||
val payload = AccountMigrationPairingPayload(scheme)
|
||||
navigationBuilder().action(R.id.action_open_accountMigrationPairing)
|
||||
.setArgs(AccountMigrationPairingFragment.Companion.createPayload(payload))
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun finishMigrationFlow() {
|
||||
navigationBuilder().action(R.id.action_open_split_screen)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openPinCodeSet() {
|
||||
val args = buildCreatePinBundle()
|
||||
|
||||
navigationBuilder().action(R.id.action_migration_to_pin)
|
||||
.setArgs(args)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
private fun buildCreatePinBundle(): Bundle {
|
||||
val delayedNavigation = NavComponentDelayedNavigation(R.id.action_open_split_screen)
|
||||
val action = PinCodeAction.Create(delayedNavigation)
|
||||
return PincodeFragment.getPinCodeBundle(action)
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.builder
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.holders.NavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
|
||||
class ActionNavigationBuilder(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
private val actionId: Int
|
||||
) : NavigationBuilder(navigationHoldersRegistry) {
|
||||
|
||||
override fun performInternal(navigationHolder: NavigationHolder) {
|
||||
performAction(navigationHolder, actionId)
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.builder
|
||||
|
||||
import androidx.navigation.NavDestination
|
||||
import io.novafoundation.nova.app.root.navigation.holders.NavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
|
||||
class CasesNavigationBuilder(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : NavigationBuilder(navigationHoldersRegistry) {
|
||||
|
||||
private class Case(val destination: Int, val actionId: Int)
|
||||
|
||||
private var cases = mutableListOf<Case>()
|
||||
|
||||
private var fallbackCaseActionId: Int? = null
|
||||
|
||||
fun addCase(currentDestination: Int, actionId: Int): CasesNavigationBuilder {
|
||||
cases.add(Case(currentDestination, actionId))
|
||||
return this
|
||||
}
|
||||
|
||||
fun setFallbackCase(actionId: Int): CasesNavigationBuilder {
|
||||
fallbackCaseActionId = actionId
|
||||
return this
|
||||
}
|
||||
|
||||
override fun performInternal(navigationHolder: NavigationHolder) {
|
||||
val navController = navigationHolder.navController ?: return
|
||||
val currentDestination = navController.currentDestination ?: return
|
||||
|
||||
val caseActionId = cases.find { case -> case.destination == currentDestination.id }
|
||||
?.actionId
|
||||
?: fallbackCaseActionId
|
||||
?: throw IllegalArgumentException("Unknown case for ${currentDestination.label}")
|
||||
|
||||
performAction(navigationHolder, caseActionId)
|
||||
}
|
||||
|
||||
private fun NavDestination.hasAction(actionId: Int): Boolean {
|
||||
return this.getAction(actionId) != null
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.builder
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.fragment.FragmentNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.holders.NavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
|
||||
/**
|
||||
* Class for building navigation.
|
||||
* Currently, it has 2 navigators: split_screen and root
|
||||
* - root-navigator - a navigator that opens fragments on top of others and is designed for fragments that do not require a split screen (For example, DAppBrowser needs to be opened in the root navigator)
|
||||
* - split_screen-navigator - the main navigator of the application. All fragments opened in it will be opened in a split screen mode
|
||||
*
|
||||
* Let's look at the scenarios for building navigation:
|
||||
* - In the normal case, you need to add a navigation node only to the split_screen_nav_graph, be it a dialog or a fragment.
|
||||
* This can be used when you are sure that the fragment or dialog should not be launched in the browser or on top of a split screen.
|
||||
* Use [navigateInFirstAttachedContext] and the fragment will be automatically attached to the SplitScreenNavigationHolder.
|
||||
* - If you expect that the fragment can also be launched from the browser, you need to add it to both the root_navigation_graph and the split_screen_navigation_graph.
|
||||
* Keep in mind that the actionId must be the same in both graphs.
|
||||
* Use [navigateInFirstAttachedContext] and the fragment will be automatically attached to the desired holder.
|
||||
* - In case of adding dialogs, you can add it only to the root_navigation_graph if you think that the dialog can be launched both from the browser and from the remote part of the application.
|
||||
* To attach the dialog to the RootNavigationHolder, call [navigateInRoot]
|
||||
* - In the latter case, we may need to add a screen that is strictly required to be opened on top of the split screen or only in the browser flow. (Such screens as entering a pin code).
|
||||
* In this case, we need to add an action only to the root_navigation_graph
|
||||
* To attach the fragment to the RootNavigationHolder, call [navigateInRoot]
|
||||
**/
|
||||
abstract class NavigationBuilder(
|
||||
private val navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) {
|
||||
|
||||
protected var navOptions: NavOptions? = null
|
||||
protected var args: Bundle? = null
|
||||
protected var extras: FragmentNavigator.Extras? = null
|
||||
|
||||
fun setArgs(args: Bundle?): NavigationBuilder {
|
||||
this.args = args
|
||||
return this
|
||||
}
|
||||
|
||||
fun setNavOptions(navOptions: NavOptions): NavigationBuilder {
|
||||
this.navOptions = navOptions
|
||||
return this
|
||||
}
|
||||
|
||||
fun setExtras(extras: FragmentNavigator.Extras?): NavigationBuilder {
|
||||
this.extras = extras
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a fragment in the first attached navigation holder (split_screen or root).
|
||||
* If it is assumed that the fragment can be opened both in root and in split_screen, then it is necessary to add a navigation node both to split_screen_navigation_graph and to root_navigation_graph
|
||||
*/
|
||||
fun navigateInFirstAttachedContext() {
|
||||
performInternal(navigationHoldersRegistry.firstAttachedHolder)
|
||||
}
|
||||
|
||||
/**
|
||||
* Always open fragment in root navigation holder.
|
||||
* In this case, the node must be added to root_navigation_graph
|
||||
**/
|
||||
fun navigateInRoot() {
|
||||
performInternal(navigationHoldersRegistry.rootNavigationHolder)
|
||||
}
|
||||
|
||||
protected fun NavigationBuilder.performAction(navigationHolder: NavigationHolder, actionId: Int) {
|
||||
val navController = navigationHolder.navController ?: return
|
||||
val currentDestination = navController.currentDestination ?: return
|
||||
|
||||
if (currentDestination.hasAction(actionId)) {
|
||||
navigationHolder.navController?.navigate(actionId, args, navOptions, extras)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun performInternal(navigationHolder: NavigationHolder)
|
||||
}
|
||||
|
||||
private fun NavDestination.hasAction(actionId: Int): Boolean {
|
||||
return this.getAction(actionId) != null
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.builder
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
|
||||
class NavigationBuilderRegistry(private val registry: NavigationHoldersRegistry) {
|
||||
|
||||
fun action(actionId: Int) = ActionNavigationBuilder(registry, actionId)
|
||||
|
||||
fun cases() = CasesNavigationBuilder(registry)
|
||||
|
||||
fun graph(graphId: Int) = OpenGraphNavigationBuilder(registry, graphId)
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.builder
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.holders.NavigationHolder
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
|
||||
class OpenGraphNavigationBuilder(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
private val graphId: Int
|
||||
) : NavigationBuilder(navigationHoldersRegistry) {
|
||||
|
||||
override fun performInternal(navigationHolder: NavigationHolder) {
|
||||
navigationHolder.navController?.navigate(graphId, args, navOptions, extras)
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.buy
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_buy_impl.presentation.BuyRouter
|
||||
|
||||
class BuyNavigator(navigationHoldersRegistry: NavigationHoldersRegistry) : BuyRouter,
|
||||
BaseNavigator(navigationHoldersRegistry)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.chainMigration
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_ahm_impl.presentation.ChainMigrationRouter
|
||||
import io.novafoundation.nova.feature_ahm_impl.presentation.migrationDetails.ChainMigrationDetailsFragment
|
||||
import io.novafoundation.nova.feature_ahm_impl.presentation.migrationDetails.ChainMigrationDetailsPayload
|
||||
|
||||
class ChainMigrationNavigator(navigationHoldersRegistry: NavigationHoldersRegistry) : ChainMigrationRouter, BaseNavigator(navigationHoldersRegistry) {
|
||||
|
||||
override fun openChainMigrationDetails(chainId: String) {
|
||||
navigationBuilder().action(R.id.action_open_chain_migration_details)
|
||||
.setArgs(ChainMigrationDetailsFragment.createPayload(ChainMigrationDetailsPayload(chainId)))
|
||||
.navigateInRoot()
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.cloudBackup
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.ChangeBackupPasswordCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.ChangeBackupPasswordRequester
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.ChangeBackupPasswordResponder
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
|
||||
class ChangeBackupPasswordCommunicatorImpl(private val router: AccountRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
|
||||
NavStackInterScreenCommunicator<ChangeBackupPasswordRequester.EmptyRequest, ChangeBackupPasswordResponder.Success>(navigationHoldersRegistry),
|
||||
ChangeBackupPasswordCommunicator {
|
||||
|
||||
override fun openRequest(request: ChangeBackupPasswordRequester.EmptyRequest) {
|
||||
super.openRequest(request)
|
||||
|
||||
router.openChangeBackupPasswordFlow()
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.cloudBackup
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_cloud_backup_impl.presentation.CloudBackupRouter
|
||||
|
||||
class CloudBackupNavigator(navigationHoldersRegistry: NavigationHoldersRegistry) : CloudBackupRouter,
|
||||
BaseNavigator(navigationHoldersRegistry)
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.cloudBackup
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.RestoreBackupPasswordCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.RestoreBackupPasswordRequester
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.changePassword.RestoreBackupPasswordResponder
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
|
||||
class RestoreBackupPasswordCommunicatorImpl(private val router: AccountRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
|
||||
NavStackInterScreenCommunicator<RestoreBackupPasswordRequester.EmptyRequest, RestoreBackupPasswordResponder.Success>(navigationHoldersRegistry),
|
||||
RestoreBackupPasswordCommunicator {
|
||||
|
||||
override fun openRequest(request: RestoreBackupPasswordRequester.EmptyRequest) {
|
||||
super.openRequest(request)
|
||||
|
||||
router.openRestoreBackupPassword()
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.cloudBackup
|
||||
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_account_impl.presentation.AccountRouter
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.createPassword.SyncWalletsBackupPasswordCommunicator
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.createPassword.SyncWalletsBackupPasswordRequester
|
||||
import io.novafoundation.nova.feature_account_api.presenatation.cloudBackup.createPassword.SyncWalletsBackupPasswordResponder
|
||||
|
||||
class SyncWalletsBackupPasswordCommunicatorImpl(private val router: AccountRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
|
||||
NavStackInterScreenCommunicator<SyncWalletsBackupPasswordRequester.EmptyRequest, SyncWalletsBackupPasswordResponder.Response>(navigationHoldersRegistry),
|
||||
SyncWalletsBackupPasswordCommunicator {
|
||||
|
||||
override fun openRequest(request: SyncWalletsBackupPasswordRequester.EmptyRequest) {
|
||||
super.openRequest(request)
|
||||
|
||||
router.openSyncWalletsBackupPassword()
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.dApp
|
||||
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.fragment.FragmentNavigator
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.builder.NavigationBuilder
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.addToFavourites.AddToFavouritesFragment
|
||||
import io.novafoundation.nova.feature_dapp_api.presentation.addToFavorites.AddToFavouritesPayload
|
||||
import io.novafoundation.nova.feature_dapp_api.presentation.browser.main.DAppBrowserPayload
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.browser.main.DAppBrowserFragment
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.search.DappSearchFragment
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.search.SearchPayload
|
||||
|
||||
class DAppNavigator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
) : BaseNavigator(navigationHoldersRegistry), DAppRouter {
|
||||
|
||||
override fun openChangeAccount() {
|
||||
navigationBuilder().action(R.id.action_open_switch_wallet)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openDAppBrowser(payload: DAppBrowserPayload, extras: FragmentNavigator.Extras?) {
|
||||
// Close dapp browser if it is already opened
|
||||
// TODO it's better to provide new url to existing browser
|
||||
navigationBuilder().graph(R.id.dapp_browser_graph)
|
||||
.setDappAnimations()
|
||||
.setExtras(extras)
|
||||
.setArgs(DAppBrowserFragment.getBundle(payload))
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openDappSearch() {
|
||||
openDappSearchWithCategory(categoryId = null)
|
||||
}
|
||||
|
||||
override fun openDappSearchWithCategory(categoryId: String?) {
|
||||
navigationBuilder().graph(R.id.dapp_search_graph)
|
||||
.setDappAnimations()
|
||||
.setArgs(DappSearchFragment.getBundle(SearchPayload(initialUrl = null, SearchPayload.Request.OPEN_NEW_URL, preselectedCategoryId = categoryId)))
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun finishDappSearch() {
|
||||
navigationBuilder().action(R.id.action_finish_dapp_search)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openAddToFavourites(payload: AddToFavouritesPayload) {
|
||||
navigationBuilder().action(R.id.action_DAppBrowserFragment_to_addToFavouritesFragment)
|
||||
.setArgs(AddToFavouritesFragment.getBundle(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openAuthorizedDApps() {
|
||||
navigationBuilder().action(R.id.action_mainFragment_to_authorizedDAppsFragment)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openTabs() {
|
||||
navigationBuilder().graph(R.id.dapp_tabs_graph)
|
||||
.setDappAnimations()
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun closeTabsScreen() {
|
||||
navigationBuilder().action(R.id.action_finish_tabs_fragment)
|
||||
.navigateInRoot()
|
||||
}
|
||||
|
||||
override fun openDAppFavorites() {
|
||||
navigationBuilder().action(R.id.action_open_dapp_favorites)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
private fun NavigationBuilder.setDappAnimations(): NavigationBuilder {
|
||||
val currentDestinationId = currentDestination?.id
|
||||
|
||||
// For this currentDestinations we will use default animation. And for other - slide_in, slide_out
|
||||
val dappDestinations = listOf(
|
||||
R.id.dappSearchFragment,
|
||||
R.id.dappBrowserFragment,
|
||||
R.id.dappTabsFragment
|
||||
)
|
||||
|
||||
val navOptionsBuilder = if (currentDestinationId in dappDestinations) {
|
||||
// Only slide out animation
|
||||
NavOptions.Builder()
|
||||
.setEnterAnim(R.anim.fragment_open_enter)
|
||||
.setExitAnim(R.anim.fragment_open_exit)
|
||||
.setPopEnterAnim(R.anim.fragment_close_enter)
|
||||
.setPopExitAnim(R.anim.fragment_slide_out)
|
||||
.setPopUpTo(R.id.splitScreenFragment, false)
|
||||
} else {
|
||||
// Slide in/out animations
|
||||
NavOptions.Builder()
|
||||
.setEnterAnim(R.anim.fragment_slide_in)
|
||||
.setExitAnim(R.anim.fragment_open_exit)
|
||||
.setPopEnterAnim(R.anim.fragment_close_enter)
|
||||
.setPopExitAnim(R.anim.fragment_slide_out)
|
||||
.setPopUpTo(R.id.splitScreenFragment, false)
|
||||
}
|
||||
|
||||
return setNavOptions(navOptionsBuilder.build())
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.dApp
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.search.DAppSearchCommunicator
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.search.DAppSearchCommunicator.Response
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.search.DappSearchFragment
|
||||
import io.novafoundation.nova.feature_dapp_impl.presentation.search.SearchPayload
|
||||
|
||||
class DAppSearchCommunicatorImpl(navigationHoldersRegistry: NavigationHoldersRegistry) :
|
||||
NavStackInterScreenCommunicator<SearchPayload, Response>(navigationHoldersRegistry),
|
||||
DAppSearchCommunicator {
|
||||
|
||||
override fun openRequest(request: SearchPayload) {
|
||||
super.openRequest(request)
|
||||
|
||||
navigationBuilder().action(R.id.action_open_dappSearch_from_browser)
|
||||
.setArgs(DappSearchFragment.getBundle(request))
|
||||
.navigateInRoot()
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.externalSign
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.FlowInterScreenCommunicator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.navigationBuilder
|
||||
import io.novafoundation.nova.common.utils.sequrity.AutomaticInteractionGate
|
||||
import io.novafoundation.nova.common.utils.sequrity.awaitInteractionAllowed
|
||||
import io.novafoundation.nova.feature_external_sign_api.model.ExternalSignCommunicator
|
||||
import io.novafoundation.nova.feature_external_sign_api.model.signPayload.ExternalSignPayload
|
||||
import io.novafoundation.nova.feature_external_sign_impl.presentation.signExtrinsic.ExternalSignFragment
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ExternalSignCommunicatorImpl(
|
||||
private val navigationHoldersRegistry: NavigationHoldersRegistry,
|
||||
private val automaticInteractionGate: AutomaticInteractionGate,
|
||||
) : CoroutineScope by CoroutineScope(Dispatchers.Main),
|
||||
FlowInterScreenCommunicator<ExternalSignPayload, ExternalSignCommunicator.Response>(),
|
||||
ExternalSignCommunicator {
|
||||
|
||||
override fun dispatchRequest(request: ExternalSignPayload) {
|
||||
launch {
|
||||
automaticInteractionGate.awaitInteractionAllowed()
|
||||
|
||||
navigationHoldersRegistry.navigationBuilder().action(R.id.action_open_externalSignGraph)
|
||||
.setArgs(ExternalSignFragment.getBundle(request))
|
||||
.navigateInRoot()
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.externalSign
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.feature_external_sign_impl.ExternalSignRouter
|
||||
import io.novafoundation.nova.feature_external_sign_impl.presentation.extrinsicDetails.ExternalExtrinsicDetailsFragment
|
||||
|
||||
class ExternalSignNavigator(
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : BaseNavigator(navigationHoldersRegistry), ExternalSignRouter {
|
||||
|
||||
override fun openExtrinsicDetails(extrinsicContent: String) {
|
||||
navigationBuilder().action(R.id.action_ConfirmSignExtrinsicFragment_to_extrinsicDetailsFragment)
|
||||
.setArgs(ExternalExtrinsicDetailsFragment.getBundle(extrinsicContent))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package io.novafoundation.nova.app.root.navigation.navigators.gift
|
||||
|
||||
import io.novafoundation.nova.app.R
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
|
||||
import io.novafoundation.nova.app.root.navigation.navigators.Navigator
|
||||
import io.novafoundation.nova.feature_gift_impl.domain.GiftId
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.GiftRouter
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.claim.ClaimGiftFragment
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.claim.ClaimGiftPayload
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.confirm.CreateGiftConfirmFragment
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.confirm.CreateGiftConfirmPayload
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.share.ShareGiftFragment
|
||||
import io.novafoundation.nova.feature_gift_impl.presentation.share.ShareGiftPayload
|
||||
import io.novafoundation.nova.feature_wallet_api.presentation.model.AssetPayload
|
||||
|
||||
class GiftNavigator(
|
||||
private val commonDelegate: Navigator,
|
||||
navigationHoldersRegistry: NavigationHoldersRegistry
|
||||
) : GiftRouter, BaseNavigator(navigationHoldersRegistry) {
|
||||
|
||||
override fun finishCreateGift() {
|
||||
navigationBuilder().action(R.id.action_finishCreateGift)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openGiftsFlow() {
|
||||
navigationBuilder().action(R.id.action_giftsFragment_to_giftsFlow)
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openSelectGiftAmount(assetPayload: AssetPayload) {
|
||||
commonDelegate.openSelectGiftAmount(assetPayload)
|
||||
}
|
||||
|
||||
override fun openConfirmCreateGift(payload: CreateGiftConfirmPayload) {
|
||||
navigationBuilder().action(R.id.action_openConfirmCreateGift)
|
||||
.setArgs(CreateGiftConfirmFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openGiftSharing(giftId: GiftId, isSecondOpen: Boolean) {
|
||||
navigationBuilder().action(R.id.action_openShareGiftFragment)
|
||||
.setArgs(ShareGiftFragment.createPayload(ShareGiftPayload(giftId, isSecondOpen)))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openMainScreen() {
|
||||
commonDelegate.openMain()
|
||||
}
|
||||
|
||||
override fun openClaimGift(payload: ClaimGiftPayload) {
|
||||
navigationBuilder().action(R.id.action_openClaimGiftFragment)
|
||||
.setArgs(ClaimGiftFragment.createPayload(payload))
|
||||
.navigateInFirstAttachedContext()
|
||||
}
|
||||
|
||||
override fun openManageWallets() {
|
||||
commonDelegate.openWallets()
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user