Add account lock detector, metadata validator, simulation diff comparator, and reconciliation engine - #600
Merged
Kingsman-99 merged 5 commits intoJul 30, 2026
Conversation
|
@CHEF-SAVY Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
6 tasks
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
Implements four Stellar Wave issues, each in its own commit:
src/accountStateDetector.tsaddsdetectLockState()/assertAccountUnlocked(), which read a recipient's trustline (is_authorized,is_authorized_to_maintain_liabilities) and the issuer'sauth_revocable/auth_immutableflags via Horizon to reportAccountLockState.src/preflightChecker.tsgainscheckRecipientsUnlocked(), which calls the detector for each recipient and throwsAccountFrozenError/AccountLockedError(new insrc/errors.ts) before a payment is built.src/validators/invoiceMetadataValidator.tswrapsajv(added as a new dependency) behindInvoiceMetadataValidator, compiled once fromStellarSplitClientConfig.metadataSchema.StellarSplitClientcompiles it in the constructor and callsvalidate()onCreateInvoiceParams.metadata(new optional field) at the top ofcreateInvoice(), throwing the newMetadataValidationErrorwhenmetadataThrowOnInvalid(defaulttrue) and the schema doesn't match.src/simulationDiff.tsaddscompareSimulations(baseline, revised)andformatDiffSummary(diff)alongside the existingdiffSimulations(). ReturnscpuDelta,memDelta(combined read+write byte delta — this SDK'sSorobanDataBuilderresources don't expose a separatememBytes),feeDelta,footprintAdded/footprintRemoved(LedgerKey XDR base64 diffs), andauthChanged.src/reconciliationEngine.tsaddsReconciliationEngine.reconcile(accountId, assetCode, dateRange), which compares an internalPayment[]ledger against actual outgoing payments fetched from Horizon (Server.payments().forAccount()) and returns per-paymentReconciliationFindings (info/warning/critical) plusisBalanced.Implementation notes / deviations from the issue text
The issues described a slightly different codebase state than what's actually on
main; to keep this minimal and avoid inventing new stable-looking APIs, a few call sites were adapted rather than followed literally:updateInvoice()andsrc/recorder.ts'sPaymentRecord[], neither of which exist in this codebase (recorder.tsis an unrelated RPC session recorder, and there is noupdateInvoicemethod — onlyupdateInvoiceStatus). Metadata validation is wired intocreateInvoice()only; the reconciliation engine takes an injectedPayment[](the SDK's actual per-invoice payment ledger) instead.SimulationDiff/ResourceDeltatypes with different fields than the ones already exported bysrc/simulationDiff.tsfor the pre-existingdiffSimulations(). To avoid a breaking rename, the new comparator uses distinct type names (SimulationComparison/SimulationComparisonNotComparable) instead of colliding with the existing exports.profiler.tsintegration was skipped — that module profilesStellarSplitClientmethod timings, not Soroban simulations, so there's nothing there to diff.authorized,authorized_to_maintain_liabilities) don't match the installed@stellar/stellar-sdktypings (is_authorized,is_authorized_to_maintain_liabilities); the implementation uses the actual SDK field names.Verification
npx tsc --noEmit— no new errors (115 pre-existing errors onmain, unchanged after these commits).npx vitest run test/simulationDiff.test.ts test/client.test.ts— 71/71 passing.Closes #532
Closes #533
Closes #534
Closes #535