Refactor/rebuild tx expiry for scan#111
Open
wantedsystem wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
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.transactionusing 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.
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.
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:
securityScanRequest.transaction.transactionand itsassertTransactionTimeBoundguard 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
timeBoundsare part of the signed envelope, so rebuilding a dapp-provided transaction would change what the user signs.