feat(staking): prepare for Polkadot 2.0 nomination pools on Asset Hub

- ChainExt.kt: Handle nomination-pools without local backing type (Polkadot 2.0)
- Add hasLocalNominationPoolsBacking() helper function
- Default to RELAYCHAIN when no local backing type exists
- StakingDashboardUpdateSystem: Improved error logging
- StakingDashboardViewModel: Show toast when item is syncing
- Update chains.json: relay chain only has relaychain staking
This commit is contained in:
2026-02-09 08:47:53 +03:00
parent 6f8a8b9511
commit 66879ae3c1
5 changed files with 114 additions and 47 deletions
@@ -90,8 +90,8 @@ class RealStakingDashboardUpdateSystem(
sharedRequestsBuilder.subscribe(accountScope)
chainUpdates.mergeIfMultiple()
}.catch {
Log.d("StakingDashboardUpdateSystem", "Failed to sync staking dashboard status for ${stakingChain.name}")
}.catch { e ->
Log.e("StakingDashboardUpdateSystem", "Failed to sync staking dashboard status for ${stakingChain.name}", e)
}
}
@@ -2,6 +2,24 @@ package io.novafoundation.nova.feature_staking_impl.domain.nominationPools
import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain
/**
* Finds the staking type that backs nomination pools.
*
* In Polkadot 1.0: Both relaychain and nomination-pools exist on the same chain
* In Polkadot 2.0: nomination-pools may exist on Asset Hub without local backing type
* (backing is via XCM from relay chain)
*
* @return The backing staking type, or RELAYCHAIN as default for Polkadot 2.0 compatibility
*/
fun Chain.Asset.findStakingTypeBackingNominationPools(): Chain.Asset.StakingType {
return staking.first { it != Chain.Asset.StakingType.NOMINATION_POOLS }
return staking.firstOrNull { it != Chain.Asset.StakingType.NOMINATION_POOLS }
?: Chain.Asset.StakingType.RELAYCHAIN // Polkadot 2.0: default to RELAYCHAIN for Asset Hub
}
/**
* Checks if this asset has nomination pools backed by a local staking type.
* Returns false for Polkadot 2.0 Asset Hub where backing is cross-chain.
*/
fun Chain.Asset.hasLocalNominationPoolsBacking(): Boolean {
return staking.any { it != Chain.Asset.StakingType.NOMINATION_POOLS }
}
@@ -102,7 +102,13 @@ class StakingDashboardViewModel(
fun onNoStakeItemClicked(index: Int) = launch {
val withoutStakeItems = stakingDashboardFlow.firstLoaded().withoutStake
val withoutStakeItem = withoutStakeItems.getOrNull(index) ?: return@launch
val noStakeItemState = withoutStakeItem.stakingState as? NoStake ?: return@launch
val noStakeItemState = withoutStakeItem.stakingState as? NoStake
if (noStakeItemState == null) {
// Item is still syncing (NotYetResolved state)
showToast(resourceManager.getString(R.string.staking_dashboard_syncing))
return@launch
}
val stakingTypes = noStakeItemState.flowType.allStakingTypes
val chain = withoutStakeItem.chain