From 8ed1909dc14e6ac755a1e689585267fc9f846ad7 Mon Sep 17 00:00:00 2001 From: Kurdistan Tech Ministry Date: Mon, 23 Feb 2026 08:29:51 +0300 Subject: [PATCH] fix: use PezkuwiCheckMortality for WalletConnect sign requests PolkadotExternalSignInteractor and ExtrinsicSplitter were using standard CheckMortality which fails with pezsp_runtime DictEnum Era type. Added isPezkuwiChain detection and routing to custom extensions. --- .../data/extrinsic/ExtrinsicSplitter.kt | 10 +++++++++- .../PolkadotExternalSignInteractor.kt | 20 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/extrinsic/ExtrinsicSplitter.kt b/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/extrinsic/ExtrinsicSplitter.kt index 1fa5f38..ce49d31 100644 --- a/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/extrinsic/ExtrinsicSplitter.kt +++ b/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/extrinsic/ExtrinsicSplitter.kt @@ -10,6 +10,7 @@ import io.novafoundation.nova.feature_account_api.data.extrinsic.ExtrinsicSplitt import io.novafoundation.nova.feature_account_api.data.extrinsic.SplitCalls import io.novafoundation.nova.runtime.ext.requireGenesisHash import io.novafoundation.nova.runtime.extrinsic.CustomTransactionExtensions +import io.novafoundation.nova.runtime.extrinsic.extensions.PezkuwiCheckImmortal import io.novafoundation.nova.runtime.extrinsic.multi.CallBuilder import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain @@ -141,12 +142,19 @@ internal class RealExtrinsicSplitter @Inject constructor( ): SendableExtrinsic { val genesisHash = chain.requireGenesisHash().fromHex() + val isPezkuwi = runtime.metadata.extrinsic.signedExtensions.any { it.id == "AuthorizeCall" } + return ExtrinsicBuilder( runtime = runtime, extrinsicVersion = ExtrinsicVersion.V4, batchMode = BatchMode.BATCH, ).apply { - setTransactionExtension(CheckMortality(Era.Immortal, genesisHash)) + // Use custom CheckMortality for Pezkuwi chains to avoid DictEnum type lookup issues + if (isPezkuwi) { + setTransactionExtension(PezkuwiCheckImmortal(genesisHash)) + } else { + setTransactionExtension(CheckMortality(Era.Immortal, genesisHash)) + } setTransactionExtension(CheckGenesis(chain.requireGenesisHash().fromHex())) setTransactionExtension(ChargeTransactionPayment(BigInteger.ZERO)) setTransactionExtension(CheckMetadataHash(CheckMetadataHashMode.Disabled)) diff --git a/feature-external-sign-impl/src/main/java/io/novafoundation/nova/feature_external_sign_impl/domain/sign/polkadot/PolkadotExternalSignInteractor.kt b/feature-external-sign-impl/src/main/java/io/novafoundation/nova/feature_external_sign_impl/domain/sign/polkadot/PolkadotExternalSignInteractor.kt index 0dea7a6..96543fb 100644 --- a/feature-external-sign-impl/src/main/java/io/novafoundation/nova/feature_external_sign_impl/domain/sign/polkadot/PolkadotExternalSignInteractor.kt +++ b/feature-external-sign-impl/src/main/java/io/novafoundation/nova/feature_external_sign_impl/domain/sign/polkadot/PolkadotExternalSignInteractor.kt @@ -39,6 +39,8 @@ import io.novafoundation.nova.runtime.ext.anyAddressToAccountId import io.novafoundation.nova.runtime.ext.utilityAsset import io.novafoundation.nova.runtime.extrinsic.CustomTransactionExtensions import io.novafoundation.nova.runtime.extrinsic.extensions.ChargeAssetTxPayment.Companion.chargeAssetTxPayment +import io.novafoundation.nova.runtime.extrinsic.extensions.PezkuwiCheckImmortal +import io.novafoundation.nova.runtime.extrinsic.extensions.PezkuwiCheckMortality import io.novafoundation.nova.runtime.extrinsic.metadata.MetadataShortenerService import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry import io.novafoundation.nova.runtime.multiNetwork.chain.model.Chain @@ -48,6 +50,7 @@ import io.novasama.substrate_sdk_android.extensions.fromHex import io.novasama.substrate_sdk_android.runtime.AccountId import io.novasama.substrate_sdk_android.runtime.RuntimeSnapshot import io.novasama.substrate_sdk_android.runtime.definitions.types.fromHex +import io.novasama.substrate_sdk_android.runtime.definitions.types.generics.Era import io.novasama.substrate_sdk_android.runtime.definitions.types.generics.EraType import io.novasama.substrate_sdk_android.runtime.definitions.types.generics.GenericCall import io.novasama.substrate_sdk_android.runtime.extrinsic.BatchMode @@ -221,9 +224,19 @@ class PolkadotExternalSignInteractor( val signingContext = signingContextFactory.default(chain) + val isPezkuwi = isPezkuwiChain(runtime) + val extrinsic = with(parsedExtrinsic) { ExtrinsicBuilder(runtime, ExtrinsicVersion.V4, BatchMode.BATCH_ALL).apply { - setTransactionExtension(CheckMortality(era, blockHash)) + // Use custom CheckMortality for Pezkuwi chains to avoid DictEnum type lookup issues + if (isPezkuwi) { + when (era) { + is Era.Mortal -> setTransactionExtension(PezkuwiCheckMortality(era, blockHash)) + is Era.Immortal -> setTransactionExtension(PezkuwiCheckImmortal(genesisHash)) + } + } else { + setTransactionExtension(CheckMortality(era, blockHash)) + } setTransactionExtension(CheckGenesis(genesisHash)) setTransactionExtension(ChargeTransactionPayment(tip)) setTransactionExtension(CheckMetadataHash(actualMetadataHash.checkMetadataHash)) @@ -350,6 +363,11 @@ class PolkadotExternalSignInteractor( private fun PolkadotSignPayload.Json.tryDecodeAssetId(runtime: RuntimeSnapshot): Any? { return assetId?.let(runtime::decodeCustomTxPaymentId) } + + private fun isPezkuwiChain(runtime: RuntimeSnapshot): Boolean { + val signedExtIds = runtime.metadata.extrinsic.signedExtensions.map { it.id } + return signedExtIds.any { it == "AuthorizeCall" } + } } private fun CheckMetadataHashMode(hash: ByteArray?): CheckMetadataHashMode {