Initial commit: Pezkuwi Wallet Android

Security hardened release:
- Code obfuscation enabled (minifyEnabled=true, shrinkResources=true)
- Sensitive files excluded (google-services.json, keystores)
- Branch.io key moved to BuildConfig placeholder
- Updated dependencies: OkHttp 4.12.0, Gson 2.10.1, BouncyCastle 1.77
- Comprehensive ProGuard rules for crypto wallet
- Navigation 2.7.7, Lifecycle 2.7.0, ConstraintLayout 2.1.4
This commit is contained in:
2026-02-12 05:19:41 +03:00
commit a294aa1a6b
7687 changed files with 441811 additions and 0 deletions
+234
View File
@@ -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="${BRANCH_KEY}" />
<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)
}
}
@@ -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
)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
}
@@ -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)
}
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
@@ -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)
}
}
@@ -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)
}
}
@@ -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)
}
}
@@ -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)
}
}
@@ -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()
}
}
@@ -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
)
}
}
@@ -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()
}
@@ -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)
}
}
}
@@ -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()
}
}
@@ -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
@@ -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
@@ -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()
}
}
}
@@ -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)
@@ -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)
@@ -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
}
@@ -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)
}
}
@@ -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
}
@@ -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();
}
}
}
@@ -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()
}
}
@@ -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,980 @@
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?, initialAmount: Double?) {
val extras = SelectSendFragment.getBundle(payload, initialRecipientAddress, initialAmount)
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().cases()
.addCase(R.id.mainFragment, R.id.action_mainFragment_to_sendFlow)
.addCase(R.id.bridgeFragment, R.id.action_bridge_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 openBridgeFlow() {
navigationBuilder().action(R.id.action_mainFragment_to_bridgeFlow)
.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)
}
}
@@ -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)
}
}
@@ -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()
}
}
@@ -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))
}
}
@@ -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))
}
}
@@ -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))
}
}
@@ -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)
}
}
@@ -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)
}
}
@@ -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)
}
}
@@ -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
}
}
@@ -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
}
@@ -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)
}
@@ -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)
}
}
@@ -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)
@@ -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()
}
}
@@ -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()
}
}
@@ -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)
@@ -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()
}
}
@@ -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()
}
}
@@ -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())
}
}
@@ -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()
}
}
@@ -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()
}
}
}
@@ -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()
}
}
@@ -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()
}
}
@@ -0,0 +1,268 @@
package io.novafoundation.nova.app.root.navigation.navigators.governance
import android.os.Bundle
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.app.root.navigation.openSplitScreenWithInstantAction
import io.novafoundation.nova.common.resources.ContextManager
import io.novafoundation.nova.common.utils.showBrowser
import io.novafoundation.nova.feature_dapp_api.presentation.browser.main.DAppBrowserPayload
import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter
import io.novafoundation.nova.feature_governance_impl.BuildConfig
import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter
import io.novafoundation.nova.feature_governance_impl.presentation.common.description.DescriptionFragment
import io.novafoundation.nova.feature_governance_impl.presentation.common.description.DescriptionPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegate.delegators.DelegateDelegatorsFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegate.delegators.DelegateDelegatorsPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegate.detail.main.DelegateDetailsFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegate.detail.main.DelegateDetailsPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegate.detail.votedReferenda.VotedReferendaFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegate.detail.votedReferenda.VotedReferendaPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.create.chooseAmount.NewDelegationChooseAmountFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.create.chooseAmount.NewDelegationChooseAmountPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.create.chooseTrack.NewDelegationChooseTracksFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.create.chooseTrack.NewDelegationChooseTracksPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.create.confirm.NewDelegationConfirmFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.create.confirm.NewDelegationConfirmPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.removeVotes.RemoveVotesFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.removeVotes.RemoveVotesPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.revoke.chooseTracks.RevokeDelegationChooseTracksFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.revoke.chooseTracks.RevokeDelegationChooseTracksPayload
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.revoke.confirm.RevokeDelegationConfirmFragment
import io.novafoundation.nova.feature_governance_impl.presentation.delegation.delegation.revoke.confirm.RevokeDelegationConfirmPayload
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.details.ReferendumDetailsFragment
import io.novafoundation.nova.feature_governance_api.presentation.referenda.details.ReferendumDetailsPayload
import io.novafoundation.nova.feature_governance_impl.presentation.common.info.ReferendumInfoFragment
import io.novafoundation.nova.feature_governance_impl.presentation.common.info.ReferendumInfoPayload
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.full.ReferendumFullDetailsFragment
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.full.ReferendumFullDetailsPayload
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.confirm.ConfirmReferendumVoteFragment
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.confirm.ConfirmVoteReferendumPayload
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.common.SetupVoteFragment
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.common.SetupVotePayload
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.voters.ReferendumVotersFragment
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.voters.ReferendumVotersPayload
class GovernanceNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry,
private val commonNavigator: Navigator,
private val contextManager: ContextManager,
private val dAppRouter: DAppRouter
) : BaseNavigator(navigationHoldersRegistry), GovernanceRouter {
override fun openReferendum(payload: ReferendumDetailsPayload) {
navigationBuilder().cases()
.addCase(R.id.referendumDetailsFragment, R.id.action_referendumDetailsFragment_to_referendumDetailsFragment)
.addCase(R.id.referendaSearchFragment, R.id.action_open_referendum_details_from_referenda_search)
.setFallbackCase(R.id.action_open_referendum_details)
.setArgs(ReferendumDetailsFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openReferendumFullDetails(payload: ReferendumFullDetailsPayload) {
navigationBuilder().action(R.id.action_referendumDetailsFragment_to_referendumFullDetailsFragment)
.setArgs(ReferendumFullDetailsFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openReferendumVoters(payload: ReferendumVotersPayload) {
navigationBuilder().action(R.id.action_referendumDetailsFragment_to_referendumVotersFragment)
.setArgs(ReferendumVotersFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openSetupReferendumVote(payload: SetupVotePayload) {
navigationBuilder().action(R.id.action_referendumDetailsFragment_to_setupVoteReferendumFragment)
.setArgs(SetupVoteFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openSetupTinderGovVote(payload: SetupVotePayload) {
navigationBuilder().action(R.id.action_tinderGovCards_to_setupTinderGovVoteFragment)
.setArgs(SetupVoteFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun backToReferendumDetails() {
navigationBuilder().action(R.id.action_confirmReferendumVote_to_referendumDetailsFragment)
.navigateInFirstAttachedContext()
}
override fun finishUnlockFlow(shouldCloseLocksScreen: Boolean) {
if (shouldCloseLocksScreen) {
navigationBuilder().action(R.id.action_confirmReferendumVote_to_mainFragment)
.navigateInFirstAttachedContext()
} else {
back()
}
}
override fun openWalletDetails(id: Long) {
commonNavigator.openWalletDetails(id)
}
override fun openAddDelegation() {
navigationBuilder().cases()
.addCase(R.id.mainFragment, R.id.action_mainFragment_to_delegation)
.addCase(R.id.yourDelegationsFragment, R.id.action_yourDelegations_to_delegationList)
.navigateInFirstAttachedContext()
}
override fun openYourDelegations() {
navigationBuilder().action(R.id.action_mainFragment_to_your_delegation)
.navigateInFirstAttachedContext()
}
override fun openBecomingDelegateTutorial() {
contextManager.getActivity()?.showBrowser(BuildConfig.DELEGATION_TUTORIAL_URL)
}
override fun backToYourDelegations() {
navigationBuilder().action(R.id.action_back_to_your_delegations)
.navigateInFirstAttachedContext()
}
override fun openRevokeDelegationChooseTracks(payload: RevokeDelegationChooseTracksPayload) {
navigationBuilder().action(R.id.action_delegateDetailsFragment_to_revokeDelegationChooseTracksFragment)
.setArgs(RevokeDelegationChooseTracksFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openRevokeDelegationsConfirm(payload: RevokeDelegationConfirmPayload) {
navigationBuilder().action(R.id.action_revokeDelegationChooseTracksFragment_to_revokeDelegationConfirmFragment)
.setArgs(RevokeDelegationConfirmFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openDelegateSearch() {
navigationBuilder().action(R.id.action_delegateListFragment_to_delegateSearchFragment)
.navigateInFirstAttachedContext()
}
override fun openSelectGovernanceTracks(bundle: Bundle) {
navigationBuilder().action(R.id.action_open_select_governance_tracks)
.setArgs(bundle)
.navigateInFirstAttachedContext()
}
override fun openTinderGovCards() {
navigationBuilder().action(R.id.action_openTinderGovCards)
.navigateInFirstAttachedContext()
}
override fun openTinderGovBasket() {
navigationBuilder().action(R.id.action_tinderGovCards_to_tinderGovBasket)
.navigateInFirstAttachedContext()
}
override fun openConfirmTinderGovVote() {
navigationBuilder().action(R.id.action_setupTinderGovBasket_to_confirmTinderGovVote)
.navigateInFirstAttachedContext()
}
override fun backToTinderGovCards() {
navigationBuilder().action(R.id.action_confirmTinderGovVote_to_tinderGovCards)
.navigateInFirstAttachedContext()
}
override fun openReferendumInfo(payload: ReferendumInfoPayload) {
navigationBuilder().cases()
.addCase(R.id.tinderGovCards, R.id.action_tinderGovCards_to_referendumInfo)
.addCase(R.id.setupTinderGovBasketFragment, R.id.action_setupTinderGovBasket_to_referendumInfo)
.setArgs(ReferendumInfoFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openReferendumFromDeepLink(payload: ReferendumDetailsPayload) {
openSplitScreenWithInstantAction(R.id.action_open_referendum_details, ReferendumDetailsFragment.getBundle(payload))
}
override fun openReferendaSearch() {
navigationBuilder().action(R.id.action_open_referenda_search)
.navigateInFirstAttachedContext()
}
override fun openReferendaFilters() {
navigationBuilder().action(R.id.action_open_referenda_filters)
.navigateInFirstAttachedContext()
}
override fun openRemoveVotes(payload: RemoveVotesPayload) {
navigationBuilder().action(R.id.action_open_remove_votes)
.setArgs(RemoveVotesFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openDelegateDelegators(payload: DelegateDelegatorsPayload) {
navigationBuilder().action(R.id.action_delegateDetailsFragment_to_delegateDelegatorsFragment)
.setArgs(DelegateDelegatorsFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openDelegateDetails(payload: DelegateDetailsPayload) {
navigationBuilder().cases()
.addCase(R.id.delegateListFragment, R.id.action_delegateListFragment_to_delegateDetailsFragment)
.addCase(R.id.yourDelegationsFragment, R.id.action_yourDelegations_to_delegationDetails)
.addCase(R.id.delegateSearchFragment, R.id.action_delegateSearchFragment_to_delegateDetailsFragment)
.setArgs(DelegateDetailsFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openNewDelegationChooseTracks(payload: NewDelegationChooseTracksPayload) {
navigationBuilder().action(R.id.action_delegateDetailsFragment_to_selectDelegationTracks)
.setArgs(NewDelegationChooseTracksFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openNewDelegationChooseAmount(payload: NewDelegationChooseAmountPayload) {
navigationBuilder().action(R.id.action_selectDelegationTracks_to_newDelegationChooseAmountFragment)
.setArgs(NewDelegationChooseAmountFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openNewDelegationConfirm(payload: NewDelegationConfirmPayload) {
navigationBuilder().action(R.id.action_newDelegationChooseAmountFragment_to_newDelegationConfirmFragment)
.setArgs(NewDelegationConfirmFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openVotedReferenda(payload: VotedReferendaPayload) {
navigationBuilder().action(R.id.action_delegateDetailsFragment_to_votedReferendaFragment)
.setArgs(VotedReferendaFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openDelegateFullDescription(payload: DescriptionPayload) {
navigationBuilder().action(R.id.action_delegateDetailsFragment_to_delegateFullDescription)
.setArgs(DescriptionFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openDAppBrowser(url: String) {
dAppRouter.openDAppBrowser(DAppBrowserPayload.Address(url))
}
override fun openReferendumDescription(payload: DescriptionPayload) {
navigationBuilder().action(R.id.action_referendumDetailsFragment_to_referendumDescription)
.setArgs(DescriptionFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openConfirmVoteReferendum(payload: ConfirmVoteReferendumPayload) {
navigationBuilder().action(R.id.action_setupVoteReferendumFragment_to_confirmReferendumVote)
.setArgs(ConfirmReferendumVoteFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openGovernanceLocksOverview() {
navigationBuilder().action(R.id.action_mainFragment_to_governanceLocksOverview)
.navigateInFirstAttachedContext()
}
override fun openConfirmGovernanceUnlock() {
navigationBuilder().action(R.id.action_governanceLocksOverview_to_confirmGovernanceUnlock)
.navigateInFirstAttachedContext()
}
}
@@ -0,0 +1,20 @@
package io.novafoundation.nova.app.root.navigation.navigators.governance
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.SelectTracksCommunicator
import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectTracksRequester
import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectTracksResponder
import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter
import io.novafoundation.nova.feature_governance_impl.presentation.tracks.select.governanceTracks.SelectGovernanceTracksFragment
class SelectTracksCommunicatorImpl(private val router: GovernanceRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
NavStackInterScreenCommunicator<SelectTracksRequester.Request, SelectTracksResponder.Response>(navigationHoldersRegistry),
SelectTracksCommunicator {
override fun openRequest(request: SelectTracksRequester.Request) {
super.openRequest(request)
router.openSelectGovernanceTracks(SelectGovernanceTracksFragment.getBundle(request))
}
}
@@ -0,0 +1,24 @@
package io.novafoundation.nova.app.root.navigation.navigators.governance
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.common.SetupVotePayload
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteCommunicator
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteRequester
import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteResponder
import kotlinx.coroutines.flow.Flow
class TinderGovVoteCommunicatorImpl(private val router: GovernanceRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
NavStackInterScreenCommunicator<TinderGovVoteRequester.Request, TinderGovVoteResponder.Response>(navigationHoldersRegistry),
TinderGovVoteCommunicator {
override val responseFlow: Flow<TinderGovVoteResponder.Response>
get() = clearedResponseFlow()
override fun openRequest(request: TinderGovVoteRequester.Request) {
super.openRequest(request)
router.openSetupTinderGovVote(SetupVotePayload(request.referendumId))
}
}
@@ -0,0 +1,100 @@
package io.novafoundation.nova.app.root.navigation.navigators.ledger
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_account_impl.presentation.AccountRouter
import io.novafoundation.nova.feature_ledger_impl.presentation.LedgerRouter
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.generic.selectAddress.AddEvmGenericLedgerAccountSelectAddressFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.generic.selectAddress.AddEvmGenericLedgerAccountSelectAddressPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.legacy.selectAddress.AddLedgerChainAccountSelectAddressFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.addChain.legacy.selectAddress.AddLedgerChainAccountSelectAddressPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.common.selectAddress.SelectAddressLedgerFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.common.selectAddress.SelectLedgerAddressPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.generic.finish.FinishImportGenericLedgerFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.generic.finish.FinishImportGenericLedgerPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.generic.preview.PreviewImportGenericLedgerFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.generic.preview.PreviewImportGenericLedgerPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.generic.selectLedger.SelectLedgerGenericImportFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.generic.selectLedger.SelectLedgerGenericPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.fillWallet.FillWalletImportLedgerFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.fillWallet.FillWalletImportLedgerLegacyPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.finish.FinishImportLedgerFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.finish.FinishImportLedgerPayload
class LedgerNavigator(
private val accountRouter: AccountRouter,
navigationHoldersRegistry: NavigationHoldersRegistry
) : BaseNavigator(navigationHoldersRegistry), LedgerRouter {
override fun openImportFillWallet(payload: FillWalletImportLedgerLegacyPayload) {
navigationBuilder().action(R.id.action_startImportLedgerFragment_to_fillWalletImportLedgerFragment)
.setArgs(FillWalletImportLedgerFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun returnToImportFillWallet() {
navigationBuilder().action(R.id.action_selectAddressImportLedgerFragment_to_fillWalletImportLedgerFragment)
.navigateInFirstAttachedContext()
}
override fun openSelectImportAddress(payload: SelectLedgerAddressPayload) {
navigationBuilder().action(R.id.action_selectLedgerImportFragment_to_selectAddressImportLedgerFragment)
.setArgs(SelectAddressLedgerFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openCreatePincode() {
accountRouter.openCreatePincode()
}
override fun openMain() {
accountRouter.openMain()
}
override fun openFinishImportLedger(payload: FinishImportLedgerPayload) {
navigationBuilder().action(R.id.action_fillWalletImportLedgerFragment_to_finishImportLedgerFragment)
.setArgs(FinishImportLedgerFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun finishSignFlow() {
back()
}
override fun openAddChainAccountSelectAddress(payload: AddLedgerChainAccountSelectAddressPayload) {
navigationBuilder().action(R.id.action_addChainAccountSelectLedgerFragment_to_addChainAccountSelectAddressLedgerFragment)
.setArgs(AddLedgerChainAccountSelectAddressFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openSelectLedgerGeneric(payload: SelectLedgerGenericPayload) {
navigationBuilder().action(R.id.action_startImportGenericLedgerFragment_to_selectLedgerGenericImportFragment)
.setArgs(SelectLedgerGenericImportFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openSelectAddressGenericLedger(payload: SelectLedgerAddressPayload) {
navigationBuilder().action(R.id.action_selectLedgerGenericImportFragment_to_selectAddressImportGenericLedgerFragment)
.setArgs(SelectAddressLedgerFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openPreviewLedgerAccountsGeneric(payload: PreviewImportGenericLedgerPayload) {
navigationBuilder().action(R.id.action_selectAddressImportGenericLedgerFragment_to_previewImportGenericLedgerFragment)
.setArgs(PreviewImportGenericLedgerFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openFinishImportLedgerGeneric(payload: FinishImportGenericLedgerPayload) {
navigationBuilder().action(R.id.action_previewImportGenericLedgerFragment_to_finishImportGenericLedgerFragment)
.setArgs(FinishImportGenericLedgerFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openAddGenericEvmAddressSelectAddress(payload: AddEvmGenericLedgerAccountSelectAddressPayload) {
navigationBuilder().action(R.id.action_addEvmAccountSelectGenericLedgerFragment_to_addEvmGenericLedgerAccountSelectAddressFragment)
.setArgs(AddEvmGenericLedgerAccountSelectAddressFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
}
@@ -0,0 +1,37 @@
package io.novafoundation.nova.app.root.navigation.navigators.ledger
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.LedgerVariant
import io.novafoundation.nova.feature_account_api.presenatation.sign.LedgerSignCommunicator
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_ledger_impl.presentation.account.common.selectLedger.SelectLedgerPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.sign.SignLedgerFragment
import io.novafoundation.nova.feature_ledger_impl.presentation.account.sign.SignLedgerPayload
class LedgerSignCommunicatorImpl(navigationHoldersRegistry: NavigationHoldersRegistry) :
NavStackInterScreenCommunicator<Request, Response>(navigationHoldersRegistry), LedgerSignCommunicator {
private var usedVariant: LedgerVariant? = null
override fun respond(response: Response) {
val requester = navController.getBackStackEntryBefore(R.id.signLedgerFragment)
saveResultTo(requester, response)
}
override fun setUsedVariant(variant: LedgerVariant) {
usedVariant = variant
}
override fun openRequest(request: Request) {
super.openRequest(request)
val payload = SignLedgerPayload(request, requireNotNull(usedVariant), SelectLedgerPayload.ConnectionMode.ALL)
val bundle = SignLedgerFragment.getBundle(payload)
navController.navigate(R.id.action_open_sign_ledger, bundle)
}
}
@@ -0,0 +1,27 @@
package io.novafoundation.nova.app.root.navigation.navigators.ledger
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_ledger_impl.presentation.account.connect.legacy.selectLedger.SelectLedgerLegacyPayload
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.LedgerChainAccount
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.SelectLedgerAddressInterScreenCommunicator
import io.novafoundation.nova.feature_ledger_impl.presentation.account.connect.legacy.selectLedger.SelectLedgerLegacyImportFragment
class SelectLedgerAddressCommunicatorImpl(navigationHoldersRegistry: NavigationHoldersRegistry) :
NavStackInterScreenCommunicator<SelectLedgerLegacyPayload, LedgerChainAccount>(navigationHoldersRegistry),
SelectLedgerAddressInterScreenCommunicator {
override fun openRequest(request: SelectLedgerLegacyPayload) {
super.openRequest(request)
val args = SelectLedgerLegacyImportFragment.getBundle(request)
navController.navigate(R.id.action_fillWalletImportLedgerFragment_to_selectLedgerImportFragment, args)
}
override fun respond(response: LedgerChainAccount) {
val responseEntry = navController.getBackStackEntry(R.id.fillWalletImportLedgerFragment)
saveResultTo(responseEntry, response)
}
}
@@ -0,0 +1,47 @@
package io.novafoundation.nova.app.root.navigation.navigators.multisig
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_multisig_operations.presentation.MultisigOperationsRouter
import io.novafoundation.nova.feature_multisig_operations.presentation.details.general.MultisigOperationDetailsFragment
import io.novafoundation.nova.feature_multisig_operations.presentation.common.MultisigOperationPayload
import io.novafoundation.nova.feature_multisig_operations.presentation.details.full.MultisigOperationFullDetailsFragment
import io.novafoundation.nova.feature_multisig_operations.presentation.details.general.MultisigOperationDetailsPayload
import io.novafoundation.nova.feature_multisig_operations.presentation.enterCall.MultisigOperationEnterCallFragment
class MultisigOperationsNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry,
private val commonDelegate: Navigator,
) : BaseNavigator(navigationHoldersRegistry), MultisigOperationsRouter {
override fun openPendingOperations() {
navigationBuilder().action(R.id.action_multisigCreatedDialog_to_multisigPendingOperationsFlow)
.navigateInFirstAttachedContext()
}
override fun openMain() {
commonDelegate.openMain()
}
override fun openMultisigOperationDetails(payload: MultisigOperationDetailsPayload) {
navigationBuilder().cases()
.addCase(R.id.multisigPendingOperationsFragment, R.id.action_multisigPendingOperationsFragment_to_multisigOperationDetailsFragment)
.setFallbackCase(R.id.action_multisigOperationDetailsFragment)
.setArgs(MultisigOperationDetailsFragment.createPayload(payload))
.navigateInFirstAttachedContext()
}
override fun openMultisigFullDetails(payload: MultisigOperationPayload) {
navigationBuilder().action(R.id.action_multisigOperationDetailsFragment_to_externalExtrinsicDetailsFragment)
.setArgs(MultisigOperationFullDetailsFragment.createPayload(payload))
.navigateInFirstAttachedContext()
}
override fun openEnterCallDetails(payload: MultisigOperationPayload) {
navigationBuilder().action(R.id.action_multisigOperationDetailsFragment_to_enterCallDetails)
.setArgs(MultisigOperationEnterCallFragment.createPayload(payload))
.navigateInFirstAttachedContext()
}
}
@@ -0,0 +1,18 @@
package io.novafoundation.nova.app.root.navigation.navigators.nft
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_nft_impl.NftRouter
import io.novafoundation.nova.feature_nft_impl.presentation.nft.details.NftDetailsFragment
class NftNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry
) : BaseNavigator(navigationHoldersRegistry), NftRouter {
override fun openNftDetails(nftId: String) {
navigationBuilder().action(R.id.action_nftListFragment_to_nftDetailsFragment)
.setArgs(NftDetailsFragment.getBundle(nftId))
.navigateInFirstAttachedContext()
}
}
@@ -0,0 +1,25 @@
package io.novafoundation.nova.app.root.navigation.navigators.pincode
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.sequrity.verification.PinCodeTwoFactorVerificationCommunicator
import io.novafoundation.nova.common.sequrity.verification.PinCodeTwoFactorVerificationRequester.Request
import io.novafoundation.nova.common.sequrity.verification.PinCodeTwoFactorVerificationResponder.Response
import io.novafoundation.nova.feature_account_impl.presentation.pincode.PinCodeAction
import io.novafoundation.nova.feature_account_impl.presentation.pincode.PincodeFragment
class PinCodeTwoFactorVerificationCommunicatorImpl(
private val navigationHoldersRegistry: NavigationHoldersRegistry
) : FlowInterScreenCommunicator<Request, Response>(), PinCodeTwoFactorVerificationCommunicator {
override fun dispatchRequest(request: Request) {
val action = PinCodeAction.TwoFactorVerification(request.useBiometryIfEnabled)
val bundle = PincodeFragment.getPinCodeBundle(action)
navigationHoldersRegistry.navigationBuilder().action(R.id.action_pin_code_two_factor_verification)
.setArgs(bundle)
.navigateInRoot()
}
}
@@ -0,0 +1,20 @@
package io.novafoundation.nova.app.root.navigation.navigators.push
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
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.governance.PushGovernanceSettingsFragment
import io.novafoundation.nova.feature_push_notifications.presentation.governance.PushGovernanceSettingsRequester
import io.novafoundation.nova.feature_push_notifications.presentation.governance.PushGovernanceSettingsResponder
class PushGovernanceSettingsCommunicatorImpl(private val router: PushNotificationsRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
NavStackInterScreenCommunicator<PushGovernanceSettingsRequester.Request, PushGovernanceSettingsResponder.Response>(navigationHoldersRegistry),
PushGovernanceSettingsCommunicator {
override fun openRequest(request: PushGovernanceSettingsRequester.Request) {
super.openRequest(request)
router.openPushGovernanceSettings(PushGovernanceSettingsFragment.getBundle(request))
}
}
@@ -0,0 +1,20 @@
package io.novafoundation.nova.app.root.navigation.navigators.push
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
import io.novafoundation.nova.feature_push_notifications.PushNotificationsRouter
import io.novafoundation.nova.feature_push_notifications.presentation.multisigs.PushMultisigSettingsCommunicator
import io.novafoundation.nova.feature_push_notifications.presentation.multisigs.PushMultisigSettingsFragment
import io.novafoundation.nova.feature_push_notifications.presentation.multisigs.PushMultisigSettingsRequester
import io.novafoundation.nova.feature_push_notifications.presentation.multisigs.PushMultisigSettingsResponder
class PushMultisigSettingsCommunicatorImpl(private val router: PushNotificationsRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
NavStackInterScreenCommunicator<PushMultisigSettingsRequester.Request, PushMultisigSettingsResponder.Response>(navigationHoldersRegistry),
PushMultisigSettingsCommunicator {
override fun openRequest(request: PushMultisigSettingsRequester.Request) {
super.openRequest(request)
router.openPushMultisigsSettings(PushMultisigSettingsFragment.createPayload(request))
}
}
@@ -0,0 +1,39 @@
package io.novafoundation.nova.app.root.navigation.navigators.push
import android.os.Bundle
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_push_notifications.PushNotificationsRouter
import io.novafoundation.nova.feature_push_notifications.presentation.settings.PushSettingsFragment
import io.novafoundation.nova.feature_push_notifications.presentation.settings.PushSettingsPayload
import io.novafoundation.nova.feature_push_notifications.presentation.settings.withWalletSelection
class PushNotificationsNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry
) : BaseNavigator(navigationHoldersRegistry), PushNotificationsRouter {
override fun openPushSettingsWithAccounts() {
navigationBuilder().action(R.id.action_open_pushNotificationsSettings)
.setArgs(PushSettingsFragment.createPayload(PushSettingsPayload.withWalletSelection(enableSwitcherOnStart = true)))
.navigateInFirstAttachedContext()
}
override fun openPushMultisigsSettings(args: Bundle) {
navigationBuilder().action(R.id.action_pushSettings_to_multisigSettings)
.setArgs(args)
.navigateInFirstAttachedContext()
}
override fun openPushGovernanceSettings(args: Bundle) {
navigationBuilder().action(R.id.action_pushSettings_to_governanceSettings)
.setArgs(args)
.navigateInFirstAttachedContext()
}
override fun openPushStakingSettings(args: Bundle) {
navigationBuilder().action(R.id.action_pushSettings_to_stakingSettings)
.setArgs(args)
.navigateInFirstAttachedContext()
}
}
@@ -0,0 +1,20 @@
package io.novafoundation.nova.app.root.navigation.navigators.push
import io.novafoundation.nova.app.root.navigation.NavStackInterScreenCommunicator
import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry
import io.novafoundation.nova.feature_push_notifications.PushNotificationsRouter
import io.novafoundation.nova.feature_push_notifications.presentation.staking.PushStakingSettingsCommunicator
import io.novafoundation.nova.feature_push_notifications.presentation.staking.PushStakingSettingsFragment
import io.novafoundation.nova.feature_push_notifications.presentation.staking.PushStakingSettingsRequester
import io.novafoundation.nova.feature_push_notifications.presentation.staking.PushStakingSettingsResponder
class PushStakingSettingsCommunicatorImpl(private val router: PushNotificationsRouter, navigationHoldersRegistry: NavigationHoldersRegistry) :
NavStackInterScreenCommunicator<PushStakingSettingsRequester.Request, PushStakingSettingsResponder.Response>(navigationHoldersRegistry),
PushStakingSettingsCommunicator {
override fun openRequest(request: PushStakingSettingsRequester.Request) {
super.openRequest(request)
router.openPushStakingSettings(PushStakingSettingsFragment.getBundle(request))
}
}
@@ -0,0 +1,137 @@
package io.novafoundation.nova.app.root.navigation.navigators.settings
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.app.root.presentation.RootRouter
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_push_notifications.presentation.settings.PushSettingsFragment
import io.novafoundation.nova.feature_push_notifications.presentation.settings.PushSettingsPayload
import io.novafoundation.nova.feature_push_notifications.presentation.settings.default
import io.novafoundation.nova.feature_settings_impl.SettingsRouter
import io.novafoundation.nova.feature_settings_impl.presentation.networkManagement.add.main.AddNetworkMainFragment
import io.novafoundation.nova.feature_settings_impl.presentation.networkManagement.add.main.AddNetworkPayload
import io.novafoundation.nova.feature_settings_impl.presentation.networkManagement.chain.ChainNetworkManagementFragment
import io.novafoundation.nova.feature_settings_impl.presentation.networkManagement.chain.ChainNetworkManagementPayload
import io.novafoundation.nova.feature_settings_impl.presentation.networkManagement.main.NetworkManagementListFragment
import io.novafoundation.nova.feature_settings_impl.presentation.networkManagement.node.CustomNodeFragment
import io.novafoundation.nova.feature_settings_impl.presentation.networkManagement.node.CustomNodePayload
import io.novafoundation.nova.feature_wallet_connect_impl.WalletConnectRouter
import io.novafoundation.nova.feature_wallet_connect_impl.presentation.sessions.list.WalletConnectSessionsPayload
class SettingsNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry,
private val rootRouter: RootRouter,
private val walletConnectDelegate: WalletConnectRouter,
private val delegate: Navigator
) : BaseNavigator(navigationHoldersRegistry),
SettingsRouter {
override fun returnToWallet() {
rootRouter.returnToWallet()
}
override fun openWallets() {
delegate.openWallets()
}
override fun openNetworks() {
navigationBuilder().action(R.id.action_open_networkManagement)
.navigateInFirstAttachedContext()
}
override fun openNetworkDetails(payload: ChainNetworkManagementPayload) {
navigationBuilder().action(R.id.action_open_networkManagementDetails)
.setArgs(ChainNetworkManagementFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openCustomNode(payload: CustomNodePayload) {
navigationBuilder().action(R.id.action_open_customNode)
.setArgs(CustomNodeFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun addNetwork() {
navigationBuilder().action(R.id.action_open_preConfiguredNetworks)
.navigateInFirstAttachedContext()
}
override fun openCreateNetworkFlow() {
navigationBuilder().action(R.id.action_open_addNetworkFragment)
.navigateInFirstAttachedContext()
}
override fun openCreateNetworkFlow(payload: AddNetworkPayload.Mode.Add) {
navigationBuilder().action(R.id.action_open_addNetworkFragment)
.setArgs(AddNetworkMainFragment.getBundle(AddNetworkPayload(payload)))
.navigateInFirstAttachedContext()
}
override fun finishCreateNetworkFlow() {
navigationBuilder().action(R.id.action_finishCreateNetworkFlow)
.setArgs(NetworkManagementListFragment.getBundle(openAddedTab = true))
.navigateInFirstAttachedContext()
}
override fun openEditNetwork(payload: AddNetworkPayload.Mode.Edit) {
navigationBuilder().action(R.id.action_open_editNetwork)
.setArgs(AddNetworkMainFragment.getBundle(AddNetworkPayload(payload)))
.navigateInFirstAttachedContext()
}
override fun openPushNotificationSettings() {
navigationBuilder().action(R.id.action_open_pushNotificationsSettings)
.setArgs(PushSettingsFragment.createPayload(PushSettingsPayload.default()))
.navigateInFirstAttachedContext()
}
override fun openCurrencies() {
navigationBuilder().action(R.id.action_mainFragment_to_currenciesFragment)
.navigateInFirstAttachedContext()
}
override fun openLanguages() {
navigationBuilder().action(R.id.action_mainFragment_to_languagesFragment)
.navigateInFirstAttachedContext()
}
override fun openAppearance() {
navigationBuilder().action(R.id.action_mainFragment_to_appearanceFragment)
.navigateInFirstAttachedContext()
}
override fun openChangePinCode() {
navigationBuilder().action(R.id.action_change_pin_code)
.setArgs(PincodeFragment.getPinCodeBundle(PinCodeAction.Change))
.navigateInFirstAttachedContext()
}
override fun openWalletDetails(metaId: Long) {
delegate.openWalletDetails(metaId)
}
override fun openSwitchWallet() {
delegate.openSwitchWallet()
}
override fun openWalletConnectScan() {
walletConnectDelegate.openScanPairingQrCode()
}
override fun openWalletConnectSessions() {
walletConnectDelegate.openWalletConnectSessions(WalletConnectSessionsPayload(metaId = null))
}
override fun openCloudBackupSettings() {
navigationBuilder().action(R.id.action_open_cloudBackupSettings)
.navigateInFirstAttachedContext()
}
override fun openManualBackup() {
navigationBuilder().action(R.id.action_open_manualBackupSelectWallet)
.navigateInFirstAttachedContext()
}
}
@@ -0,0 +1,67 @@
package io.novafoundation.nova.app.root.navigation.navigators.staking
import androidx.lifecycle.MutableLiveData
import androidx.navigation.NavController
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.common.utils.Event
import io.novafoundation.nova.common.utils.event
import io.novafoundation.nova.feature_staking_impl.presentation.StakingDashboardRouter
class StakingDashboardNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry
) : BaseNavigator(navigationHoldersRegistry), StakingDashboardRouter {
private var stakingTabNavController: NavController? = null
private var pendingAction: Int? = null
override val scrollToDashboardTopEvent = MutableLiveData<Event<Unit>>()
fun setStakingTabNavController(navController: NavController) {
stakingTabNavController = navController
if (pendingAction != null) {
navController.navigate(pendingAction!!)
pendingAction = null
}
}
fun clearStakingTabNavController() {
stakingTabNavController = null
}
override fun openMoreStakingOptions() {
stakingTabNavController?.navigate(R.id.action_stakingDashboardFragment_to_moreStakingOptionsFragment)
}
override fun backInStakingTab() {
stakingTabNavController?.popBackStack()
}
override fun returnToStakingDashboard() {
navigationBuilder()
.action(R.id.back_to_main)
.navigateInFirstAttachedContext()
returnToStakingTabRoot()
scrollToDashboardTopEvent.value = Unit.event()
}
override fun openStakingDashboard() {
stakingTabNavController.performNavigationOrDelay(R.id.action_open_staking)
}
private fun returnToStakingTabRoot() {
stakingTabNavController.performNavigationOrDelay(R.id.return_to_staking_dashboard)
}
private fun NavController?.performNavigationOrDelay(actionId: Int) {
val controller = this
if (controller != null) {
controller.navigate(actionId)
} else {
pendingAction = actionId
}
}
}
@@ -0,0 +1,74 @@
package io.novafoundation.nova.app.root.navigation.navigators.staking
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_staking_impl.presentation.StakingDashboardRouter
import io.novafoundation.nova.feature_staking_impl.presentation.StartMultiStakingRouter
import io.novafoundation.nova.feature_staking_impl.presentation.parachainStaking.start.common.StartParachainStakingMode
import io.novafoundation.nova.feature_staking_impl.presentation.parachainStaking.start.setup.StartParachainStakingFragment
import io.novafoundation.nova.feature_staking_impl.presentation.parachainStaking.start.setup.StartParachainStakingPayload
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.confirm.ConfirmMultiStakingFragment
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.confirm.ConfirmMultiStakingPayload
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.landing.StartStakingLandingFragment
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.landing.model.StartStakingLandingPayload
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.setupAmount.SetupAmountMultiStakingFragment
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.setupAmount.SetupAmountMultiStakingPayload
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.setupStakingType.SetupStakingTypeFragment
import io.novafoundation.nova.feature_staking_impl.presentation.staking.start.setupStakingType.SetupStakingTypePayload
class StartMultiStakingNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry,
private val stakingDashboardRouter: StakingDashboardRouter,
private val commonNavigationHolder: Navigator,
) : BaseNavigator(navigationHoldersRegistry), StartMultiStakingRouter {
override fun openStartStakingLanding(payload: StartStakingLandingPayload) {
navigationBuilder().action(R.id.action_mainFragment_to_startStackingLanding)
.setArgs(StartStakingLandingFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openStartParachainStaking() {
navigationBuilder().action(R.id.action_startStakingLandingFragment_to_staking_parachain_start_graph)
.setArgs(StartParachainStakingFragment.getBundle(StartParachainStakingPayload(StartParachainStakingMode.START)))
.navigateInFirstAttachedContext()
}
override fun openStartMythosStaking() {
navigationBuilder().action(R.id.action_startStakingLandingFragment_to_staking_mythos_start_graph)
.navigateInFirstAttachedContext()
}
override fun openStartMultiStaking(payload: SetupAmountMultiStakingPayload) {
navigationBuilder().action(R.id.action_startStakingLandingFragment_to_start_multi_staking_nav_graph)
.setArgs(SetupAmountMultiStakingFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openSetupStakingType(payload: SetupStakingTypePayload) {
navigationBuilder().action(R.id.action_setupAmountMultiStakingFragment_to_setupStakingType)
.setArgs(SetupStakingTypeFragment.getArguments(payload))
.navigateInFirstAttachedContext()
}
override fun openConfirm(payload: ConfirmMultiStakingPayload) {
navigationBuilder().action(R.id.action_setupAmountMultiStakingFragment_to_confirmMultiStakingFragment)
.setArgs(ConfirmMultiStakingFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openSelectedValidators() {
navigationBuilder().action(R.id.action_confirmMultiStakingFragment_to_confirmNominationsFragment)
.navigateInFirstAttachedContext()
}
override fun returnToStakingDashboard() {
stakingDashboardRouter.returnToStakingDashboard()
}
override fun goToWalletDetails(metaId: Long) {
commonNavigationHolder.openWalletDetails(metaId)
}
}
@@ -0,0 +1,91 @@
package io.novafoundation.nova.app.root.navigation.navigators.staking.mythos
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_staking_impl.domain.staking.redeem.RedeemConsequences
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.start.confirm.ConfirmStartMythosStakingFragment
import io.novafoundation.nova.feature_staking_impl.presentation.mythos.start.confirm.ConfirmStartMythosStakingPayload
import io.novafoundation.nova.feature_staking_impl.presentation.mythos.unbond.confirm.ConfirmUnbondMythosFragment
import io.novafoundation.nova.feature_staking_impl.presentation.mythos.unbond.confirm.ConfirmUnbondMythosPayload
import io.novafoundation.nova.feature_staking_impl.presentation.validators.details.StakeTargetDetailsPayload
import io.novafoundation.nova.feature_staking_impl.presentation.validators.details.ValidatorDetailsFragment
class MythosStakingNavigator(
navigationHoldersRegistry: NavigationHoldersRegistry,
private val stakingDashboardRouter: StakingDashboardRouter,
) : BaseNavigator(navigationHoldersRegistry), MythosStakingRouter {
override fun openCollatorDetails(payload: StakeTargetDetailsPayload) {
navigationBuilder()
.action(R.id.open_validator_details)
.setArgs(ValidatorDetailsFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openConfirmStartStaking(payload: ConfirmStartMythosStakingPayload) {
navigationBuilder()
.action(R.id.action_startMythosStakingFragment_to_confirmStartMythosStakingFragment)
.setArgs(ConfirmStartMythosStakingFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openClaimRewards() {
navigationBuilder()
.action(R.id.action_open_mythos_claim_rewards)
.navigateInFirstAttachedContext()
}
override fun openBondMore() {
navigationBuilder()
.action(R.id.action_open_MythosBondMoreGraph)
.navigateInFirstAttachedContext()
}
override fun openUnbond() {
navigationBuilder()
.action(R.id.action_open_stakingMythosUnbondGraph)
.navigateInFirstAttachedContext()
}
override fun openUnbondConfirm(payload: ConfirmUnbondMythosPayload) {
navigationBuilder()
.action(R.id.action_setupUnbondMythosFragment_to_confirmUnbondMythosFragment)
.setArgs(ConfirmUnbondMythosFragment.getBundle(payload))
.navigateInFirstAttachedContext()
}
override fun openRedeem() {
navigationBuilder()
.action(R.id.action_stakingFragment_to_mythosRedeemFragment)
.navigateInFirstAttachedContext()
}
override fun finishRedeemFlow(redeemConsequences: RedeemConsequences) {
if (redeemConsequences.willKillStash) {
stakingDashboardRouter.returnToStakingDashboard()
} else {
returnToStakingMain()
}
}
override fun openStakedCollators() {
navigationBuilder()
.action(R.id.action_stakingFragment_to_mythosCurrentCollatorsFragment)
.navigateInFirstAttachedContext()
}
override fun returnToStartStaking() {
navigationBuilder()
.action(R.id.action_return_to_start_staking)
.navigateInFirstAttachedContext()
}
override fun returnToStakingMain() {
navigationBuilder()
.action(R.id.back_to_staking_main)
.navigateInFirstAttachedContext()
}
}
@@ -0,0 +1,20 @@
package io.novafoundation.nova.app.root.navigation.navigators.staking.mythos
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_staking_impl.presentation.mythos.start.selectCollatorSettings.SelectMythCollatorSettingsFragment
import io.novafoundation.nova.feature_staking_impl.presentation.mythos.start.selectCollatorSettings.SelectMythCollatorSettingsInterScreenCommunicator
import io.novafoundation.nova.feature_staking_impl.presentation.mythos.start.selectCollatorSettings.model.MythCollatorRecommendationConfigParcel
class SelectMythCollatorSettingsInterScreenCommunicatorImpl(navigationHoldersRegistry: NavigationHoldersRegistry) :
SelectMythCollatorSettingsInterScreenCommunicator,
NavStackInterScreenCommunicator<MythCollatorRecommendationConfigParcel, MythCollatorRecommendationConfigParcel>(navigationHoldersRegistry) {
override fun openRequest(request: MythCollatorRecommendationConfigParcel) {
super.openRequest(request)
val bundle = SelectMythCollatorSettingsFragment.getBundle(request)
navController.navigate(R.id.action_selectMythosCollatorFragment_to_selectMythCollatorSettingsFragment, bundle)
}
}

Some files were not shown because too many files have changed in this diff Show More