QuoteService

class QuoteService(serviceAddress: String, httpClient: HttpClient? = null, httpRequestHeaders: Map<String, String>? = null)

SEP-38 Anchor RFQ (Request for Quote) API client.

Implements the client side of SEP-38 for requesting price quotes for asset exchanges between on-chain and off-chain assets. This service allows wallets and applications to:

  • Discover supported assets and delivery methods

  • Request indicative prices for asset pairs (non-binding)

  • Request firm quotes (binding commitments)

  • Retrieve previously created quotes

SEP-38 enables anchors to accept any Stellar asset in exchange for off-chain assets (fiat currencies, commodities, etc.) without requiring one-for-one reserve-backed Stellar assets. This reduces liquidity fragmentation on the DEX and provides greater flexibility for deposit/withdrawal operations.

Quote types:

  • Indicative prices: Non-binding price information via GET /prices and GET /price

  • Firm quotes: Binding commitments via POST /quote that reserve liquidity until expiration

Typical workflow:

  1. Call info to discover available assets and delivery methods

  2. Call prices to get indicative prices for multiple asset pairs (optional)

  3. Call price to get indicative price for a specific amount (optional)

  4. Call postQuote to request a firm quote with binding commitment

  5. Execute trade via SEP-6, SEP-24, or SEP-31 using the quote ID

  6. Call getQuote to check quote status (optional)

Authentication:

Asset format:

  • Stellar assets: "stellar:CODE:ISSUER" (e.g., "stellar:USDC:GA5...ZVN")

  • Fiat currencies: "iso4217:USD" (ISO 4217 three-character code)

Example - Complete quote workflow:

// 1. Initialize from domain
val quoteService = QuoteService.fromDomain("testanchor.stellar.org")

// 2. Discover available assets
val info = quoteService.info()
info.assets.forEach { asset ->
println("Asset: ${asset.asset}")
asset.sellDeliveryMethods?.forEach { method ->
println(" Sell via: ${method.name}")
}
}

// 3. Get indicative prices (optional)
val pricesResponse = quoteService.prices(
sellAsset = "stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
sellAmount = "100"
)
pricesResponse.buyAssets?.forEach { buyAsset ->
println("Can buy ${buyAsset.asset} at price ${buyAsset.price}")
}

// 4. Get specific indicative price (optional)
val priceResponse = quoteService.price(
context = "sep6",
sellAsset = "stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
buyAsset = "iso4217:BRL",
sellAmount = "100",
buyDeliveryMethod = "PIX"
)
println("Indicative price: ${priceResponse.price}")
println("Total with fees: ${priceResponse.totalPrice}")

// 5. Request firm quote (requires authentication)
val jwtToken = obtainSep10Token() // Get JWT via SEP-10 WebAuth

val quoteRequest = Sep38QuoteRequest(
context = "sep6",
sellAsset = "stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
buyAsset = "iso4217:BRL",
sellAmount = "100",
buyDeliveryMethod = "PIX",
countryCode = "BR"
)

val quote = quoteService.postQuote(quoteRequest, jwtToken)
println("Quote ID: ${quote.id}")
println("Expires at: ${quote.expiresAt}")
println("Guaranteed rate: ${quote.price}")

// 6. Retrieve quote later (optional)
val retrievedQuote = quoteService.getQuote(quote.id, jwtToken)
println("Quote status: ${retrievedQuote.expiresAt}")

Example - Error handling:

try {
val quote = quoteService.postQuote(request, jwtToken)
} catch (e: Sep38BadRequestException) {
println("Invalid request: ${e.error}")
} catch (e: Sep38PermissionDeniedException) {
println("Authentication required or expired: ${e.error}")
} catch (e: Sep38NotFoundException) {
println("Quote not found: ${e.error}")
} catch (e: Sep38UnknownResponseException) {
println("Unexpected error (${e.statusCode}): ${e.responseBody}")
}

See also:

Constructors

Link copied to clipboard
constructor(serviceAddress: String, httpClient: HttpClient? = null, httpRequestHeaders: Map<String, String>? = null)

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
suspend fun getQuote(id: String, jwtToken: String): Sep38QuoteResponse

Retrieves a previously created firm quote by ID.

Link copied to clipboard
suspend fun info(jwtToken: String? = null): Sep38InfoResponse

Retrieves supported assets and delivery methods available for trading.

Link copied to clipboard
suspend fun postQuote(request: Sep38QuoteRequest, jwtToken: String): Sep38QuoteResponse

Requests a firm quote with binding commitment from the anchor.

Link copied to clipboard
suspend fun price(context: String, sellAsset: String, buyAsset: String, sellAmount: String? = null, buyAmount: String? = null, sellDeliveryMethod: String? = null, buyDeliveryMethod: String? = null, countryCode: String? = null, jwtToken: String? = null): Sep38PriceResponse

Fetches an indicative price for a specific asset pair and amount.

Link copied to clipboard
suspend fun prices(sellAsset: String? = null, buyAsset: String? = null, sellAmount: String? = null, buyAmount: String? = null, sellDeliveryMethod: String? = null, buyDeliveryMethod: String? = null, countryCode: String? = null, jwtToken: String? = null): Sep38PricesResponse

Fetches indicative prices for available assets given a base asset and amount.