Skip to content

SAC transfer transactions without RPC#861

Merged
Ryang-21 merged 9 commits intomasterfrom
sac-transfer
Feb 20, 2026
Merged

SAC transfer transactions without RPC#861
Ryang-21 merged 9 commits intomasterfrom
sac-transfer

Conversation

@Ryang-21
Copy link
Contributor

Why

Users have requested a way to build SAC transfer transactions without the need to rely on an RPC. This would allow for lightweight clients to be built.

What

  • Implements TransactionBuilder.addSacTransferOperation that constructs the transfer operation with the appropriate authorization and ledger footprint.
  • TransactionBuilder.build now includes resourceFee if it contains sorobanData

@github-actions
Copy link

github-actions bot commented Feb 19, 2026

Size Change: +51 kB (+1.47%)

Total Size: 3.52 MB

Filename Size Change
dist/stellar-base.js 2.6 MB +37.4 kB (+1.46%)
dist/stellar-base.min.js 920 kB +13.6 kB (+1.51%)

compressed-size-action

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 implements a new addSacTransferOperation method on TransactionBuilder that allows constructing SAC (Stellar Asset Contract) transfer transactions without requiring RPC simulation. The implementation handles the creation of authorization entries and ledger footprints based on the asset type and destination type. Additionally, the PR fixes a bug where TransactionBuilder.build() was not including the resource fee in the total transaction fee for Soroban transactions.

Changes:

  • Added addSacTransferOperation method to construct SAC transfer operations with appropriate auth entries and footprints for different asset/destination combinations
  • Fixed TransactionBuilder.build() to include resource fees in the total transaction fee when sorobanData is present
  • Refactored fee-bump transaction logic to correctly calculate inclusion fees by subtracting resource fees

Reviewed changes

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

File Description
types/index.d.ts Added TypeScript definitions for SorobanFees interface and addSacTransferOperation method signature
src/transaction_builder.js Implemented addSacTransferOperation with footprint construction logic and fixed fee calculation in build() method
test/unit/transaction_builder_test.js Added comprehensive tests for different asset/destination combinations and edge cases; updated existing fee-bump test expectations
CHANGELOG.md Documented the new feature and bug fix

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

import { SignerKey } from './signerkey';
import { Memo } from './memo';
// eslint-disable-next-line no-unused-vars
import { Asset } from './asset';
Copy link
Contributor

Choose a reason for hiding this comment

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

Is ESLint complaining that we only use this import in the doc portion?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah the ESLint rules does not know that its being used for the jsdoc

Comment on lines +740 to +748
instructions: sorobanFees
? sorobanFees.instructions
: defaultPaymentFees.instructions,
diskReadBytes: sorobanFees
? sorobanFees.readBytes
: defaultPaymentFees.readBytes,
writeBytes: sorobanFees
? sorobanFees.writeBytes
: defaultPaymentFees.writeBytes
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it OK to have 0 for these?

}),
ext: new xdr.SorobanTransactionDataExt(0),
resourceFee: new xdr.Int64(
sorobanFees ? sorobanFees.resourceFee : defaultPaymentFees.resourceFee
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

);
});

it('credit asset + source is issuer: omits source trustline', function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

We could group tests in a nested describe block to make it clear they are related and reuse variables.

@quietbits quietbits linked an issue Feb 20, 2026 that may be closed by this pull request
@Ryang-21 Ryang-21 merged commit c319d2e into master Feb 20, 2026
8 checks passed
@Ryang-21 Ryang-21 deleted the sac-transfer branch February 20, 2026 19:34
Comment on lines +658 to +662
const args = [
nativeToScVal(source, { type: 'address' }),
nativeToScVal(destination, { type: 'address' }),
nativeToScVal(amount, { type: 'i128' })
];
Copy link
Contributor

Choose a reason for hiding this comment

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

You can combine these 😉

Suggested change
const args = [
nativeToScVal(source, { type: 'address' }),
nativeToScVal(destination, { type: 'address' }),
nativeToScVal(amount, { type: 'i128' })
];
const args = nativeToScVal([source, destination, amount], {
type: ['address', 'address', 'i128' ]
}).vec();

})
});

const footprint = new xdr.LedgerFootprint({
Copy link
Contributor

Choose a reason for hiding this comment

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

you can/should use Contract.getFootprint for this one for brevity

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.

Add a way to build SAC payments without transaction simulation

4 participants