diff --git a/android/src/main/java/net/rotko/zigner/screens/scan/transaction/UnifiedTransactionScreen.kt b/android/src/main/java/net/rotko/zigner/screens/scan/transaction/UnifiedTransactionScreen.kt index df9d69d1d1..8b17cdeb56 100644 --- a/android/src/main/java/net/rotko/zigner/screens/scan/transaction/UnifiedTransactionScreen.kt +++ b/android/src/main/java/net/rotko/zigner/screens/scan/transaction/UnifiedTransactionScreen.kt @@ -415,11 +415,6 @@ private fun ZcashPcztSimpleContent(req: SignRequest.ZcashPczt) { // Fee val feeZec = "%.8f".format(inspection.netValue / 100_000_000.0) DetailRow(label = "Fee", value = "$feeZec ZEC") - - // Warnings - if (!inspection.anchorMatches) { - WarningCard("Anchor mismatch — the transaction may reference an outdated state.") - } } // ============================================================================= diff --git a/android/src/main/java/net/rotko/zigner/screens/scan/transaction/ZcashPcztScreen.kt b/android/src/main/java/net/rotko/zigner/screens/scan/transaction/ZcashPcztScreen.kt index 052bd0f06f..5012a24d9f 100644 --- a/android/src/main/java/net/rotko/zigner/screens/scan/transaction/ZcashPcztScreen.kt +++ b/android/src/main/java/net/rotko/zigner/screens/scan/transaction/ZcashPcztScreen.kt @@ -120,8 +120,12 @@ fun ZcashPcztScreen( .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(12.dp) ) { - // Anchor verification - AnchorCard(insp) + // Verified-notes context (known-spends ratio + local balance). + // Anchor is intentionally not displayed or validated — + // Keystone doesn't and equality-checking against our local + // anchor was the rotko-invented gate behind the constant + // "re-sync first" friction. + VerificationCard(insp) // Spends if (insp.spends.isNotEmpty()) { @@ -177,9 +181,6 @@ fun ZcashPcztScreen( } // Warnings - if (!insp.anchorMatches) { - WarningCard("Anchor does not match verified state. Transaction may reference a different chain state.") - } if (insp.knownSpends < insp.actionCount) { WarningCard("${insp.actionCount - insp.knownSpends} spend(s) not in verified notes. These may be unknown or dummy actions.") } @@ -271,7 +272,7 @@ fun ZcashPcztScreen( } @Composable -private fun AnchorCard(insp: ZcashPcztInspection) { +private fun VerificationCard(insp: ZcashPcztInspection) { Column( modifier = Modifier .fillMaxWidth() @@ -280,17 +281,6 @@ private fun AnchorCard(insp: ZcashPcztInspection) { .padding(16.dp), verticalArrangement = Arrangement.spacedBy(4.dp) ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text("Anchor", style = SignerTypeface.LabelM, color = MaterialTheme.colors.textTertiary) - Text( - text = if (insp.anchorMatches) "matches" else "MISMATCH", - style = SignerTypeface.LabelM, - color = if (insp.anchorMatches) MaterialTheme.colors.primary else MaterialTheme.colors.red500 - ) - } Text( text = "${insp.knownSpends}/${insp.actionCount} spends verified", style = SignerTypeface.CaptionM, diff --git a/ios/PolkadotVault/Screens/Scan/Zcash/ZcashPcztView.swift b/ios/PolkadotVault/Screens/Scan/Zcash/ZcashPcztView.swift index 15c562a4f0..824d2a6f4e 100644 --- a/ios/PolkadotVault/Screens/Scan/Zcash/ZcashPcztView.swift +++ b/ios/PolkadotVault/Screens/Scan/Zcash/ZcashPcztView.swift @@ -54,7 +54,7 @@ struct ZcashPcztView: View { ScrollView { VStack(alignment: .leading, spacing: Spacing.small) { // Anchor status - anchorCard(inspection: inspection) + verificationCard(inspection: inspection) // Spends if !inspection.spends.isEmpty { @@ -108,9 +108,6 @@ struct ZcashPcztView: View { } // Warnings - if !inspection.anchorMatches { - warningCard("Anchor does not match verified state. Transaction may reference a different chain state.") - } if inspection.knownSpends < inspection.actionCount { warningCard("\(inspection.actionCount - inspection.knownSpends) spend(s) not in verified notes.") } @@ -188,17 +185,8 @@ struct ZcashPcztView: View { // MARK: - Card Components - private func anchorCard(inspection: ZcashPcztInspection) -> some View { + private func verificationCard(inspection: ZcashPcztInspection) -> some View { VStack(alignment: .leading, spacing: Spacing.extraSmall) { - HStack { - Text("Anchor") - .font(PrimaryFont.labelM.font) - .foregroundColor(.textAndIconsTertiary) - Spacer() - Text(inspection.anchorMatches ? "matches" : "MISMATCH") - .font(PrimaryFont.labelM.font) - .foregroundColor(inspection.anchorMatches ? .textAndIconsPrimary : .accentRed300) - } Text("\(inspection.knownSpends)/\(inspection.actionCount) spends verified") .font(PrimaryFont.captionM.font) .foregroundColor(inspection.knownSpends == inspection.actionCount ? .textAndIconsSecondary : .accentRed300) @@ -206,7 +194,7 @@ struct ZcashPcztView: View { Text(String(format: "Verified balance: %.8f ZEC", balZec)) .font(PrimaryFont.captionM.font) .foregroundColor(.textAndIconsSecondary) - } +} .frame(maxWidth: .infinity, alignment: .leading) .padding(Spacing.medium) .containerBackground() diff --git a/rust/definitions/src/navigation.rs b/rust/definitions/src/navigation.rs index b7fbfb8bc5..3f4fe2b784 100644 --- a/rust/definitions/src/navigation.rs +++ b/rust/definitions/src/navigation.rs @@ -1084,10 +1084,8 @@ pub struct ZcashPcztInspection { pub spends: Vec, pub outputs: Vec, pub net_value: i64, - pub anchor_matches: bool, pub verified_balance: u64, pub known_spends: u32, - pub anchor_hex: String, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/rust/signer/src/lib.rs b/rust/signer/src/lib.rs index 063317b705..ff127e80b9 100644 --- a/rust/signer/src/lib.rs +++ b/rust/signer/src/lib.rs @@ -1970,17 +1970,28 @@ fn inspect_zcash_pczt(pczt_bytes: Vec) -> Result = notes .iter() @@ -1991,23 +2002,17 @@ fn inspect_zcash_pczt(pczt_bytes: Vec) -> Result) -> Result) -> Result 0 { return Err(ErrorDisplayed::Str { s: "No PCZT spend nullifiers match verified notes. This transaction may spend notes you don't recognize.".to_string(), diff --git a/rust/signer/src/signer.udl b/rust/signer/src/signer.udl index ff4983bc69..14c41268ce 100644 --- a/rust/signer/src/signer.udl +++ b/rust/signer/src/signer.udl @@ -1496,7 +1496,10 @@ dictionary ZcashSignContext { boolean has_notes; }; -// PCZT inspection result for display before signing +// PCZT inspection result for display before signing. +// Anchor is intentionally not validated — matches the Keystone signing model +// (PCZT is ground truth; signature happens after user review of +// recipient + amount + fee). dictionary ZcashPcztInspection { u32 action_count; // spends: list of (value_zatoshis, nullifier_is_known) pairs @@ -1505,13 +1508,10 @@ dictionary ZcashPcztInspection { sequence outputs; // net value (spends - outputs) in zatoshis = fee i64 net_value; - // anchor matches our verified anchor? - boolean anchor_matches; // our verified balance (0 if no notes stored) u64 verified_balance; // how many spend nullifiers match our verified notes u32 known_spends; - string anchor_hex; }; dictionary ZcashPcztSpend {