diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/domain/bridge/multisig/BridgeMultisigInteractor.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/domain/bridge/multisig/BridgeMultisigInteractor.kt index bae39e56..a758bfa3 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/domain/bridge/multisig/BridgeMultisigInteractor.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/domain/bridge/multisig/BridgeMultisigInteractor.kt @@ -174,9 +174,7 @@ class RealBridgeMultisigInteractor @Inject constructor( ChainGeneses.PEZKUWI_ASSET_HUB to BridgeMultisigConstants.MULTISIG_ADDRESS, ChainGeneses.POLKADOT_ASSET_HUB to BridgeMultisigConstants.MULTISIG_ADDRESS_POLKADOT, ).flatMap { (chainGenesis, multisigAddress) -> - runCatching { getPendingApprovalsFor(chainGenesis, multisigAddress, metaAccount) } - .onFailure { android.util.Log.e("BridgeDebug", "getPendingApprovalsFor($chainGenesis) threw", it) } - .getOrElse { emptyList() } + runCatching { getPendingApprovalsFor(chainGenesis, multisigAddress, metaAccount) }.getOrElse { emptyList() } } } @@ -186,14 +184,11 @@ class RealBridgeMultisigInteractor @Inject constructor( metaAccount: MetaAccount, ): List { val chain = chainRegistry.getChain(chainGenesis) - val myAccountId = metaAccount.accountIdIn(chain)?.intoKey() - android.util.Log.e("BridgeDebug", "chain=$chainGenesis myAccountId=${myAccountId?.toHexWithPrefix()}") - if (myAccountId == null) return emptyList() + val myAccountId = metaAccount.accountIdIn(chain)?.intoKey() ?: return emptyList() // Only the 5 known bridge signatories can ever have anything to approve here - same gate // as getSignerStateFor, matching how the rest of this screen already scopes itself. val isKnownSignatory = BridgeMultisigConstants.SIGNATORIES.any { it.address.toAccountId().intoKey() == myAccountId } - android.util.Log.e("BridgeDebug", "isKnownSignatory=$isKnownSignatory") if (!isKnownSignatory) return emptyList() val multisigAccountId = multisigAddress.toAccountId().intoKey() @@ -201,21 +196,17 @@ class RealBridgeMultisigInteractor @Inject constructor( val keys = storageDataSource.query(chain.id) { runtime.metadata.bridgeMultisig().multisigs.keys(multisigAccountId) } - android.util.Log.e("BridgeDebug", "keys.size=${keys.size}") if (keys.isEmpty()) return emptyList() val entries = storageDataSource.query(chain.id) { runtime.metadata.bridgeMultisig().multisigs.entries(keys) } - android.util.Log.e("BridgeDebug", "entries.size=${entries.size}") val notYetApprovedByMe = entries.filterNot { (_, onChainMultisig) -> myAccountId in onChainMultisig.approvals } - android.util.Log.e("BridgeDebug", "notYetApprovedByMe.size=${notYetApprovedByMe.size}") if (notYetApprovedByMe.isEmpty()) return emptyList() val callHashes = notYetApprovedByMe.keys.map { it.second } val callDataByHash = fetchCallData(chain, multisigAccountId, callHashes) - android.util.Log.e("BridgeDebug", "callDataByHash=${callDataByHash.mapValues { it.value != null }}") return notYetApprovedByMe.map { (key, onChainMultisig) -> val callHash = key.second @@ -236,25 +227,16 @@ class RealBridgeMultisigInteractor @Inject constructor( ): Map { return runCatching { val globalConfig = globalConfigDataSource.getGlobalConfig() - android.util.Log.e("BridgeDebug", "multisigsApiUrl=${globalConfig.multisigsApiUrl}") val request = BridgeOffChainCallDataRequest(multisigAccountId, callHashes, chain.id) val response = bridgeMultisigOperationsApi.getCallDatas(globalConfig.multisigsApiUrl, request) - android.util.Log.e("BridgeDebug", "response nodes=${response.data.multisigOperations.nodes.size}") val runtime = chainRegistry.getRuntime(chain.id) response.data.multisigOperations.nodes.mapNotNull { node -> val hash = CallHash.fromHexOrNull(node.callHash) ?: return@mapNotNull null - val call = node.callData?.let { - runCatching { GenericCall.fromHexOrNull(runtime, it) } - .onFailure { e -> android.util.Log.e("BridgeDebug", "GenericCall decode failed for $it", e) } - .getOrNull() - } - android.util.Log.e("BridgeDebug", "hash=$hash callData=${node.callData} decodedCall=${call != null}") + val call = node.callData?.let { GenericCall.fromHexOrNull(runtime, it) } hash to call }.toMap() - } - .onFailure { android.util.Log.e("BridgeDebug", "fetchCallData threw", it) } - .getOrElse { emptyMap() } + }.getOrElse { emptyMap() } } override suspend fun submitApproval(approval: PendingBridgeApproval): Result = runCatching { diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/bridge/BridgeViewModel.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/bridge/BridgeViewModel.kt index cae57f14..55d56130 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/bridge/BridgeViewModel.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/bridge/BridgeViewModel.kt @@ -25,7 +25,9 @@ import io.novafoundation.nova.feature_wallet_api.domain.model.amountFromPlanks import io.novafoundation.nova.runtime.ext.ChainGeneses import io.novafoundation.nova.runtime.ext.addressOf import io.novafoundation.nova.runtime.ext.displayNameWithAssetStandard +import io.novafoundation.nova.runtime.ext.findAssetByStatemineAssetId import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry +import io.novafoundation.nova.runtime.multiNetwork.getRuntime import io.novasama.substrate_sdk_android.ss58.SS58Encoder.toAccountId import kotlinx.coroutines.Job import kotlinx.coroutines.launch @@ -474,10 +476,8 @@ class BridgeViewModel( fun refreshPendingSignatures() { launch { - val approvals = bridgeMultisigInteractor.getPendingApprovals() - android.util.Log.e("BridgeDebug", "refreshPendingSignatures: approvals.size=${approvals.size}") - val models = approvals.mapNotNull { it.toPendingSignatureUiOrNull() } - android.util.Log.e("BridgeDebug", "refreshPendingSignatures: models.size=${models.size}") + val models = bridgeMultisigInteractor.getPendingApprovals() + .mapNotNull { it.toPendingSignatureUiOrNull() } _pendingSignatures.postValue(models) } @@ -501,24 +501,19 @@ class BridgeViewModel( * BridgeMultisigInteractor.submitApproval's own refusal to blind-sign for why this isn't * just a display-only gap: an unparseable row would have no safe "Sign" action anyway). */ private suspend fun PendingBridgeApproval.toPendingSignatureUiOrNull(): PendingSignatureModel? { - val call = call ?: run { - android.util.Log.e("BridgeDebug", "toPendingSignatureUiOrNull: call is null for hash=$callHash") - return null - } + val call = call ?: return null - val assetId = if (chain.id == ChainGeneses.POLKADOT_ASSET_HUB) { + // These constants are the raw on-chain pallet_assets id (e.g. 1984 on Polkadot Asset Hub) - + // NOT this app's own local Chain.Asset.id (chain.assetsById is keyed by the latter, which + // can differ, so it must be resolved via the Statemine-id reverse lookup, not indexed directly). + val onChainAssetId = if (chain.id == ChainGeneses.POLKADOT_ASSET_HUB) { BridgeMultisigConstants.POLKADOT_USDT_ASSET_ID } else { BridgeMultisigConstants.WUSDT_ASSET_ID } - val asset = chain.assetsById[assetId] ?: run { - android.util.Log.e("BridgeDebug", "toPendingSignatureUiOrNull: asset $assetId not found on ${chain.name}") - return null - } - val parsed = assetSourceRegistry.sourceFor(asset).transfers.tryParseTransfer(call, chain) ?: run { - android.util.Log.e("BridgeDebug", "toPendingSignatureUiOrNull: tryParseTransfer returned null, call=$call") - return null - } + val runtime = chainRegistry.getRuntime(chain.id) + val asset = chain.findAssetByStatemineAssetId(runtime, onChainAssetId.toBigInteger()) ?: return null + val parsed = assetSourceRegistry.sourceFor(asset).transfers.tryParseTransfer(call, chain) ?: return null val decimalAmount = asset.amountFromPlanks(parsed.amount.amount) val amountText = "${NumberFormat.getNumberInstance().format(decimalAmount)} ${asset.symbol.value}"