Skip to content

fix: Fix issues with latest stellar-base version#101

Merged
zeljkoX merged 4 commits intomainfrom
fix-stellar-base-issues
Mar 3, 2026
Merged

fix: Fix issues with latest stellar-base version#101
zeljkoX merged 4 commits intomainfrom
fix-stellar-base-issues

Conversation

@zeljkoX
Copy link
Contributor

@zeljkoX zeljkoX commented Mar 3, 2026

This PR will fix issues with latest stellar-base version.

In the latest version TransactionBuilder.build() now includes resourceFee.

Our logic used assembleTransaction and with latest change it resulted in double addition of resourceFee.

stellar/js-stellar-base#861

Summary by CodeRabbit

  • Bug Fixes

    • Fixed compatibility with the latest stellar-base version for transaction assembly.
    • Enhanced fee calculation logic to ensure transactions always have adequate fees with a safety floor.
    • Improved transaction building to bypass potential assembly failures.
  • Tests

    • Added comprehensive tests for fee and resource fee calculation validation.

Copilot AI review requested due to automatic review settings March 3, 2026 11:40
@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

Walkthrough

The pull request fixes an issue with assembleTransaction when used with the latest stellar-base version by introducing a safety floor for fee calculation and replacing the assembly approach. The fee calculation now ensures max_fee covers inner transaction fees plus inclusion fees. The simulation flow bypasses rpc.assembleTransaction in favor of direct TransactionBuilder construction with explicit sorobanData and authorization injection.

Changes

Cohort / File(s) Summary
Changelog
.changeset/humble-ducks-sin.md
Documents a minor version bump and fix for assembleTransaction compatibility with latest stellar-base.
Fee Calculation
src/plugin/fee.ts, test/fee.test.ts
Adds innerTxFee extraction and enforces a safety floor where max_fee must be at least innerTxFee + inclusionFee; includes debug logging expansion and new test case validating the floor mechanism.
Simulation Assembly
src/plugin/simulation.ts, test/read-only.test.ts
Replaces rpc.assembleTransaction with direct TransactionBuilder construction, adds sorobanData parsing and auth resolution from simulation results, and introduces helper functions and tests validating resource fee handling.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Plugin as Plugin<br/>(simulation.ts)
    participant RPC as Stellar RPC
    participant TB as TransactionBuilder

    rect rgba(200, 100, 100, 0.5)
    Note over Client,TB: Previous Flow (with rpc.assembleTransaction)
    Client->>Plugin: buildWithChannel(tx)
    Plugin->>RPC: simulateTransaction(tx)
    RPC-->>Plugin: simResult (resourceFee, auth, transactionData)
    Plugin->>RPC: assembleTransaction(simResult)
    RPC-->>Plugin: assembled tx
    Plugin-->>Client: transaction
    end

    rect rgba(100, 150, 200, 0.5)
    Note over Client,TB: New Flow (with direct TransactionBuilder)
    Client->>Plugin: buildWithChannel(tx)
    Plugin->>RPC: simulateTransaction(tx)
    RPC-->>Plugin: simResult (resourceFee, auth, sorobanData)
    Plugin->>Plugin: parse sorobanData & resolve auth
    Plugin->>TB: new TransactionBuilder with sorobanData
    TB-->>Plugin: built transaction
    Plugin-->>Client: transaction
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • dylankilkenny
  • tirumerla

Poem

🐰 A bunny hops through fees with care,
No more assembleTransaction despair!
With direct builds and safety floors,
Soroban dances through open doors,
Inner fees protected, auth resolved with flair! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title directly addresses the main change: fixing compatibility issues with the latest stellar-base version. The title is concise, specific, and clearly summarizes the primary objective of the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-stellar-base-issues

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

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 Soroban transaction assembly and fee calculation to avoid double-counting resourceFee introduced by recent @stellar/stellar-sdk changes, and adds regression tests to lock in correct fee behavior.

Changes:

  • Build channel-sourced transactions directly from simulation.transactionData instead of rpc.assembleTransaction() to prevent double-adding resourceFee.
  • Add a safety floor in max-fee calculation so fee-bump max_fee never underpays the inner transaction fee.
  • Extend tests to cover “resource fee added exactly once” and “inner tx fee as floor” scenarios.

Reviewed changes

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

