openzeppelin_relayer/constants/stellar_transaction.rs
1//! Constants for Stellar transaction processing.
2//!
3//! This module contains default values used throughout the Stellar transaction
4//! handling logic, including fees, retry delays, and timeout thresholds.
5//!
6//! ## Gas Abstraction Contract Addresses
7//!
8//! This module also contains default contract addresses for Soroban gas abstraction:
9//! - **Soroswap**: AMM DEX for token-to-XLM quotes and swaps
10//! - **FeeForwarder**: Contract that enables fee payment in tokens instead of XLM
11//!
12//! These addresses can be overridden via environment variables if needed.
13//! See `ServerConfig` for the corresponding env var names.
14
15use chrono::Duration;
16
17// =============================================================================
18// Transaction Fees
19// =============================================================================
20
21pub const STELLAR_DEFAULT_TRANSACTION_FEE: u32 = 100;
22/// Default maximum fee for fee-bump transactions (0.1 XLM = 1,000,000 stroops)
23pub const STELLAR_DEFAULT_MAX_FEE: i64 = 1_000_000;
24/// Maximum number of operations allowed in a Stellar transaction
25pub const STELLAR_MAX_OPERATIONS: usize = 100;
26
27/// Horizon API base URL for Stellar mainnet
28pub const STELLAR_HORIZON_MAINNET_URL: &str = "https://horizon.stellar.org";
29/// Horizon API base URL for Stellar testnet
30pub const STELLAR_HORIZON_TESTNET_URL: &str = "https://horizon-testnet.stellar.org";
31
32// Status check scheduling
33/// Initial delay before first status check (in seconds)
34/// Set to 2s for faster detection of transaction state changes
35pub const STELLAR_STATUS_CHECK_INITIAL_DELAY_SECONDS: i64 = 2;
36
37/// Minimum age before triggering Pending status recovery (in seconds)
38/// Only schedule a recovery job if Pending transaction without hash exceeds this age
39/// This prevents scheduling a job on every status check
40pub const STELLAR_PENDING_RECOVERY_TRIGGER_SECONDS: i64 = 10;
41
42// Transaction validity
43/// Approximate Stellar ledger close time in seconds (used for ledger-based expiration)
44pub const STELLAR_LEDGER_TIME_SECONDS: u64 = 5;
45
46/// Default transaction validity duration (in minutes) for sponsored transactions
47/// Provides reasonable time for users to review and submit while ensuring transaction doesn't expire too quickly
48pub const STELLAR_SPONSORED_TRANSACTION_VALIDITY_MINUTES: i64 = 2;
49
50/// Sponsored transaction validity in seconds (2 minutes).
51/// Used for gas abstraction authorization validity so it aligns with the transaction submission window.
52pub const STELLAR_SPONSORED_TRANSACTION_VALIDITY_SECONDS: u64 = 120;
53
54/// Get status check initial delay duration
55pub fn get_stellar_status_check_initial_delay() -> Duration {
56 Duration::seconds(STELLAR_STATUS_CHECK_INITIAL_DELAY_SECONDS)
57}
58
59/// Get sponsored transaction validity duration
60pub fn get_stellar_sponsored_transaction_validity_duration() -> Duration {
61 Duration::minutes(STELLAR_SPONSORED_TRANSACTION_VALIDITY_MINUTES)
62}
63
64// Recovery thresholds
65/// Maximum lifetime for stuck transactions (Sent, Pending, Submitted) before marking as Failed (15 minutes)
66/// Safety net for transactions without time bounds - prevents infinite retries.
67pub const STELLAR_MAX_STUCK_TRANSACTION_LIFETIME_MINUTES: i64 = 15;
68
69/// Base interval (seconds) for resubmitting a Submitted transaction.
70/// Stellar Core retries internally for ~2 ledgers (~10s). We start resubmitting at 10s
71/// to ensure the transaction is back in the mempool before Core's window closes.
72pub const STELLAR_RESUBMIT_BASE_INTERVAL_SECONDS: i64 = 10;
73
74/// Maximum number of times a Stellar submission may be retried after an insufficient-fee error.
75pub const STELLAR_INSUFFICIENT_FEE_MAX_RETRIES: u32 = 2;
76
77/// Maximum resubmit interval (seconds) to cap the resubmission backoff.
78/// Prevents excessively long gaps between resubmissions.
79pub const STELLAR_RESUBMIT_MAX_INTERVAL_SECONDS: i64 = 120;
80
81/// Growth factor for resubmit backoff. Each tier multiplies the interval by this factor.
82/// With base=10 and factor=1.5: 10s → 15s → 22s → 33s → 50s → 75s → 113s → 120s (capped).
83pub const STELLAR_RESUBMIT_GROWTH_FACTOR: f64 = 1.5;
84
85/// Get base resubmit interval for Submitted transactions
86pub fn get_stellar_resubmit_base_interval() -> Duration {
87 Duration::seconds(STELLAR_RESUBMIT_BASE_INTERVAL_SECONDS)
88}
89
90/// Get maximum resubmit interval (backoff cap) for Submitted transactions
91pub fn get_stellar_resubmit_max_interval() -> Duration {
92 Duration::seconds(STELLAR_RESUBMIT_MAX_INTERVAL_SECONDS)
93}
94
95/// Get max lifetime duration for stuck transactions (Sent, Pending, Submitted)
96pub fn get_stellar_max_stuck_transaction_lifetime() -> Duration {
97 Duration::minutes(STELLAR_MAX_STUCK_TRANSACTION_LIFETIME_MINUTES)
98}
99
100// =============================================================================
101// Soroswap DEX Contract Addresses (Mainnet Only)
102// =============================================================================
103// Official Soroswap mainnet deployments from:
104// https://github.com/soroswap/core/blob/main/public/mainnet.contracts.json
105//
106// Testnet addresses must be provided via environment variables:
107// - STELLAR_TESTNET_SOROSWAP_ROUTER_ADDRESS
108// - STELLAR_TESTNET_SOROSWAP_FACTORY_ADDRESS
109// - STELLAR_TESTNET_SOROSWAP_NATIVE_WRAPPER_ADDRESS
110
111/// Soroswap router contract address on Stellar mainnet
112pub const STELLAR_SOROSWAP_MAINNET_ROUTER: &str =
113 "CAG5LRYQ5JVEUI5TEID72EYOVX44TTUJT5BQR2J6J77FH65PCCFAJDDH";
114
115/// Soroswap factory contract address on Stellar mainnet
116pub const STELLAR_SOROSWAP_MAINNET_FACTORY: &str =
117 "CA4HEQTL2WPEUYKYKCDOHCDNIV4QHNJ7EL4J4NQ6VADP7SYHVRYZ7AW2";
118
119/// Native XLM wrapper token contract address on Stellar mainnet
120/// This is the Soroban token contract that wraps native XLM for use in Soroswap
121pub const STELLAR_SOROSWAP_MAINNET_NATIVE_WRAPPER: &str =
122 "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA";
123
124// =============================================================================
125// FeeForwarder Contract Addresses (Mainnet Only)
126// =============================================================================
127// The FeeForwarder contract enables gas abstraction by allowing users to pay
128// transaction fees in tokens instead of native XLM.
129//
130// Testnet address must be provided via environment variable:
131// - STELLAR_TESTNET_FEE_FORWARDER_ADDRESS
132
133/// FeeForwarder contract address on Stellar mainnet
134/// Set to empty string until mainnet deployment is available
135pub const STELLAR_FEE_FORWARDER_MAINNET: &str = "";