fix(visualsign): always emit Condensed/Expanded in preview_layout (PRS-548)#403
Open
pepe-anchor wants to merge 1 commit into
Open
fix(visualsign): always emit Condensed/Expanded in preview_layout (PRS-548)#403pepe-anchor wants to merge 1 commit into
pepe-anchor wants to merge 1 commit into
Conversation
…S-548)
The iOS VSP decoder declares PreviewLayout.condensed and .expanded as
non-optional List. The Ethereum visualizers emitted condensed: None /
expanded: None, and skip_serializing_if dropped those keys from the JSON,
so Swift's synthesized decoder threw keyNotFound and silently degraded
every Ethereum preview_layout (Uniswap Universal Router swaps, Permit2,
ERC-20 previews) to FallbackText. Solana/Sui/Tron already emit both keys,
which is why this was Ethereum-only.
Fix at the serialization layer: SignablePayloadFieldPreviewLayout::serialize
now always emits Condensed and Expanded, defaulting to {"Fields": []} when
unset. One central change covers all chains and is regression-proof. No
content is synthesized (Title/Subtitle still carry the summary), so empty
lists render nothing. The signed digest is computed over the JSON string
and re-signed per request, so no stored hashes break.
Regenerates the affected visualsign-ethereum and parser_cli fixtures.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes an iOS decoding failure by ensuring PreviewLayout JSON always includes Condensed and Expanded, even when the builder leaves them unset, preventing Swift’s synthesized decoder from throwing keyNotFound and falling back to FallbackText.
Changes:
- Updated
SignablePayloadFieldPreviewLayout::serializeto always emitCondensedandExpanded, defaulting to{"Fields":[]}when unset. - Added/updated unit tests to assert key presence and preserve deterministic alphabetical ordering.
- Regenerated Ethereum and parser CLI fixtures to include the newly always-present
Condensed/Expandedkeys.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/visualsign/src/lib.rs | Forces PreviewLayout serialization to always include Condensed and Expanded; adds/updates tests for key presence and ordering. |
| src/parser/cli/tests/fixtures/ethereum-json.display.expected | Updates expected CLI display output to include Condensed/Expanded in PreviewLayout. |
| src/parser/cli/tests/fixtures/ethereum-from-file.display.expected | Updates expected CLI display output to include Condensed/Expanded in PreviewLayout. |
| src/chain_parsers/visualsign-ethereum/tests/fixtures/uniswap-v3swap.expected | Updates expected Ethereum fixture output to include Condensed/Expanded in nested PreviewLayouts. |
| src/chain_parsers/visualsign-ethereum/tests/fixtures/uniswap-v2swap.expected | Updates expected Ethereum fixture output to include Condensed/Expanded in nested PreviewLayouts. |
| src/chain_parsers/visualsign-ethereum/tests/fixtures/json-uniswap-ur-v2_1_1.expected | Updates expected Ethereum JSON fixture output to include Condensed/Expanded. |
| src/chain_parsers/visualsign-ethereum/tests/fixtures/json-eip1559.expected | Updates expected Ethereum JSON fixture output to include Condensed/Expanded. |
| src/chain_parsers/visualsign-ethereum/tests/fixtures/1559.expected | Updates expected Ethereum fixture output to include Condensed/Expanded. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why am I making this PR?
The iOS VSP decoder (
anchor-ios VisualSigningPayload.swift) declaresPreviewLayout.condensedandPreviewLayout.expandedas non-optionalListfields. The Ethereum visualizers were emittingcondensed: None/expanded: None, andskip_serializing_ifwas silently dropping those keys from the JSON. Swift's synthesized decoder threwkeyNotFoundon receipt, degrading every Ethereumpreview_layout(Uniswap Universal Router swaps, Permit2, ERC-20 previews) toFallbackText.This was tracked in Sentry as IOS-646 and is the root cause behind PRS-548. Solana, Sui, and Tron already emit both keys unconditionally, which is why the failure was Ethereum-only.
What am I changing?
src/visualsign/src/lib.rs—SignablePayloadFieldPreviewLayout::serializenow always emitsCondensedandExpanded, defaulting to{"Fields": []}when the builder left either asNone. Removed the now-contradictoryskip_serializing_ifannotations on both fields. This is one central serialization-layer change that covers all chains without touching any chain-specific visualizer.test_preview_layout_always_emits_condensed_and_expanded— a failing-first unit test asserting both keys are always present even whencondensedandexpandedareNone.test_preview_layout_fields_alphabetical_order— the expected key set now includesExpanded(was["Condensed", "Title"], now["Condensed", "Expanded", "Title"]).visualsign-ethereumfixtures (1559,json-eip1559,json-uniswap-ur-v2_1_1,uniswap-v2swap,uniswap-v3swap) and 2parser_clidisplay fixtures (ethereum-from-file,ethereum-json). All fixture diffs are purely additive: onlyCondensedandExpandedkeys are added, no existing content removed or reordered.What is the Linear ticket?
PRS-548 (https://linear.app/anchorlabs/issue/PRS-548)
What are the rollback steps?
Revert the single commit (
fix(visualsign): always emit Condensed/Expanded in preview_layout). This revertssrc/visualsign/src/lib.rsto emitcondensed/expandedonly when set, restoring the prior iOS-decode-failure behavior. No database migrations, no config changes, no deploy coordination required.Is this change backwards compatible?
Yes. The signed digest is computed over the JSON string at request time (
parser/app/routes/parse.rs) and re-signed fresh per request, so changing serialized JSON output breaks no stored hashes. The change is purely additive from a JSON perspective: consumers that already handle the keys see no behavior change; consumers that were failing on missing keys (iOS) now succeed.Does this require cross-team/service coordination?
No. The iOS fix is on the parser side; no anchor-ios change is needed. The parser service is stateless and re-signs per request.
How do I know it works as designed? Which tests exercise this code?
test_preview_layout_always_emits_condensed_and_expanded— new unit test, written failing-first, asserts{"Fields": []}is emitted for both keys when the builder leaves them asNone.preview_layoutnodes across the Ethereum fixture files were verified to carryTitle+Condensed+Expandedafter regeneration.make -C src test— all tests green (pinned toolchain 1.88.0 fromsrc/).cargo fmt --check— clean.cargo clippy --all-targets -- -D warnings— clean.