Skip to content

Add clear-signing guard + direct Uniswap V3 swap path - #33

Closed
szhygulin wants to merge 1 commit into
mainfrom
feat/clear-signing-guard
Closed

Add clear-signing guard + direct Uniswap V3 swap path#33
szhygulin wants to merge 1 commit into
mainfrom
feat/clear-signing-guard

Conversation

@szhygulin

Copy link
Copy Markdown
Collaborator

Summary

  • Trust classifier. Every prepared EVM + TRON tx now carries a trustModeclear-signable (Ledger decodes on-device), blind-sign (swiss-knife.xyz decoder URL supplied), or blind-sign-unavoidable (unknown contract / cross-chain bridge — recommend rejection). A domain-tagged payloadHash fingerprint lets the user cross-reference decoder output against the bytes the Ledger will actually sign, echoed at both prepare-time and send-time.
  • Direct Uniswap V3 swap builder. New buildUniswapV3DirectSwap probes single-hop exactInputSingle and falls back to multi-hop exactInput via WETH, handling native ETH in/out through multicall wrap/unwrap. Selectors are in the Ledger clear-sign set, so routes via this path get hardware-verified on-device instead of blind-signed.
  • Routing policy. prepare_swap runs LiFi and direct-V3 quotes in parallel and prefers direct when its minOut is within 1.0% (L1) or 0.5% (L2s) of LiFi's. Otherwise it falls back to LiFi and surfaces the gap via rejectedAlternative. Cross-chain always goes via LiFi and is stamped blind-sign-unavoidable.

Test plan

  • npx vitest run — 380 / 380 passing, including 3 new suites (clear-sign-guard.test.ts, uniswap-v3-direct.test.ts, swap-routing-policy.test.ts)
  • npx tsc --noEmit — clean
  • Manual: prepare a USDC → WETH same-chain swap on Ethereum mainnet RPC; confirm trustMode === "clear-signable" and the routingDecision is direct-v3
  • Manual: prepare a USDC Ethereum → USDC.e Polygon bridge; confirm blind-sign-unavoidable with a decoderUrl
  • Manual: sign a direct-V3 swap on a real Ledger and confirm human-readable on-device fields (vs LiFi's raw calldata screen)
  • After merge: tag v0.5.0 to ship via the release workflow

Classify every prepared tx as clear-signable / blind-sign /
blind-sign-unavoidable and surface a verification path to the user. A
domain-tagged payload fingerprint ties the decoder result (swiss-knife.xyz)
to the exact bytes the Ledger will sign; blind-sign-unavoidable cases
recommend rejection when the user cannot independently verify the call.

To maximize clear-sign coverage, add a direct Uniswap V3 swap builder
(exactInputSingle + multi-hop via WETH, with native wrap/unwrap through
multicall) and route prepare_swap to it when its minOut is within 1.0% (L1)
or 0.5% (L2s) of LiFi's quote. TRON transactions are unconditionally
classified clear-signable since they go through the TRON Ledger app with
local protobuf verification.
@szhygulin

Copy link
Copy Markdown
Collaborator Author

Closing without merge — the underlying clear-signing vs blind-signing classification turned out to be inaccurate (several commands labeled clear-signable are actually blind-signed on Ledger, and vice versa). Needs a redo from verified sources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant