You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/relayer/guides/stellar-sponsored-transactions-guide.mdx
+292-6Lines changed: 292 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,8 @@ Stellar Sponsored Transactions (also known as gasless transactions) allow users
10
10
11
11
1.**Quote**: Estimate the fee cost in your preferred token
12
12
2.**Build**: Prepare a transaction that includes fee payment in the token
13
-
3.**Send**: Sign and submit the transaction (relayer pays XLM fees, user pays token fees)
13
+
3.**Sign**: User signs the transaction including fee payment
14
+
4.**Send**: Submit the transaction (relayer pays XLM fees, user pays token fees)
14
15
15
16
The relayer handles the complexity of fee conversion, token swaps, and XLM fee payment, while users simply pay in their preferred token.
16
17
@@ -69,10 +70,12 @@ First, configure a Stellar relayer in your `config.json`:
69
70
### 2. Policy Configuration Explained
70
71
71
72
#### `fee_payment_strategy`
73
+
72
74
-**`relayer`**: Relayer pays all network fees. Users pay fees in tokens.
73
75
-**`user`**: User must include fee payment in the transaction.
74
76
75
77
#### `allowed_tokens`
78
+
76
79
List of tokens that can be used for fee payment. Each token can have:
77
80
78
81
-**`asset`**: Asset identifier in format `"native"` or `"CODE:ISSUER"` (e.g., `"USDC:GA5Z..."`)
@@ -84,16 +87,19 @@ List of tokens that can be used for fee payment. Each token can have:
84
87
-`retain_min_amount`: Minimum amount to retain after swap
85
88
86
89
#### `swap_config` (Global)
90
+
87
91
Configuration for converting collected tokens back to XLM:
88
92
89
93
-**`strategies`**: DEX strategies to use (currently supports `order-book`)
90
94
-**`cron_schedule`**: Schedule for automatic token swaps (e.g., `"0 */6 * * *"` = every 6 hours)
91
95
-**`min_balance_threshold`**: Minimum XLM balance (in stroops) before triggering swaps
92
96
93
97
#### `slippage_percentage`
98
+
94
99
Default slippage tolerance for token conversions (default: 1.0%)
95
100
96
101
#### `fee_margin_percentage`
102
+
97
103
Additional fee margin added to estimated fees to account for price fluctuations (default: 10.0%)
98
104
99
105
### 3. Enabling Trustlines
@@ -102,10 +108,9 @@ Before users can pay fees in tokens, the relayer account must establish trustlin
102
108
103
109
For a complete example of how to create trustlines, see the [Relayer SDK example](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk/tree/main/examples/relayer/stellar/sponsored/create-trustline.ts).
104
110
105
-
106
111
## Using the API
107
112
108
-
The sponsored transaction flow consists of three steps: **Quote**, **Build**, and **Send**.
113
+
The sponsored transaction flow consists of four steps: **Quote**, **Build**, **Sign**, and **Send**.
109
114
110
115
### Step 1: Get Fee Quote
111
116
@@ -225,7 +230,7 @@ If the user's address is connected with another relayer configured in **relayer
@@ -250,7 +255,7 @@ Submit the signed transaction to the relayer. The relayer will:
250
255
"network": "testnet",
251
256
"fee_bump": true
252
257
}
253
-
```
258
+
````
254
259
255
260
**Response:**
256
261
@@ -303,6 +308,7 @@ When building transactions from operations, use the following format:
303
308
```
304
309
305
310
Supported operation types:
311
+
306
312
-`payment`: Standard payment operation
307
313
-`createAccount`: Account creation
308
314
-`changeTrust`: Trustline management
@@ -330,7 +336,6 @@ Supported operation types:
330
336
-`extendFootprintTtl`: Extend footprint TTL
331
337
-`restoreFootprint`: Restore footprint
332
338
333
-
334
339
## Best Practices
335
340
336
341
1.**Always Quote First**: Get a fee quote before building to show users the expected cost
@@ -341,6 +346,287 @@ Supported operation types:
341
346
6.**Use Fee Margins**: The `fee_margin_percentage` helps account for price fluctuations
342
347
7.**Monitor Trustlines**: Ensure trustlines are established before users attempt transactions
343
348
349
+
## Soroban Gas Abstraction
350
+
351
+
### Overview
352
+
353
+
Soroban Gas Abstraction extends the sponsored transaction concept to Soroban smart contracts. Instead of requiring users to hold XLM for contract invocation fees, users can pay in any Soroban token (e.g., a USDC Soroban token contract). This is powered by a **FeeForwarder smart contract** that wraps the user's contract call with fee collection logic.
354
+
355
+
**How it differs from Classic Stellar Sponsored Transactions:**
356
+
357
+
| Aspect | Classic Stellar | Soroban Gas Abstraction |
|**Authorization**| Standard transaction signing | User signs a `SorobanAuthorizationEntry`|
363
+
|**Submission**| Relayer wraps in fee-bump envelope | Relayer injects signed auth entries and submits directly |
364
+
365
+
### Prerequisites
366
+
367
+
- A running OpenZeppelin Relayer instance
368
+
- A Stellar relayer configured with `"fee_payment_strategy": "user"`
369
+
- A deployed **FeeForwarder contract** on the target network. [Check the OpenZeppelin contract here](https://github.com/OpenZeppelin/stellar-contracts/tree/main/packages/fee-abstraction)
370
+
- The `STELLAR_TESTNET_FEE_FORWARDER_ADDRESS` or `STELLAR_MAINNET_FEE_FORWARDER_ADDRESS` environment variable set to the FeeForwarder contract address
- Sufficient XLM balance in the relayer account for network fees
373
+
374
+
### Configuration
375
+
376
+
Configure the relayer with Soroban token contracts in the `allowed_tokens` list. Note that Soroban tokens use contract addresses (`C...` format) rather than the `CODE:ISSUER` format used for classic Stellar assets.
The Soroban gas abstraction flow uses the same endpoints as classic sponsored transactions but with key differences in the request/response payloads and an additional authorization signing step.
443
+
444
+
#### Step 1: Get Fee Quote
445
+
446
+
Estimate the fee for a Soroban contract invocation in your preferred token.
The `transaction_xdr` should contain the Soroban `InvokeHostFunction` operation, and the `fee_token` should be a Soroban token contract address (`C...` format).
The response includes `max_fee_in_token` and `max_fee_in_token_ui` fields that account for slippage buffer. These represent the maximum amount the user authorizes.
464
+
465
+
```json
466
+
{
467
+
"success": true,
468
+
"data": {
469
+
"fee_in_token_ui": "1.5",
470
+
"fee_in_token": "15000000",
471
+
"conversion_rate": "0.15",
472
+
"max_fee_in_token": "15750000",
473
+
"max_fee_in_token_ui": "1.575"
474
+
}
475
+
}
476
+
```
477
+
478
+
#### Step 2: Build Sponsored Transaction
479
+
480
+
Prepare a Soroban transaction that wraps your contract call with the FeeForwarder contract.
The response includes a `user_auth_entry` field containing the Soroban authorization entry that the user must sign. This authorization entry authorizes the FeeForwarder contract to collect fees in the specified token on the user's behalf.
Unlike classic sponsored transactions where the user signs the full transaction XDR, for Soroban gas abstraction the user must sign the **`user_auth_entry`** returned from the Build response. This is a `SorobanAuthorizationEntry` XDR that authorizes:
517
+
518
+
1. The FeeForwarder contract to transfer fee tokens from the user to the relayer
519
+
2. The user's original contract invocation (wrapped inside the FeeForwarder call)
520
+
521
+
The signing method depends on your setup:
522
+
523
+
-**Programmatic signing**: Use the Stellar SDK to sign the authorization entry with the user's private key
524
+
-**Wallet signing**: Use a Soroban-compatible wallet that supports signing authorization entries
525
+
-**CLI helper tool**: A ready-to-use signing tool is provided in the repository at `helpers/sign_soroban_auth_entry.rs`
526
+
527
+
##### Using the CLI Helper Tool
528
+
529
+
The repository includes a helper tool that signs Soroban authorization entries directly from the command line. This is useful for testing and development:
530
+
531
+
```bash
532
+
cargo run --example sign_soroban_auth_entry -- \
533
+
--secret-key "S..." \
534
+
--auth-entry "<base64 XDR from build response>" \
535
+
--network testnet
536
+
```
537
+
538
+
To generate the full JSON payload ready for the `/transactions` endpoint, include the `--transaction-xdr` flag:
539
+
540
+
```bash
541
+
cargo run --example sign_soroban_auth_entry -- \
542
+
--secret-key "S..." \
543
+
--auth-entry "<base64 XDR from build response>" \
544
+
--network testnet \
545
+
--transaction-xdr "<transaction XDR from build response>"
546
+
```
547
+
548
+
This outputs a JSON object with `network`, `transaction_xdr`, and `signed_auth_entry` fields that can be sent directly to the Submit endpoint.
549
+
550
+
For complete code examples of signing authorization entries and testing the full gas abstraction flow (quote, build, sign, and send), see the [Relayer SDK examples](https://github.com/OpenZeppelin/openzeppelin-relayer-sdk/tree/main/examples/relayers/stellar/src/soroban). The example demonstrates the end-to-end flow including fee estimation, transaction building, authorization signing, and submission.
551
+
552
+
#### Step 4: Submit to Relayer
553
+
554
+
Submit the transaction XDR from the Build response along with the user's **signed authorization entry**. The relayer will:
555
+
556
+
1. Inject the user's signed authorization entry into the transaction
557
+
2. Add the relayer's own authorization entry (as the transaction source account)
558
+
3. Re-simulate the transaction with the signed auth entries for accurate resource calculation
559
+
4. Apply a resource buffer (15% safety margin) to prevent execution failures
This differs from classic sponsored transactions which use the `"CODE:ISSUER"` format. The relayer automatically detects whether to use the classic or Soroban flow based on the `fee_token` format and the presence of `InvokeHostFunction` operations in the transaction XDR.
600
+
601
+
### How the FeeForwarder Contract Works
602
+
603
+
The FeeForwarder contract acts as a proxy that:
604
+
605
+
1.**Collects the fee**: Transfers the fee token amount from the user to the relayer
606
+
2.**Executes the user's call**: Invokes the target contract function on behalf of the user
607
+
3.**Manages authorization**: Bundles fee approval and contract invocation into a single authorization entry
608
+
609
+
The contract's `forward()` function takes these parameters:
610
+
611
+
-`fee_token` - Soroban token contract address for fee payment
612
+
-`fee_amount` - Actual fee to charge
613
+
-`max_fee_amount` - Maximum fee authorized by the user (includes slippage buffer)
614
+
-`expiration_ledger` - Ledger number when the authorization expires
615
+
-`target_contract` - The contract the user wants to invoke
616
+
-`target_fn` - The function name to call
617
+
-`target_args` - The function arguments
618
+
-`user` - The user's account address
619
+
-`relayer` - The relayer's account address (fee recipient)
620
+
621
+
### Best Practices for Soroban Gas Abstraction
622
+
623
+
1.**Use the Quote endpoint first**: Always get a fee estimate before building to show users the expected cost, including the max fee with slippage
624
+
2.**Handle authorization expiration**: Authorization entries expire at a specific ledger. Rebuild if the authorization has expired
625
+
3.**Validate token contract addresses**: Ensure fee tokens use valid Soroban contract addresses (`C...` format, 56 characters)
626
+
4.**Monitor resource fees**: Soroban transactions have dynamic resource fees based on CPU instructions, storage reads/writes, and ledger entry access. The relayer applies a 15% buffer, but complex contract calls may need higher limits
627
+
5.**Set appropriate max fees**: Configure `max_allowed_fee` per token to prevent excessive fees during network congestion
628
+
6.**Configure the FeeForwarder address**: Ensure the correct FeeForwarder contract address is set via environment variables for each network
0 commit comments