File Description
src/plugin/simulation.ts Switches away from assembleTransaction() and constructs the tx with simulation-derived SorobanTransactionData to avoid double resource-fee addition.
src/plugin/fee.ts Ensures computed fee-bump max_fee is at least the inner transaction fee (plus inclusion fee) when mismatches occur.
test/read-only.test.ts Adds a regression test ensuring inner tx fee equals classic fee + resource fee exactly once.
test/fee.test.ts Adds a test ensuring calculateMaxFee floors to the inner tx fee when computed fee would underpay.

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/plugin/simulation.ts (1)

150-152: ⚠️ Potential issue | 🟠 Major

Auth expiry validation is skipped for simulation-derived auth.

At Line 151 you validate only the input auth, but at Lines 170-175 you may replace it with auth decoded from simResult. That fallback path bypasses validateAuthExpiry, so near-expiry signatures can slip through and fail downstream.

Suggested fix
-  if (simResult.latestLedger) {
-    validateAuthExpiry(auth, simResult.latestLedger, minSignatureExpirationLedgerBuffer);
-  }
+  const resolvedAuth =
+    auth && auth.length > 0
+      ? auth
+      : (simResult.results?.[0]?.auth ?? []).map((a: string) =>
+          xdr.SorobanAuthorizationEntry.fromXDR(a, 'base64')
+        );
+
+  if (simResult.latestLedger !== undefined) {
+    validateAuthExpiry(resolvedAuth, simResult.latestLedger, minSignatureExpirationLedgerBuffer);
+  }
@@
-  const resolvedAuth =
-    auth && auth.length > 0
-      ? auth
-      : (simResult.results?.[0]?.auth ?? []).map((a: string) =>
-          xdr.SorobanAuthorizationEntry.fromXDR(a, 'base64')
-        );

Also applies to: 169-175

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugin/simulation.ts` around lines 150 - 152, The current code validates
only the original auth variable (validateAuthExpiry(auth,
simResult.latestLedger, minSignatureExpirationLedgerBuffer)) but later may
replace auth with the simulation-decoded auth from simResult, so the fallback
path skips expiry validation; update the flow to validate the effective auth
after any replacement: after you set or decode auth from simResult (referencing
simResult and the variable auth/decoded auth), call
validateAuthExpiry(effectiveAuth, simResult.latestLedger,
minSignatureExpirationLedgerBuffer) so the auth used downstream is always
checked against simResult.latestLedger and minSignatureExpirationLedgerBuffer.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/plugin/simulation.ts`:
- Around line 167-174: Several parsing/assembly calls
(xdr.SorobanTransactionData.fromXDR when creating sorobanData,
xdr.SorobanAuthorizationEntry.fromXDR when building resolvedAuth, and the
TransactionBuilder(...).build() sequence) are running outside a try/catch so
decoding errors escape instead of returning a pluginError with code
ASSEMBLY_FAILED; wrap the entire assembly/parsing block that produces
sorobanData, resolvedAuth and the TransactionBuilder(...).build() call in a
try/catch, catch any exception, normalize it into the plugin error envelope with
code "ASSEMBLY_FAILED" and a clear message, and return/throw that pluginError
instead of letting raw exceptions propagate.

---

Outside diff comments:
In `@src/plugin/simulation.ts`:
- Around line 150-152: The current code validates only the original auth
variable (validateAuthExpiry(auth, simResult.latestLedger,
minSignatureExpirationLedgerBuffer)) but later may replace auth with the
simulation-decoded auth from simResult, so the fallback path skips expiry
validation; update the flow to validate the effective auth after any
replacement: after you set or decode auth from simResult (referencing simResult
and the variable auth/decoded auth), call validateAuthExpiry(effectiveAuth,
simResult.latestLedger, minSignatureExpirationLedgerBuffer) so the auth used
downstream is always checked against simResult.latestLedger and
minSignatureExpirationLedgerBuffer.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0132159 and abb5f35.

📒 Files selected for processing (5)
  • .changeset/humble-ducks-sin.md
  • src/plugin/fee.ts
  • src/plugin/simulation.ts
  • test/fee.test.ts
  • test/read-only.test.ts

Copy link
Contributor

@NicoMolinaOZ NicoMolinaOZ left a comment

Choose a reason for hiding this comment

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

LGTM!

@zeljkoX zeljkoX merged commit 3d3c3e3 into main Mar 3, 2026
11 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

Development

Successfully merging this pull request may close these issues.

3 participants