Skip to content

Refactor/rebuild tx expiry for scan#111

Open
wantedsystem wants to merge 2 commits into
mainfrom
refactor/rebuild-tx-expiry-for-scan
Open

Refactor/rebuild tx expiry for scan#111
wantedsystem wants to merge 2 commits into
mainfrom
refactor/rebuild-tx-expiry-for-scan

Conversation

@wantedsystem

Copy link
Copy Markdown
Contributor

Summary

While a confirmation dialog stays open, the security scan/simulation runs against the transaction snapshot captured when the dialog opened. As time passes, that envelope approaches its time-bound expiry, and Blockaid simulation/validation can fail on a (near-)expired transaction.

This PR ensures the scan always uses a non-expired transaction:

  • Sequence the refreshers. The transaction refresher now runs first in isolation. Its patch is merged into the context before the remaining refreshers execute, allowing prices and scans to run in parallel against the updated context. As a result, the scan simulates/validates the renewed envelope instead of a stale snapshot.
  • Propagate the rebuilt envelope. The transaction refresher already rebuilds the transaction with a fresh time bound for re-validation. It now also writes that rebuilt XDR into securityScanRequest.transaction.
  • Leave the user-facing transaction untouched. Only the scan request is renewed. The displayed transaction and its assertTransactionTimeBound guard remain unchanged, and the signable envelope is rebuilt again at confirmation time.

Like the TRON wallet (snap-tron-wallet)

This follows the same pattern as the TRON wallet's transaction-expiration refresh: refresh the transaction expiry first → scan the fresh transaction → persist it to context → reschedule.

We also ported TRON's freshness gate (hasFreshExpiration). The scanned envelope is kept as-is while it still has sufficient time before expiry and is only replaced with a freshly rebuilt one once it enters a refresh buffer. This keeps scans stable on a single envelope instead of switching to a new one every cycle.

One intentional difference from TRON is that its freshness check can skip a network round-trip when the transaction is still fresh. Here, the createValidated* rebuild runs on every cycle because it also performs balance, sequence, and fee re-validation. The freshness gate therefore provides scan-envelope stability, not rebuild avoidance.

Scope

  • Send and change-trust flows (which run both the transaction and scan refreshers).
  • Dapp sign-transaction remains unchanged. Stellar timeBounds are part of the signed envelope, so rebuilding a dapp-provided transaction would change what the user signs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the confirmation-context refresh pipeline so Blockaid security scan/simulation runs against a transaction envelope that won’t expire while the confirmation dialog remains open. It does this by rebuilding the transaction first, propagating the rebuilt XDR into the scan request (with a freshness gate to avoid needless churn), and ensuring downstream refreshers see that updated context in the same cycle.

Changes:

  • Rebuild and validate the pending transaction each cycle, and (when needed) write the rebuilt envelope XDR into securityScanRequest.transaction using an expiry “freshness” buffer.
  • Update the refresh orchestrator so the transaction refresher runs first (isolated), merges its patch into context, then runs remaining refreshers in parallel with rejection isolation.
  • Add/extend unit tests covering scan-transaction renewal behavior and the new refresher ordering behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/snap/src/handlers/cronjob/refreshConfirmationContext/transactionRefresher.ts Adds scan-envelope renewal + freshness gate; propagates rebuilt XDR into the security scan request.
packages/snap/src/handlers/cronjob/refreshConfirmationContext/transactionRefresher.test.ts Adds tests for renewing/keeping scan XDR based on expiry buffer and parseability.
packages/snap/src/handlers/cronjob/refreshConfirmationContext/handler.ts Sequences transaction refresher first, merges its patch into context, then runs remaining refreshers in parallel with safe settlement.
packages/snap/src/handlers/cronjob/refreshConfirmationContext/handler.test.ts Adds a test asserting transaction refresher runs first and its patch is visible to subsequent refreshers.
packages/snap/snap.manifest.json Updates bundle shasum to match the new build output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants