Skip to content

feat(stellar): implement Soroban pre-flight budget enforcement and DE…#862

Merged
temma02 merged 2 commits into
StellerCraft:mainfrom
whiteghost0001:feature/issues-772-773-soroban-preflight-dex-liquidity
Jun 27, 2026
Merged

feat(stellar): implement Soroban pre-flight budget enforcement and DE…#862
temma02 merged 2 commits into
StellerCraft:mainfrom
whiteghost0001:feature/issues-772-773-soroban-preflight-dex-liquidity

Conversation

@whiteghost0001

Copy link
Copy Markdown
Contributor

Closes #773 — Soroban Contract Execution Budget Enforcement with Pre-Flight Fee Estimation Closes #772 — Stellar DEX Liquidity Aggregation Service with Multi-Hop Route Optimization

=== Issue #773: Soroban Pre-Flight Budget Enforcement ===

Solution — packages/stellar/src/soroban-budget-monitor.ts:
• Introduced BudgetLimits interface (maxCpuInstructions, maxMemoryBytes) with
sensible Protocol-21 defaults (100M CPU instructions, 40 MB memory).
• extractBudgetUsage() reads cost.cpuInsns and cost.memBytes from a successful
SorobanRpc.Api.SimulateTransactionSuccessResponse.
• checkBudget() compares actual usage against configured limits and returns a
BudgetCheckResult that includes the estimated minimum resource fee
(simResult.minResourceFee).

Solution — packages/stellar/src/soroban.ts:
• createRpcServer() creates a SorobanRpc.Server pointed at the configured
SOROBAN_RPC_URL (defaults to soroban-testnet.stellar.org).
• preflightTransaction() runs rpc.simulateTransaction() on the unsigned
transaction, asserts the response is a success (not an error or restore),
calls checkBudget() and throws a descriptive error if any limit is exceeded,
then calls SorobanRpc.assembleTransaction() to stamp the correct resource fee
footprint onto the transaction and returns the ready-to-sign tx together with
the BudgetCheckResult.
• invokeContract() composes the full lifecycle: preflight → sign → sendTransaction
→ poll getTransaction until NOT_FOUND resolves, throwing on FAILED status.
• Both functions accept optional budgetLimits and rpc arguments so they can be
tested with mocks or tightened per-call without changing global state.

=== Issue #772: DEX Liquidity Aggregation with Multi-Hop Route Optimization ===

Problem:
dex-price-feed.ts only fetched spot prices from the DEX order book. There was
no logic to discover optimal swap paths through the Stellar liquidity network,
leaving users with sub-optimal execution on large or illiquid swaps.

Solution — packages/stellar/src/dex-price-feed.ts:
• findBestStrictSendRoutes(sourceAsset, sourceAmount, destinationAsset):
Calls Horizon's strictSendPaths endpoint, which explores all available
liquidity paths (AMM pools + order books) across up to MAX_HOPS (6) hops.
Results are filtered to paths with ≤ 5 intermediate assets (path array
excludes source and destination, so total hops ≤ 6), then sorted descending
by destinationAmount — i.e. the route that gives the most output for your
fixed input is first.
• findBestStrictReceiveRoutes(sourceAsset, destinationAsset, destinationAmount):
Mirror function using strictReceivePaths for fixed-output swaps. Sorted
ascending by sourceAmount (cheapest source cost first).
• getOptimalRoute(): Thin wrapper that returns the single best strict-send route
or null if Horizon finds no path.
• getPrice(): Retained from the original design — fetches the mid-market price
from the order book (average of best ask and best bid).
• assetFromRecord() helper converts Horizon path records (asset_type /
asset_code / asset_issuer) to StellarSdk.Asset instances, handling the
native XLM case.
• All public functions accept an optional server argument for dependency
injection / testing.

=== Supporting files ===

• packages/stellar/src/config.ts — exports STELLAR_NETWORK, HORIZON_URL,
SOROBAN_RPC_URL from env with testnet
defaults.
• packages/stellar/src/service.ts — placeholder module (future Horizon helpers)
• packages/stellar/src/mock.ts — placeholder module (future test mocks)
• packages/stellar/src/index.ts — re-exports all new modules alongside the
existing service/config/mock exports.

…X liquidity aggregation

