Stellar Integration
Overview
OpenZeppelin Relayer provides comprehensive support for Stellar networks, enabling secure transaction relaying, Soroban smart contract operations, and advanced transaction management. This integration supports both standard Stellar operations and the latest Soroban smart contract functionality.
Stellar support is currently under active development. The API interactions and specifics described below may evolve.
Features
- Full Soroban smart contract support (invocation, deployment, WASM uploads)
- Standard Stellar payment operations
- Support for all Stellar operations via XDR transaction submission
- Fee bump transaction support
- Sponsored transactions - Users pay fees in tokens instead of XLM
- Secure transaction signing with multiple signer backends
- Transaction status monitoring and sequence number management
- Custom RPC endpoints and network policies
- Metrics and observability
Supported Networks
Stellar networks are defined via JSON configuration files, providing flexibility to:
- Configure standard Stellar clusters:
mainnet,testnet - Set up custom Stellar-compatible networks with specific RPC endpoints
- Define network passphrases for proper transaction signing
Example Stellar network configurations:
{
"networks": [
{
"type": "stellar",
"network": "mainnet",
"rpc_urls": ["https://mainnet.sorobanrpc.com"],
"explorer_urls": ["https://stellar.expert/explorer/public"],
"average_blocktime_ms": 5000,
"is_testnet": false,
"passphrase": "Public Global Stellar Network ; September 2015"
},
{
"type": "stellar",
"network": "testnet",
"rpc_urls": ["https://soroban-testnet.stellar.org"],
"explorer_urls": ["https://stellar.expert/explorer/testnet"],
"average_blocktime_ms": 5000,
"is_testnet": true,
"passphrase": "Test SDF Network ; September 2015"
}
]
}For detailed network configuration options, see the Network Configuration guide.
Quickstart
For a step-by-step setup, see Quick Start Guide. Key prerequisites:
- Rust 2021, version
1.88or later - Redis
- Docker (optional)
Example configuration for a Stellar relayer:
{
"id": "stellar-example",
"name": "Stellar Example",
"network": "testnet",
"paused": false,
"notification_id": "notification-example",
"signer_id": "local-signer",
"network_type": "stellar"
}For more configuration examples, visit the OpenZeppelin Relayer examples repository.
Configuration
Relayer Policies
Stellar relayers support standard relayer configuration options along with Stellar-specific policies:
| Policy | Type | Default | Description |
|---|---|---|---|
min_balance | integer | None | Minimum balance in stroops (1 XLM = 10,000,000 stroops) required for the relayer account |
max_fee | integer | None | Maximum transaction fee in stroops the relayer is willing to pay |
timeout_seconds | integer | None | Transaction timeout in seconds |
concurrent_transactions | boolean | false | Enable concurrent transaction processing. When enabled, bypasses the lane gating mechanism that normally ensures sequential processing for each relayer. Only enable this when your relayer manages transactions from multiple accounts with independent sequence number pools. |
fee_payment_strategy | string | None | Fee payment strategy: user enables sponsored transactions (users pay fees in tokens), relayer means relayer pays all fees in XLM |
allowed_tokens | array | None | List of tokens allowed for fee payments in sponsored transactions. Each token includes asset, max_allowed_fee (optional), and metadata (optional) |
fee_margin_percentage | float | None | Fee margin percentage applied when converting XLM fees to token amounts for sponsored transactions |
slippage_percentage | float | None | Maximum slippage percentage allowed when swapping tokens via DEX for sponsored transactions |
swap_config | object | None | DEX swap configuration for automated token swaps to keep relayer funded. See Swap Configuration below for details |
Example configuration with policies:
{
"id": "stellar-example",
"name": "Stellar Example",
"network": "testnet",
"paused": false,
"network_type": "stellar",
"signer_id": "local-signer",
"policies": {
"fee_payment_strategy": "relayer",
"min_balance": 10000000,
"max_fee": 1000000,
"timeout_seconds": 30,
"concurrent_transactions": false
}
}For general relayer configuration options, check User Documentation - Relayers.
Swap Configuration (Sponsored Transactions)
The swap_config policy enables automated token swaps to keep the relayer funded with XLM. This is particularly useful for sponsored transactions where the relayer receives tokens but needs XLM to pay network fees.
| Field | Type | Description |
|---|---|---|
strategies | array | DEX strategies to use for token swaps, in priority order. Supported values: order-book (Stellar Horizon order book API). Strategies are tried sequentially until one can handle the asset. |
cron_schedule | string | Cron expression defining how often scheduled swaps should run (e.g., "0 0 * * * *" for every hour). Optional. |
min_balance_threshold | integer | Minimum XLM balance (in stroops) that triggers a swap. If the relayer's balance drops below this, a swap is attempted. Optional. |
Example swap configuration:
{
"policies": {
"fee_payment_strategy": "user",
"swap_config": {
"strategies": ["order-book"],
"cron_schedule": "0 0 * * * *",
"min_balance_threshold": 10000000
}
}
}Allowed Tokens Configuration
When using sponsored transactions (fee_payment_strategy: "user"), you can configure which tokens users can pay fees with via the allowed_tokens array. Each token entry supports:
| Field | Type | Description |
|---|---|---|
asset | string | Required. The asset identifier (e.g., native for XLM or USDC:GBBD... for USDC) |
max_allowed_fee | integer | Maximum fee amount allowed for this token (in token's smallest unit). Optional. |
swap_config | object | Per-token swap configuration. Optional. |
Per-token swap configuration fields:
slippage_percentage: Maximum slippage percentage allowed when swapping this token via DEXmin_amount: Minimum amount of a token to swap in a single operationmax_amount: Maximum amount of a token to swap in a single operationretain_min_amount: Minimum amount of a token to retain in the relayer account after a swap (prevents swapping the entire balance)
Example allowed tokens configuration:
{
"policies": {
"fee_payment_strategy": "user",
"allowed_tokens": [
{
"asset": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5",
"max_allowed_fee": 1000000000,
"swap_config": {
"slippage_percentage": 0.5,
"min_amount": 10000000,
"max_amount": 1000000000,
"retain_min_amount": 10000000
}
}
]
}
}Sponsored Transactions
Sponsored transactions allow users to pay transaction fees in tokens (e.g., USDC) instead of native XLM. This enables gasless user experiences where users don't need to hold XLM to interact with Stellar applications.
Asset Support: Currently, only classic Stellar assets (credit_alphanum4 and credit_alphanum12) are supported for sponsored transactions. Soroban token support will be available in a future release.
Enabling Sponsored Transactions
To enable sponsored transactions for a Stellar relayer, configure the following in your relayer's policies:
-
Set
fee_payment_strategytouser: This enables the sponsored transaction flow where users pay fees in tokens. -
Configure
allowed_tokens: Specify which tokens users can pay fees with. Each token can have:asset: The asset identifier (e.g.,nativefor XLM orUSDC:GBBD...for USDC)max_allowed_fee: Maximum fee amount allowed for this token (optional)swap_config: DEX swap configuration for automated token swaps to keep relayer funded
-
Configure DEX service: The relayer needs a DEX service configured to convert between XLM and fee tokens. This is typically configured at the service level.
Example configuration for sponsored transactions:
{
"id": "stellar-example",
"name": "Stellar Example",
"network": "testnet",
"paused": false,
"notification_id": "notification-example",
"signer_id": "local-signer",
"network_type": "stellar",
"policies": {
"fee_payment_strategy": "user",
"fee_margin_percentage": 5,
"swap_config": {
"strategies": ["order-book"]
},
"allowed_tokens": [
{
"asset": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5"
}
]
}
}Sponsored Transaction Endpoints
Once enabled, the relayer provides two endpoints for sponsored transactions:
- Quote (
POST /api/v1/relayers/<relayer_id>/transactions/sponsored/quote): Estimate the fee in tokens for a transaction - Build (
POST /api/v1/relayers/<relayer_id>/transactions/sponsored/build): Prepare a transaction with fee payment instructions
Both endpoints accept either:
transaction_xdr: A pre-built transaction XDR (base64 encoded)operations: An array of operations withsource_account(required when using operations)
The build endpoint returns a prepared transaction that includes:
- The transaction XDR ready for signing
- Fee amount in both XLM (stroops) and the specified token
- Transaction validity timestamp
After receiving the prepared transaction, users must sign it and submit it through the standard transaction submission endpoint. The relayer will wrap it in a fee-bump transaction where the relayer pays the XLM fees, and the user pays the token fees.
For detailed examples and code samples, see the SDK Stellar examples.
API Reference
Transaction Operations
The Stellar API supports a variety of transaction operations:
| Method Name | Required Parameters | Description |
|---|---|---|
| Send Transaction | network, operations (or transaction_xdr) | Submit a transaction to the Stellar network. Supports payment and Soroban operations directly, or any Stellar operation via pre-built XDR transactions. Also supports fee bump transactions for managing transaction fees. |
| Get Transaction Details | transaction_id | Retrieve a specific transaction by its ID. |
| List Transactions | (none) | List transactions for the relayer with pagination support. |
| Quote Sponsored Transaction | transaction_xdr (or operations with source_account), fee_token | Estimate the fee in tokens for a transaction. Available in user fee payment mode only. |
| Build Sponsored Transaction | transaction_xdr (or operations with source_account), fee_token | Prepare a transaction with fee payment instructions. Available in user fee payment mode only. |
Supported Operation Types
| Operation Type | Description |
|---|---|
payment | Transfer native XLM or other assets between accounts |
invoke_contract | Call a deployed Soroban smart contract function |
create_contract | Deploy a new Soroban smart contract from WASM hash |
upload_wasm | Upload WASM contract code to the Stellar ledger |
Transaction Structure
Required fields:
network: The Stellar network ("testnet", "mainnet", etc.)- Either
operations(array of operations) ORtransaction_xdr(base64-encoded XDR) - but not both
Optional fields:
source_account: The Stellar account that will be the source of the transaction (defaults to relayer’s address)memo: Transaction memo (see Memo Types below)valid_until: Transaction expiration time (ISO 8601 format)transaction_xdr: Pre-built transaction XDR (base64 encoded, signed or unsigned) - mutually exclusive withoperationsfee_bump: Boolean flag to request fee-bump wrapper (only valid with signedtransaction_xdr)max_fee: Maximum fee for fee bump transactions in stroops (defaults to 1,000,000 = 0.1 XLM)
Transaction Input Methods
The relayer supports three ways to submit transactions:
- Operations-based: Build a transaction by specifying the
operationsarray (recommended for most use cases) - Transaction XDR (unsigned): Submit a pre-built unsigned transaction using
transaction_xdrfield (advanced use case) - Transaction XDR (signed): Submit a signed transaction using
transaction_xdrwithfee_bump: true(required for signed XDR) to wrap it in a fee bump transaction
Example 1: Operations-based Transaction
curl --location --request POST 'http://localhost:8080/api/v1/relayers/<stellar_relayer_id>/transactions' \
--header 'Authorization: Bearer <api_key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"network": "testnet",
"operations": [
{
"type": "payment",
"destination": "GD77B6LYQ5XDCW6CND7CQMA23FSV7MZQGLBAU5OMEOXQM6XFTCMWQQCJ",
"asset": {"type": "native"},
"amount": 1000000
}
],
"memo": {"type": "text", "value": "Payment for services"}
}'Example 2: Unsigned Transaction XDR
Submit a pre-built unsigned transaction. The relayer will sign it with its configured signer:
curl --location --request POST 'http://localhost:8080/api/v1/relayers/<stellar_relayer_id>/transactions' \
--header 'Authorization: Bearer <api_key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"network": "testnet",
"transaction_xdr": "AAAAAgAAAACige4lTdwSB/sto4SniEdJ2kOa2X65s5bqkd40J4DjSwAAAGQAAHAkAAAADgAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAKKB7iVN3BIH+y2jhKeIR0naQ5rZfrmzluqR3jQngONLAAAAAAAAAAAAD0JAAAAAAAAAAAA="
}'The transaction_xdr field should contain a base64-encoded unsigned transaction envelope. This is useful when:
- You need precise control over transaction structure
- You want to use advanced Stellar features not exposed via the operations API
Example 3: Signed Transaction XDR
Submit a pre-signed transaction with fee bump wrapper. Note: fee_bump: true is required when submitting signed XDR:
curl --location --request POST 'http://localhost:8080/api/v1/relayers/<stellar_relayer_id>/transactions' \
--header 'Authorization: Bearer <api_key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"network": "testnet",
"transaction_xdr": "AAAAAgAAAABjc+mbXCnvmVk4lxqVl7s0LAz5slXqmkHBg8PpH7p3DgAAAGQABpK0AAAACQAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAGN0qQBW8x3mfbwGGYndt2uq4O4sZPUrDx5HlwuQke9zAAAAAAAAAAAAAA9CAAAAAQAAAAA=",
"fee_bump": true,
"max_fee": 10000000
}'The fee bump feature is useful when:
- You have a pre-signed transaction from another system or wallet
- You want the relayer to pay transaction fees on behalf of the original signer
- You need to increase the fee for a transaction to ensure timely execution
When using transaction_xdr:
- The XDR must be properly formatted and valid for the target network
- For unsigned XDR, the relayer will add its signature before submission
- For signed XDR,
fee_bump: trueis mandatory - the relayer requires this to wrap the signed transaction in a fee bump envelope - The
max_feeparameter (in stroops) controls the maximum fee for fee bump transactions (defaults to 1,000,000 = 0.1 XLM)
See API Reference for full details and examples.
Asset Types
Assets in Stellar operations must be specified with a type field:
Native XLM:
{"type": "native"}Credit Asset (4 characters or less):
{
"type": "credit_alphanum4",
"code": "USDC",
"issuer": "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN"
}Credit Asset (5-12 characters):
{
"type": "credit_alphanum12",
"code": "LONGASSET",
"issuer": "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN"
}Memo Types
Transactions can include optional memos:
- No Memo:
"type": "none" - Text Memo:
"type": "text", "value": "Payment for services"(max 28 UTF-8 bytes) - ID Memo:
"type": "id", "value": "12345" - Hash Memo:
"type": "hash", "value": "deadbeef..."(32 bytes hex) - Return Memo:
"type": "return", "value": "deadbeef..."(32 bytes hex)
Memos are not supported for Soroban contract operations (invoke_contract, create_contract, upload_wasm). Attempting to include a memo with these operations will result in an error.
Soroban Contract Operations
Invoke Contract
Call a deployed Soroban smart contract:
curl --location --request POST 'http://localhost:8080/api/v1/relayers/<stellar_relayer_id>/transactions' \
--header 'Authorization: Bearer <api_key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"network": "testnet",
"operations": [
{
"type": "invoke_contract",
"contract_address": "CA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUWDA",
"function_name": "transfer",
"args": [
{"address": "GCRID3RFJXOBEB73FWRYJJ4II5E5UQ413F7LTM4W5KI54NBHQDRUXVLY"},
{"address": "GD77B6LYQ5XDCW6CND7CQMA23FSV7MZQGLBAU5OMEOXQM6XFTCMWQQCJ"},
{"i128": {"hi": "0", "lo": "1000000"}}
],
"auth": {"type": "source_account"}
}
]
}'Create Contract
Deploy a new Soroban smart contract:
curl --location --request POST 'http://localhost:8080/api/v1/relayers/<stellar_relayer_id>/transactions' \
--header 'Authorization: Bearer <api_key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"network": "testnet",
"operations": [
{
"type": "create_contract",
"source": {
"from": "address",
"address": "GCRID3RFJXOBEB73FWRYJJ4II5E5UQ413F7LTM4W5KI54NBHQDRUXVLY"
},
"wasm_hash": "d3b2f6f8a1c5e9b4a7d8c2e1f5a9b3c6e8d4f7a2b5c8e1d4f7a0b3c6e9d2f5a8",
"salt": "0000000000000000000000000000000000000000000000000000000000000001"
}
]
}'Upload WASM
Upload contract code to the Stellar ledger:
curl --location --request POST 'http://localhost:8080/api/v1/relayers/<stellar_relayer_id>/transactions' \
--header 'Authorization: Bearer <api_key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"network": "testnet",
"operations": [
{
"type": "upload_wasm",
"wasm": {
"type": "base64",
"base64": "AGFzbQEAAAABBgFgAX8BfwMCAQAFAwEAAQcPAgVoZWxsbwAACG1lbW9yeTIDCgQAAAAL"
}
}
]
}'ScVal Argument Format
When invoking contract functions, arguments must be provided as ScVal values in JSON format:
| Type | Format | Description |
|---|---|---|
| U64 | "u64": "1000000" | Unsigned 64-bit integer |
| I64 | "i64": "-500" | Signed 64-bit integer |
| U32 | "u32": 42 | Unsigned 32-bit integer |
| I32 | "i32": -42 | Signed 32-bit integer |
| Boolean | "bool": true | Boolean value |
| String | "string": "hello world" | UTF-8 string |
| Symbol | "symbol": "transfer" | Symbol (used for function names) |
| Address | "address": "GCRID3RFJXOBEB73FWRYJJ4II5E5UQ413F7LTM4W5KI54NBHQDRUXVLY" | Stellar account or contract address |
| Bytes | "bytes": "deadbeef" | Hex-encoded byte array |
| Vector | "vec": ["u32": 1, "u32": 2, "u32": 3] | Array of ScVal values |
| Map | "map": ["key": "symbol": "name", "val": "string": "MyToken"] | Key-value pairs |
Additional types like U128, I128, U256, and I256 are also supported using multi-part representations.
Authorization Modes
Soroban operations support different authorization modes:
| Type | Description |
|---|---|
none | No authorization required |
source_account | Use the transaction source account (default) |
addresses | Use specific addresses (future feature) |
xdr | Advanced: provide base64-encoded XDR entries. This allows you to provide pre-signed SorobanAuthorizationEntry objects for complex authorization scenarios. See the official Stellar documentation on authorization for detailed information about SorobanAuthorizationEntries. |
Signer Support
Stellar networks support the following signer types:
- Local Signer: Uses encrypted keystore files (suitable for development)
- Google Cloud KMS: Uses Google Cloud Key Management Service with ED25519 keys (recommended for production)
- Turnkey: Uses Turnkey’s secure key management infrastructure with ED25519 keys (recommended for production)
For detailed signer configuration, see the Signers Configuration guide.
For complete examples:
- Google Cloud KMS: stellar-gcp-kms-signer example
- Turnkey: stellar-turnkey-signer example
Security
- Do not expose the relayer directly to the public internet
- Deploy behind a secure backend (reverse proxy, firewall)
- Use hosted signers in production systems
- Ensure proper network passphrases are configured for transaction signing
Troubleshooting
- Check environment variables and configuration files for errors
- Verify network passphrase matches the target network
- Review container logs for Stellar-specific errors
- Ensure Soroban RPC endpoints are properly configured for contract operations
Roadmap
- See Project Roadmap for upcoming features
Support
For help, join our Telegram or open an issue on GitHub.
License
This project is licensed under the GNU Affero General Public License v3.0.