Introduction
Sponsored transactions allow a sponsor account to pay Stellar transaction fees on behalf of another user. This is essential when working with smart accounts (Soroban contract-based accounts) that cannot pay fees themselves. Using the fee-bump pattern, you can build seamless user experiences where end users never need to hold XLM for gas. This guide walks you through implementing fee-bump deposits and withdrawals with the DeFindex API.Why Are Sponsored Transactions Needed?
Smart Accounts and Transaction Fees
On Stellar, there are two types of accounts:- Native accounts (
G...addresses) — Standard Stellar accounts that hold XLM and can pay transaction fees. They also serve as the source account (sequence number provider) for transactions. - Smart accounts (
C...addresses) — Soroban contract-based accounts. These accounts cannot be the source account of a transaction and cannot pay transaction fees because Stellar requires fees and sequence numbers from a nativeG...account.
When a DeFindex vault is operated by a smart account, the transaction will fail if no one covers the fee.
- Source = always a native
G...account (provides the sequence number). In a fee-bump transaction, the sponsor pays the fee, not the source account.- Caller (from) = can be
G...orC...(the account that authorizes the vault operation)
The Fee-Bump Solution
Stellar’s fee-bump transaction wraps an existing (inner) transaction with an outer envelope that specifies a different fee-paying account:G... account (which provides the sequence number). The caller signs the inner transaction to authorize the vault operation. The sponsor wraps it in a fee-bump and signs the outer transaction to pay the fee. The network processes both as a single unit.
Prerequisites
@stellar/stellar-sdk^14.3.0- Two Stellar keypairs:
- Sponsor — A native
G...account funded with XLM to pay fees - Caller — The account executing vault operations (can be
G...orC...)
- Sponsor — A native
- DeFindex API key (generate it at the DeFindex Console under API Keys)
Environment Configuration
Create a.env file based on the following template:
Note onCALLER_SECRETand smart accounts:CALLER_SECRETexpects a Stellar secret key (S...) for nativeG...accounts. If the caller is a smart account (C...), authorization comes from wallet interactions (Freighter, xBull, etc.), not a raw private key. In that scenario, present the unsigned XDR to the user’s wallet for signing instead of usingKeypair.fromSecret(...).
Deposit with Fee Bump
Step 1: Initialize API Client and Keypairs
Step 2: Get Unsigned Deposit Transaction
API Reference:POST /vault/{address}/deposit—DepositDto
Step 3: Sign Inner Transaction with Caller
Step 4: Create and Sign Fee-Bump with Sponsor
Step 5: Submit the Transaction
API Reference:POST /send—SendXdrDto
Withdraw with Fee Bump
The withdrawal flow is the same pattern, but first queries the user’s vault balance to determine how much of the underlying assets to withdraw.Step 1: Get Vault Balance
API Reference: GET /vault/{address}/balance
Step 2: Get Unsigned Withdrawal Transaction
API Reference:POST /vault/{address}/withdraw—WithdrawDto
Step 3: Sign, Wrap, and Submit
The signing and fee-bump steps are identical to the deposit flow:Fee Considerations
buildFeeBumpTransactiontakes a per-operation base fee, not a total fee. The SDK internally multiplies by(numOperations + 1)to compute the total fee-bump fee (CAP-0015 rule).- For a typical Soroban transaction with 1 operation, passing
parseInt(transaction.fee)as the base fee produces a total fee-bump fee of2 × innerFee(since1 op + 1 = 2). This satisfies the protocol’s fee-rate check because the per-operation rate equals the inner transaction’s rate. - The DeFindex API builds the inner transaction with a simulated resource fee and a correct inclusion fee. Passing
parseInt(transaction.fee)as the base fee ensures you meet the required minimum. - To increase priority during network congestion, pass a higher base fee:
Common Issues
Production Notes
- Channel accounts for concurrent sponsors: If the sponsor account submits multiple fee-bump transactions in parallel, sequence-number collisions will cause failures. Use channel accounts. a pool of funded
G...accounts — so each concurrent submission uses its own sequence number. - XDR verification before signing: In production, the sponsor should decode and inspect the inner transaction XDR before signing. Verify that the operations, amounts, and destination contracts match expected values. Never blindly sign arbitrary XDRs.