Skip to content

Commit 082e577

Browse files
abbys-code-hubAbigail Adeboga
andauthored
docs: Stellar fees guide (#59)
* docs: add stellar fee estimation and budgeting guide * chore: commit package-lock.json * remove package-lock.jsno --------- Co-authored-by: Abigail Adeboga <adebogaabigail@gmail.com>
1 parent 450e90a commit 082e577

4 files changed

Lines changed: 180 additions & 7 deletions

File tree

docs.json

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,9 @@
117117
"guides/multichain-agent",
118118
"guides/bring-your-own-model",
119119
"guides/privacy-best-practices",
120-
"guides/stellar-wallet-integration"
121-
]
122-
},
123-
{
124-
"group": "Operations",
125-
"pages": [
126-
"guides/stellar-mainnet-deployment"
120+
"guides/stellar-fees",
121+
"guides/stellar-troubleshooting",
122+
"guides/spectre-stellar-cookbook"
127123
]
128124
},
129125
{

getting-started.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ try {
149149
- [Single-Chain Agent Guide](guides/single-chain-agent) — deeper walkthrough
150150
- [Multichain Agent Guide](guides/multichain-agent) — deploy across multiple chains
151151
- [Bring Your Own Model](guides/bring-your-own-model) — use OpenAI or Claude instead of Gemini
152+
- [Stellar Fee Estimation & Budgeting](guides/stellar-fees) — learn about inclusion fees, Soroban resource fees, and fee bumps
152153
- [Stellar React Hooks](sdk/stellar-react-hooks) — React hooks for Stellar stealth address operations
153154
- [Stellar Troubleshooting](guides/stellar-troubleshooting) — fixes for common Stellar, Soroban, and Stealth errors
154155
- [SDK Reference](sdk/agent-client) — full API documentation

guides/stellar-fees.mdx

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: "Stellar Fee Estimation & Budgeting"
3+
description: "A comprehensive guide to Stellar classic operation fees, Soroban resource fees, fee-bump transaction sponsorship, and budgeting heuristics for Wraith applications."
4+
---
5+
6+
Predictable budgeting on Stellar requires understanding both its classic payment fees and its multi-dimensional Soroban resource pricing. This guide explains how fees are calculated, outlines typical baseline costs for Wraith smart contract operations, and details how to estimate and budget for production-ready applications.
7+
8+
---
9+
10+
## The Stellar Fee Model
11+
12+
Stellar uses a hybrid fee structure consisting of two distinct layers: **Inclusion Fees** (classic operation fees) and **Resource Fees** (Soroban-specific execution and storage fees).
13+
14+
### 1. Classic Operation Fees
15+
16+
For non-Soroban operations (such as native XLM payments or creating accounts) and as a baseline inclusion fee for all transactions, Stellar charges a base fee per operation:
17+
* **Base Fee**: Defined by the network (currently `100 stroops` or `0.00001 XLM` per operation; $1 \text{ XLM} = 10,000,000 \text{ stroops}$).
18+
* **Formula**: $\text{Inclusion Fee} = \text{Base Fee} \times \text{Operation Count}$
19+
* **Payment**: Deducted from the transaction source account's balance.
20+
21+
### 2. Soroban Resource Fees
22+
23+
Soroban smart contracts introduce multi-dimensional resource metering to prevent execution bottlenecks. Instead of a single gas price, Soroban tracks resource usage across several distinct dimensions:
24+
25+
* **CPU Instructions**: Modeled CPU instructions executed by the WebAssembly (Wasm) runtime.
26+
* **Memory Bytes**: Peak RAM utilized during transaction execution.
27+
* **Ledger Read Entries**: The number of distinct ledger entries read from the database.
28+
* **Ledger Write Entries**: The number of distinct ledger entries created or modified.
29+
* **Ledger Read Bytes**: The total serialized size in bytes of all ledger entries read.
30+
* **Ledger Write Bytes**: The total serialized size in bytes of all ledger entries written.
31+
* **Event Bytes**: The serialized size of contract events emitted during execution.
32+
33+
Soroban uses these metrics to compute a fee in stroops based on current network parameters.
34+
35+
<Info>
36+
Transactions containing Soroban contract invocations must submit an inclusion fee *plus* the calculated Soroban resource fee.
37+
</Info>
38+
39+
---
40+
41+
## Network Surge Pricing & Congestion
42+
43+
During high-traffic periods, if the network capacity is exceeded, Stellar enters **surge pricing**:
44+
* **Classic Surge**: Transactions are prioritized based on their `fee` (inclusion fee bidding). Transactions with higher inclusion fees are processed first.
45+
* **Soroban Surge**: Soroban enforces separate per-ledger resource limits (e.g., maximum instructions or write bytes per ledger). If a transaction's resource demands exceed limits, or if resource contention occurs, transactions undergo a resource fee auction.
46+
* **Mitigation**: Production applications should dynamically adjust the base fee bid multiplier during periods of high congestion.
47+
48+
---
49+
50+
## Fee-Bump Transactions & Sponsorship
51+
52+
UX is critical for privacy applications. To spare users from having to hold native XLM to pay for stealth transaction fees, developers can use **Fee-Bump Transactions**:
53+
54+
* **Mechanics**: A fee-bump transaction wraps an inner transaction. The outer fee-bump envelope is signed by a sponsor (the fee-bump payer), while the inner transaction is signed by the user.
55+
* **Who Pays**: The sponsor paying the fee-bump pays the entire transaction fee (including both the inclusion fee and any Soroban resource fees).
56+
* **Stealth Use Case**: This allows users with a newly derived stealth address (which contains no XLM) to spend their incoming stealth tokens immediately, sponsored by a relayer. The relayer can recoup the fee in tokens off-chain or via a deduction in the transfer payload.
57+
58+
---
59+
60+
## Per-Wraith-Operation Resource Baselines
61+
62+
Below are the audited, post-optimization resource baselines for the Wraith smart contract suite on Stellar. These numbers are captured from the standard benchmark tests (`stellar/bench` running in `soroban-sdk = 22.0.0` environment).
63+
64+
| Contract | Function / Entry Point | Parameters | CPU Instructions | Memory (RAM) | Read Entries | Write Entries | Read Bytes | Write Bytes | Event Bytes |
65+
|---|---|---|---:|---:|---:|---:|---:|---:|---:|
66+
| **stealth-announcer** | `announce` | `metadata_len=32` | 15,458 | 1,666 B | 1 | 0 | 104 B | 0 B | 248 B |
67+
| **stealth-registry** | `register_keys` | First-time | 33,345 | 4,461 B | 1 | 2 | 104 B | 332 B | 188 B |
68+
| **stealth-sender** | `send` | Asset: XLM | 182,403 | 28,137 B | 5 | 3 | 1,068 B | 520 B | 484 B |
69+
| **stealth-sender** | `batch_send` | Batch size: 5 | 807,519 | 120,229 B | 5 | 7 | 1,068 B | 1,416 B | 2,420 B |
70+
| **stealth-sender** | `batch_send` | Batch size: 10 | 1,633,634 | 245,649 B | 5 | 12 | 1,068 B | 2,536 B | 4,840 B |
71+
| **wraith-names** | `register` | `name_len=3` | 59,792 | 6,240 B | 1 | 2 | 104 B | 516 B | 204 B |
72+
| **wraith-names** | `resolve` | Hit | 46,096 | 5,456 B | 1 | 0 | 452 B | 0 B | 0 B |
73+
| **wraith-names** | `name_of` | Hit | 47,042 | 5,383 B | 1 | 0 | 452 B | 0 B | 0 B |
74+
75+
### Storage Rent Costs
76+
77+
Soroban contracts pay rent for persistent ledger entries based on their serialized size.
78+
* **Sizes**: A registered stealth meta-address costs ~176 bytes. A name mapping costs ~224 bytes, and its reverse lookup maps to ~136 bytes.
79+
* **Protocol 23 Low-Fee Model**: At `fee_write_1kb = 3,500 stroops` and `persistentRentRateDenominator = 1,402`, the annual storage rate is **~0.001538 XLM per byte**.
80+
* **Impact**: Registering a name (mapping + reverse) totals 360 bytes of storage, costing approximately **0.00055 XLM per year** in storage rent.
81+
82+
---
83+
84+
## Worked Cost Scenarios
85+
86+
These examples demonstrate how specific workflows translate to real-world costs on the Stellar network (assuming typical testnet parameters).
87+
88+
### Scenario A: Sending a Stealth Payment
89+
90+
A user sends a payment to a recipient's stealth address. This requires a classic `createAccount` operation (or `payment` for pre-existing accounts) and a Soroban invocation of `stealth-sender::send` to emit the stealth announcement event.
91+
92+
* **Inclusion Fees**: 2 operations (create account + contract invoke) = `200 stroops`.
93+
* **Soroban Resource Fees**: ~35,000 stroops (based on 182,403 instructions, 5 reads, and 3 writes).
94+
* **Total Cost**: **~35,200 stroops (~0.00352 XLM)**.
95+
96+
### Scenario B: Withdrawing Stealth Funds
97+
98+
A recipient checks for incoming payments, matches their view tags, and withdraws the balance to their hot wallet. Because the stealth address is a standard keypair, the withdrawal is a simple, classic payment transaction.
99+
100+
* **Operations**: 1 payment operation.
101+
* **Soroban Invocations**: None (pure classic transaction).
102+
* **Total Cost**: **100 stroops (0.00001 XLM)**.
103+
104+
### Scenario C: Batch Sending (10 Recipients)
105+
106+
An application distributes payroll to 10 stealth addresses. Calling `stealth-sender::batch_send` processes the payments atomically and groups event announcements.
107+
108+
* **Inclusion Fees**: 11 operations (10 payments/creates + 1 contract invoke) = `1,100 stroops`.
109+
* **Soroban Resource Fees**: ~110,000 stroops (based on 1,633,634 instructions and 12 write entries).
110+
* **Total Cost**: **~111,100 stroops (~0.01111 XLM)**.
111+
* **Savings**: Batching reduces CPU instructions and read entries significantly, saving over **60%** in fees compared to 10 separate transactions.
112+
113+
---
114+
115+
## SDK Fee Estimation Helper
116+
117+
The `@stellar/stellar-sdk` library provides the `prepareTransaction` helper to simulate contract invocations and automatically calculate the necessary Soroban resource budgets and transaction fees.
118+
119+
```typescript
120+
import { Account, TransactionBuilder, rpc, Operation } from "@stellar/stellar-sdk";
121+
122+
// Initialize Soroban RPC Server
123+
const rpcServer = new rpc.Server("https://soroban-testnet.stellar.org");
124+
125+
async function estimateFees(sourcePublicKey: string, contractId: string) {
126+
// 1. Fetch account sequence number
127+
const account = await rpcServer.getAccount(sourcePublicKey);
128+
129+
// 2. Build the preliminary transaction
130+
const tx = new TransactionBuilder(account, {
131+
fee: "100", // Start with network minimum base fee
132+
networkPassphrase: "Test SDF Network ; September 2015",
133+
})
134+
.addOperation(
135+
Operation.invokeContractFunction({
136+
contract: contractId,
137+
function: "announce",
138+
args: [], // Add arguments as XDR ScVal structures
139+
})
140+
)
141+
.build();
142+
143+
// 3. Simulate and prepare transaction
144+
console.log("Simulating transaction on-chain...");
145+
const preparedTx = await rpcServer.prepareTransaction(tx);
146+
147+
// 4. Extract calculated fee components
148+
const totalFee = preparedTx.fee; // Combined inclusion + resource fee (in stroops)
149+
const resourceFee = preparedTx.sorobanData.resources().fee().toString();
150+
const inclusionFee = (BigInt(totalFee) - BigInt(resourceFee)).toString();
151+
152+
console.log(`Inclusion Fee: ${inclusionFee} stroops (${Number(inclusionFee) / 1e7} XLM)`);
153+
console.log(`Resource Fee: ${resourceFee} stroops (${Number(resourceFee) / 1e7} XLM)`);
154+
console.log(`Total Fee: ${totalFee} stroops (${Number(totalFee) / 1e7} XLM)`);
155+
156+
return preparedTx;
157+
}
158+
```
159+
160+
---
161+
162+
## Budgeting Heuristics for Production
163+
164+
To ensure smooth operations in production apps, implement these heuristics:
165+
166+
1. **Keep a 5 XLM Fee Buffer**: Newly derived stealth accounts should keep a tiny amount of XLM (typically 5 XLM) reserved for fee bids and the minimum ledger reserve (1 XLM base account reserve + 0.5 XLM per sub-entry or trustline).
167+
2. **Prioritize Batching**: Always batch transfers when sending payments to multiple recipients. Calling `batch_send` reduces transaction fee costs and cuts ledger read overhead.
168+
3. **Set a Surge Pricing Margin**: In production, configure your fee estimator to add a margin (e.g., 20% to 50%) to the suggested base fee during network congestion to prevent transactions from getting stuck in the transaction queue.
169+
4. **Account for Rent Renewal**: For stateful registries, monitor the Time-to-Live (TTL) of storage entries. Implement automated routines to call the `extend_ttl` endpoint on contracts to prevent crucial records (like registrant meta-addresses) from being archived.

sdk/chains/stellar.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,13 @@ This replaces the need to manually query `sorobanServer.getEvents()` and parse X
429429

430430
---
431431

432+
## Troubleshooting & Fees
433+
434+
If you encounter errors while building with Stellar primitives (like `tx_bad_seq`, `op_no_trust`, or stealth-specific errors), see the [Stellar Troubleshooting Guide](/guides/stellar-troubleshooting) for common causes and code fixes.
435+
436+
For detailed fee calculations, baseline resource metrics, and budgeting advice for Soroban smart contracts, see:
437+
- [Stellar Fee Estimation & Budgeting](/guides/stellar-fees) — learn about inclusion fees, Soroban resource fees, and fee bumps
438+
- [Stellar Offline Transaction Signing](/guides/stellar-offline-signing) — build online, sign air-gapped, submit without the private key touching the internet
432439
## See Also
433440

434441
- [Stellar React Hooks](/sdk/stellar-react-hooks) — React hooks for stealth address operations

0 commit comments

Comments
 (0)