Closes StellerCraft#773 — Soroban Contract Execution Budget Enforcement with Pre-Flight Fee Estimation
Closes StellerCraft#772 — Stellar DEX Liquidity Aggregation Service with Multi-Hop Route Optimization

=== Issue StellerCraft#773: Soroban Pre-Flight Budget Enforcement ===

Problem:
  Contract invocations in soroban.ts were being broadcast directly to the network
  without first simulating them. This meant there was no way to know ahead of time
  whether a call would exceed the configured CPU instruction or memory budget, and
  no fee estimation was performed before submission.

Solution — packages/stellar/src/soroban-budget-monitor.ts:
  • Introduced BudgetLimits interface (maxCpuInstructions, maxMemoryBytes) with
    sensible Protocol-21 defaults (100M CPU instructions, 40 MB memory).
  • extractBudgetUsage() reads cost.cpuInsns and cost.memBytes from a successful
    SorobanRpc.Api.SimulateTransactionSuccessResponse.
  • checkBudget() compares actual usage against configured limits and returns a
    BudgetCheckResult that includes the estimated minimum resource fee
    (simResult.minResourceFee).

Solution — packages/stellar/src/soroban.ts:
  • createRpcServer() creates a SorobanRpc.Server pointed at the configured
    SOROBAN_RPC_URL (defaults to soroban-testnet.stellar.org).
  • preflightTransaction() runs rpc.simulateTransaction() on the unsigned
    transaction, asserts the response is a success (not an error or restore),
    calls checkBudget() and throws a descriptive error if any limit is exceeded,
    then calls SorobanRpc.assembleTransaction() to stamp the correct resource fee
    footprint onto the transaction and returns the ready-to-sign tx together with
    the BudgetCheckResult.
  • invokeContract() composes the full lifecycle: preflight → sign → sendTransaction
    → poll getTransaction until NOT_FOUND resolves, throwing on FAILED status.
  • Both functions accept optional budgetLimits and rpc arguments so they can be
    tested with mocks or tightened per-call without changing global state.

=== Issue StellerCraft#772: DEX Liquidity Aggregation with Multi-Hop Route Optimization ===

Problem:
  dex-price-feed.ts only fetched spot prices from the DEX order book. There was
  no logic to discover optimal swap paths through the Stellar liquidity network,
  leaving users with sub-optimal execution on large or illiquid swaps.

Solution — packages/stellar/src/dex-price-feed.ts:
  • findBestStrictSendRoutes(sourceAsset, sourceAmount, destinationAsset):
    Calls Horizon's strictSendPaths endpoint, which explores all available
    liquidity paths (AMM pools + order books) across up to MAX_HOPS (6) hops.
    Results are filtered to paths with ≤ 5 intermediate assets (path array
    excludes source and destination, so total hops ≤ 6), then sorted descending
    by destinationAmount — i.e. the route that gives the most output for your
    fixed input is first.
  • findBestStrictReceiveRoutes(sourceAsset, destinationAsset, destinationAmount):
    Mirror function using strictReceivePaths for fixed-output swaps. Sorted
    ascending by sourceAmount (cheapest source cost first).
  • getOptimalRoute(): Thin wrapper that returns the single best strict-send route
    or null if Horizon finds no path.
  • getPrice(): Retained from the original design — fetches the mid-market price
    from the order book (average of best ask and best bid).
  • assetFromRecord() helper converts Horizon path records (asset_type /
    asset_code / asset_issuer) to StellarSdk.Asset instances, handling the
    native XLM case.
  • All public functions accept an optional server argument for dependency
    injection / testing.

=== Supporting files ===

  • packages/stellar/src/config.ts   — exports STELLAR_NETWORK, HORIZON_URL,
                                       SOROBAN_RPC_URL from env with testnet
                                       defaults.
  • packages/stellar/src/service.ts  — placeholder module (future Horizon helpers)
  • packages/stellar/src/mock.ts     — placeholder module (future test mocks)
  • packages/stellar/src/index.ts    — re-exports all new modules alongside the
                                       existing service/config/mock exports.
@drips-wave

drips-wave Bot commented Jun 26, 2026

Copy link
Copy Markdown

@whiteghost0001 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! 🚀

Learn more about application limits

@temma02 temma02 merged commit 1621440 into StellerCraft:main Jun 27, 2026
0 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants