feat: show estimated balance changes in confirmation dialog#118
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a local, best-effort Stellar simulation path to surface estimated balance changes on the signTransaction confirmation screen, while keeping Blockaid as validation-only and ensuring the UI hides the section when no usable deltas are available.
Changes:
- Seed the confirmation context with locally-derived
estimatedChangesso fund-flow can render immediately, independent of remote scan timing. - Introduce local simulation endpoint diffing + mapping (
SimulationState→TransactionScanEstimatedChanges) and wire it intosignTransaction. - Update the scan refresher to request validation only and to preserve locally-derived
estimatedChangesacross remote refreshes.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.tsx | Renders the new estimated-changes section in the sign-transaction confirmation flow. |
| packages/snap/src/ui/confirmation/controller.tsx | Adds initialScan seeding and gates remote scan scheduling on useSecurityAlerts (validation-only). |
| packages/snap/src/ui/confirmation/components/index.ts | Exposes the new EstimatedChanges component via the components barrel. |
| packages/snap/src/ui/confirmation/components/EstimatedChanges/EstimatedChanges.tsx | New UI component to display send/receive asset deltas. |
| packages/snap/src/ui/confirmation/components/EstimatedChanges/EstimatedChanges.test.tsx | Unit tests for EstimatedChanges rendering/hiding behavior. |
| packages/snap/src/services/transaction/TransactionSimulator.ts | Adds simulateEndpoints and supports operation-source-only simulation via option flag. |
| packages/snap/src/services/transaction/TransactionSimulator.test.ts | Tests simulateEndpoints to ensure fee is excluded from estimated-change delta baseline. |
| packages/snap/src/services/transaction/TransactionService.ts | Adds deriveEstimatedChanges and injects assetMetadataService for SEP-41 metadata mapping. |
| packages/snap/src/services/transaction/TransactionService.test.ts | Tests local estimated-changes derivation across multiple sign-transaction scenarios. |
| packages/snap/src/services/transaction/mapSimulationToEstimatedChanges.ts | New mapper converting simulation snapshot deltas into TransactionScanAssetChange[]. |
| packages/snap/src/services/transaction/mapSimulationToEstimatedChanges.test.ts | Unit tests for native + classic mapping and empty/no-signer scenarios. |
| packages/snap/src/services/transaction/index.ts | Re-exports the new mapper. |
| packages/snap/src/services/transaction/mocks/transaction.fixtures.ts | Updates TransactionService test fixture construction with assetMetadataService. |
| packages/snap/src/handlers/keyring/signTransaction.ts | Computes local estimated changes and seeds them into initialScan for the confirmation dialog. |
| packages/snap/src/handlers/cronjob/refreshConfirmationContext/scanRefresher.ts | Changes refresher behavior to validation-only and preserves local estimatedChanges. |
| packages/snap/src/handlers/cronjob/refreshConfirmationContext/scanRefresher.test.ts | Updates/adds tests for validation-only options and preservation of local changes. |
| packages/snap/src/context.ts | Wires assetMetadataService into TransactionService construction. |
| packages/snap/snap.manifest.json | Updates bundle shasum for the new build output. |
| packages/site/.env.development | Sets SNAP_ORIGIN for local dev site configuration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
stanleyyconsensys
left a comment
There was a problem hiding this comment.
i think the idea is a not align with our dicussion
- sign txn: always use remote simulation
- chg trust / send : always use local simulation
| return { | ||
| assets: [ | ||
| { | ||
| type: 'out', |
There was a problem hiding this comment.
can we have a enum for out
| preferences.useExternalPricingData && | ||
| tokenPrices !== undefined; | ||
|
|
||
| const canUseRemoteSimulation = |
There was a problem hiding this comment.
it looks more clear if we do it via renderOptions
current is
{
loadPrice: true,
scanTxn: true,
validateTxn: true,
},
to (with some renaming)
// Change trust / confirm send
{
loadPrice: true,
securityScanning: true,
localSimulation: true,
remoteSimulation: false
}
// sign txn
{
loadPrice: true,
securityScanning: true,
localSimulation: false,
remoteSimulation: true
},
| const { asset_type: assetType, asset } = assetDiff; | ||
|
|
||
| if ( | ||
| assetType === 'NATIVE' || |
There was a problem hiding this comment.
just question why we need to check assetType and asset.type?
| * @returns The post-fee initial state and the final state after all operations. | ||
| * @throws {TransactionValidationException} When simulation produces no states. | ||
| */ | ||
| simulateEndpoints( |
There was a problem hiding this comment.
this method does not seem useful,
as simulate already give us all the state
| * this scoped to sign-transaction estimated changes; normal validation still | ||
| * requires the wallet account to be the transaction or fee source. | ||
| */ | ||
| allowOperationSourceAccount?: boolean; |
There was a problem hiding this comment.
sign txn is only using security scan, why we need this?
| * @param params.signerAddress - The Stellar address whose changes are surfaced. | ||
| * @returns The estimated changes, or `{ assets: [] }` when they cannot be derived. | ||
| */ | ||
| async deriveEstimatedChanges(params: { |
There was a problem hiding this comment.
again, doesnt we said sign txn is using security scanning?
| // Seed a local estimate so the dialog can render immediately. If Blockaid | ||
| // later returns displayable simulation results, the scan refresher replaces | ||
| // this fallback with the remote estimate. | ||
| const estimatedChanges = await this.#deriveEstimatedChanges( |
There was a problem hiding this comment.
may be we can remove this and let security api to do the work
Summary
EstimatedChangescomponent, aligned with Tron/Solana.EstimatedChanges: skeleton while the scan is in flight, plus explicit “not available” / “no changes” states when appropriate.Notes
assets. Otherwise the locally seeded fallback stays visible.