Skip to content

feat(frontend): implement client-side Soroban transaction simulation sandbox — dry-run before signing, fee breakdown, storage state diff, risk indicators, and pre-sign confirmation modal #1540

Description

@Chibey-max

Overview

Users currently sign transactions blindly — they see the Freighter pop-up but have no understanding of what the transaction will do, what state the contract will be in after it succeeds, or how much it will cost. A simulation sandbox runs the transaction against testnet before the user signs, showing them the exact outcome.

What to build

  • SorobanSimulator service (frontend, lib/soroban-simulator.ts):
    • Accepts a built (unsigned) SorobanTransaction XDR
    • Calls simulateTransaction on the configured Stellar RPC endpoint
    • Parses the SimulateTransactionResponse: resource fee, CPU instructions, memory bytes, read/write ledger entries
    • Returns { success: bool, fee_estimate: { resource_fee, base_fee, total_fee_xlm }, state_diff: LedgerEntryDiff[], error?: string }
  • LedgerEntryDiff — human-readable diff of storage entries that would change:
  • TransactionPreviewModal component (shown before any sign() call):
    • "What this transaction does" description (derived from the method name and decoded arguments)
    • Fee breakdown table: resource fee, base fee, total in XLM and USD (using live rate from full-stack issue)
    • State diff panel: collapsible table of storage changes
    • Risk indicators: warn if transaction writes to more than 10 storage keys (large footprint), or if resource fee exceeds 1 XLM
    • "Sign & Submit" and "Cancel" buttons
  • Wire into: escrow creation, milestone release, dispute filing — every Soroban transaction entry point

Acceptance Criteria

  • Simulation calls use the RPC simulateTransaction endpoint; not submitTransaction
  • Fee is displayed in both XLM (7 decimal places) and USD (2 decimal places via live rate)
  • State diff correctly decodes at least: EscrowState, MilestoneState, u128 amounts
  • Simulation failure (contract error) is shown with a human-readable error message, not raw XDR
  • Modal blocks signing until the user explicitly clicks "Sign & Submit"
  • Cancel discards the unsigned transaction; no state mutation occurs
  • Loading state while simulation is in-flight; spinner + "Simulating transaction..." label
  • Unit tests for SorobanSimulator.parseFee and LedgerEntryDiff decoding with fixture XDR blobs

Technical notes

  • Use @stellar/stellar-sdk rpc.Server.simulateTransaction() for simulation
  • ABI decoding: parse ScVal XDR using the contract's method schema from the registry; unknown types fall back to raw hex display

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions