Skip to content

Latest commit

 

History

History
467 lines (340 loc) · 20.4 KB

sep-0038.md

File metadata and controls

467 lines (340 loc) · 20.4 KB

Preamble

SEP: 0038
Title: Anchor RFQ API
Author: Jake Urban <@jakeurban> and Leigh McCulloch <@leighmcculloch>
Track: Standard
Status: Draft
Created: 2021-04-09
Updated: 2022-03-16
Discussion: https://github.com/stellar/stellar-protocol/issues/901
Version 1.6.1

Summary

This protocol enables anchors to accept off-chain assets in exchange for different on-chain assets, and vice versa. Specifically, it enables anchors to provide quotes that can be referenced within the context of existing Stellar Ecosystem Proposals. How the exchange of assets is facilitated is outside the scope of this document.

Motivation

Anchoring an asset and issuing an asset are distinct functions that have different business and technical requirements. However, issuing an asset has often been a prerequisite for anchoring an asset. This protocol enables anchors to transfer value on and off the Stellar network for their clients regardless of whether a one-for-one reserve-backed Stellar asset exists for the off-chain asset held by the anchor's clients.

Removing this requirement for anchors also provides downstream benefits to ecosystem participants generally. Enabling anchors to accept any Stellar asset will naturally decrease liquidity fragmentation on the decentralized exchange, leading to greater market depth and tighter spreads between trading pairs.

Specification

stellar.toml

An anchor must define the location of their ANCHOR_QUOTE_SERVER in their stellar.toml. This is how a wallet knows where to find the anchor's server.

Authentication

This protocol's endpoints use authentication in the form of a SEP-10 JSON Web Token (JWT) in the Authorization header of the request.

Authentication is mandatory for POST /quote and GET /quote/:id, but optional for the remaining endpoints. When optional, if authentication is provided it can be used to personalize the respective responses.

Authorization: Bearer <jwt>

Content Type

All endpoints accept in requests the following Content-Type:

  • application/json

All endpoints respond with content type:

  • application/json

Errors

If an error occurs when calling any endpoint, an appropriate HTTP status code will be returned along with an error response.

Status Code

Common HTTP status codes may be returned for a server. In particular the following are expected:

Status Code Name Reason
400 Bad Request The request is invalid in any way.
403 Permission Denied No Authorization header has been provided or the contents of the header are not accepted as valid.

The response body must contain a human-readable description of the reason for error:

{
  "error": "The requested asset is not supported. See GET /prices for supported assets."
}

Asset Identification Format

This protocol can be used to provide quotes for any class of asset in exchange for a Stellar asset. The following format is used to identify an asset in API requests and responses.

<scheme>:<identifer>

The currently accepted scheme values are:

Name Description
stellar Used for Stellar assets.
iso4217 Used for fiat currencies.

stellar Identifier Format

The SEP-11 asset format.

iso4217 Identifier Format

The ISO 4217 three-character currency code for the fiat currency.

For example, Stellar USDC would be identified as:

stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN

Fiat USD would be identified as:

iso4217:USD

Endpoints

GET Info

This endpoint describes the supported Stellar assets and off-chain assets available for trading. Note that the anchor may not support a trading pair between every Stellar asset and off-chain asset listed. Use the GET /prices endpoint to see which pairs are supported.

Authentication

Optional SEP-10. If authentication is provided it can be used to personalize the response.

Request

No request arguments required.

Response

A 200 Success status code should be returned for successful requests.

Name Type Description
assets array An array of objects describing the assets available in exchange for one or more of the other assets listed.

assets Object Schema

Name Type Description
asset string The Asset Identification Format value.
sell_delivery_methods array (optional) Only for non-Stellar assets. An array of objects describing the methods a client can use to sell/deliver funds to the anchor. The method of delivery may affect the expiration and/or price provided in a POST /quote response. If the delivery method is not necessary for providing accurate quotes and expirations, the server can omit this attribute.
buy_delivery_methods array (optional) Only for non-Stellar assets. An array of objects describing the methods a client can use to buy/retrieve funds from the anchor. The method of delivery may affect the expiration and/or price provided in a POST /quote response. If the delivery method is not necessary for providing accurate quotes and expirations, the server can omit this attribute.
country_codes array (optional) Only for fiat assets. A list of ISO 3166-1 alpha-3 codes of the countries where the Anchor operates for fiat transactions.

Object Schema for sell_delivery_methods and buy_delivery_methods.

Name Type Description
name string The value to use when making POST /quote requests.
description string A human readable description of the method identified by name.
Example

GET /info

{
  "assets":  [
    {
      "asset": "stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN"
    },
    {
      "asset": "stellar:BRL:GDVKY2GU2DRXWTBEYJJWSFXIGBZV6AZNBVVSUHEPZI54LIS6BA7DVVSP"
    },
    {
      "asset": "iso4217:BRL",
      "country_codes": ["BRA"],
      "sell_delivery_methods": [
        {
          "name": "cash",
          "description": "Deposit cash BRL at one of our agent locations."
        },
        {
          "name": "ACH",
          "description": "Send BRL directly to the Anchor's bank account."
        },
        {
          "name": "PIX",
          "description": "Send BRL directly to the Anchor's bank account."
        }
      ],
      "buy_delivery_methods": [
        {
          "name": "cash",
          "description": "Pick up cash BRL at one of our payout locations."
        },
        {
          "name": "ACH",
          "description": "Have BRL sent directly to your bank account."
        },
        {
          "name": "PIX",
          "description": "Have BRL sent directly to the account of your choice."
        }
      ]
    }
  ]
}

GET Prices

This endpoint can be used to fetch the indicative prices of available off-chain assets in exchange for a Stellar asset and vice versa.

These prices are indicative. The actual price will be calculated at conversion time once the Anchor receives the funds from a User.

The prices returned include any margin that the provider may keep as a service fee, and this margin may vary depending on the directional flow of funds, amount, delivery method, country code, or other factors.

Authentication

Optional SEP-10. If authentication is provided it can be used to personalize the response.

Request

Name Type Description
sell_asset string The asset you want to sell, using the Asset Identification Format.
sell_amount string The amount of sell_asset the client would exchange for each of the buy_assets.
sell_delivery_method string (optional) One of the name values specified by the sell_delivery_methods array for the associated asset returned from GET /info. Can be provided if the user is delivering an off-chain asset to the anchor but is not strictly required.
buy_delivery_method string (optional) One of the name values specified by the buy_delivery_methods array for the associated asset returned from GET /info. Can be provided if the user intends to receive an off-chain asset from the anchor but is not strictly required.
country_code string (optional) The ISO 3166-1 alpha-3 code of the user's current address. Should be provided if there are two or more country codes available for the desired asset in GET /info.

Response

A 200 Success status code should be returned for successful requests.

Name Type Description
buy_assets array An array of objects containing information on the assets that the client will receive when they provide sell_asset.

buy_assets Object Schema

Name Type Description
asset string The Asset Identification Format value.
price string The price offered by the anchor for one unit of asset in terms of sell_asset. In traditional finance, asset would be referred to as the base asset and sell_asset as the counter asset.
decimals integer The number of decimals needed to represent asset.
Examples
GET /prices?sell_asset=stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN&sell_amount=100&country_code=BRA&buy_delivery_method=ACH
{
  "buy_assets": [
    {
      "asset": "iso4217:BRL",
      "price": "0.18",
      "decimals": 2
    }
  ]
}

GET /prices?sell_asset=iso4217:BRL&sell_amount=500&country_code=BRA&sell_delivery_method=PIX
{
  "buy_assets": [
    {
      "asset": "stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN",
      "price": "5.42",
      "decimals": 7
    }
  ]
}

GET Price

This endpoint can be used to fetch the indicative price for a given asset pair.

The client must provide either sell_amount or buy_amount, but not both.

These prices are indicative. The actual price will be calculated at conversion time once the Anchor receives the funds from a User.

The price returned includes any margin that the provider may keep as a service fee, and this margin may vary depending on the directional flow of funds, amount, delivery method, country code, or other factors.

Authentication

Optional SEP-10. If authentication is provided it can be used to personalize the response.

Request

Name Type Description
sell_asset string The asset the client would like to sell. Ex. USDC:G..., iso4217:ARS
buy_asset string The asset the client would like to exchange for sell_asset.
sell_amount string The amount of sell_asset the client would exchange for buy_asset.
buy_amount string The amount of buy_asset the client would like to purchase with sell_asset.
sell_delivery_method string (optional) One of the name values specified by the sell_delivery_methods array for the associated asset returned from GET /info. Can be provided if the user is delivering an off-chain asset to the anchor but is not strictly required.
buy_delivery_method string (optional) One of the name values specified by the buy_delivery_methods array for the associated asset returned from GET /info. Can be provided if the user intends to receive an off-chain asset from the anchor but is not strictly required.
country_code string (optional) The ISO 3166-1 alpha-3 code of the user's current address. Should be provided if there are two or more country codes available for the desired asset in GET /info.

Response

A 200 Success status code should be returned for successful requests.

Name Type Description
price string The price offered by the anchor for one unit of buy_asset in terms of sell_asset. In traditional finance, buy_asset would be referred to as the base asset and sell_asset as the counter asset.
sell_amount string The amount of sell_asset the anchor would exchange for buy_asset.
buy_amount string The amount of buy_asset the anchor would provide with sell_asset.
Examples
GET /price?sell_asset=iso4217:BRL&buy_asset=stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN&sell_amount=500&sell_delivery_method=PIX&country_code=BRA
{
  "price": "5.42",
  "sell_amount": "500",
  "buy_amount": "92.25"
}

GET /price?sell_asset=iso4217:BRL&buy_asset=stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN&buy_amount=100&sell_delivery_method=PIX&country_code=BRA
{
  "price": "5.42",
  "sell_amount": "542",
  "buy_amount": "100"
}

GET /price?sell_asset=stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN&buy_asset=iso4217:BRL&sell_amount=100&buy_delivery_method=PIX&country_code=BRA
{
  "price": "0.18",
  "sell_amount": "100",
  "buy_amount": "555.56"
}

GET /price?sell_asset=stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN&buy_asset=iso4217:BRL&buy_amount=500&buy_delivery_method=PIX&country_code=BRA
{
  "price": "0.18",
  "sell_amount": "90",
  "buy_amount": "500"
}

POST Quote

This endpoint can be used to request a firm quote for a Stellar asset and off-chain asset pair.

In contrast with the GET /price and GET /prices endpoints, the amount requested must be held in reserve and not used in calculations of subsequent quotes until the expiration provided in the response.

Protecting Against Bad Actors

To protect against bad actor clients reserving all available capital without following through with the requested trades, servers should only accept requests for quotes from Stellar accounts that belong to entities or individuals that have been properly KYC'ed, either via SEP-12 or some other mechanism.

Servers may deny access to the API if misuse is detected.

Transaction Fees

The quote returned includes any margin that the provider may keep as a service fee, and this margin may vary depending on the directional flow of funds, the delivery method, amount, country code, or other factors.

If the client requests some amount of an off-chain asset for providing some amount of a Stellar asset, the client will submit a Stellar transaction delievering funds to the anchor before the expiration included in the response, paying a fee as determined by state of the Stellar network.

In the reverse scenario, the anchor will submit a Stellar transaction to deliver funds to the client as long as the client delivered off-chain funds to the anchor before the expiration. In this case, the anchor will likely increase their margin to cover the cost of submitting the transaction.

Authentication

SEP-10.

Request

The client must provide either sell_amount or buy_amount, but not both.

Unless the list included in the GET /info response is empty or missing for the associated off-chain asset, the client must also provide either sell_delivery_method or buy_delivery_method, but not both.

Name Type Description
sell_asset string Same as the definition of sell_asset in GET /price.
buy_asset string Same as the definition of buy_asset in GET /price.
sell_amount string Same as the definition of sell_amount in GET /price.
buy_amount string The same definition of buy_amount in GET /price.
expire_after UTC ISO 8601 string (optional) The client's desired expires_at date and time for the quote. Anchors may choose an expires_at that occurs after the expire_after. Anchors should return 400 Bad Request if the an expiration on or after the requested value cannot be provided.
sell_delivery_method string (optional) One of the name values specified by the sell_delivery_methods array for the associated asset returned from GET /info. Must be provided if the user is delivering an off-chain asset to the anchor unless no more than one method is specified in the GET /info response.
buy_delivery_method string (optional) One of the name values specified by the buy_delivery_methods array for the associated asset returned from GET /info. Must be provided if the user intends to receive an off-chain asset from the anchor unless no more than one method is specified in the GET /info response.
country_code string (optional) The ISO 3166-1 alpha-3 code of the user's current address. Should be provided if there are two or more country codes available for the desired asset in GET /info.

Response

A 201 Created status code should be returned for successful requests.

Name Type Description
id string The unique identifier for the quote to be used in other Stellar Ecosystem Proposals (SEPs).
expires_at UTC ISO 8601 string The date and time by which the anchor must receive funds from the client.
price string The price offered by the anchor for one unit of buy_asset in terms of sell_asset. In traditional finance, buy_asset would be referred to as the base asset and sell_asset as the counter asset.
sell_asset string The asset the client would like to sell. Ex. USDC:G..., iso4217:ARS
sell_amount string The amount of sell_asset to be exchanged for buy_asset.
buy_asset string The asset the client would like to exchange for sell_asset.
buy_amount string The amount of buy_asset to be exchanged for sell_asset. price * buy_amount = sell_amount must be true up to the number of decimals required for buy_asset.

GET Quote

This endpoint can be used to fetch a previously-provided firm quote. Quotes referenced in other protocols must be available at this endpoint past the expires_at expiration for the quote.

Authentication

SEP-10.

Request

Name Type Description
id string The unique identifier for the quote. Same as the id returned in the POST /quote response.

Response

This response body should match the response from POST /quote.

Name Type Description
id string The id specified in the request.
expires_at UTC ISO 8601 string The date and time by which the anchor must receive funds from the client.
price string The price offered by the anchor for one unit of buy_asset in terms of sell_asset. In traditional finance, buy_asset would be referred to as the base asset and sell_asset as the counter asset.
sell_asset string The asset the client would like to sell. Ex. USDC:G..., iso4217:ARS
sell_amount string The amount of sell_asset to be exchanged for buy_asset.
buy_asset string The asset the client would like to exchange for sell_asset.
buy_amount string The amount of buy_asset to be exchanged for sell_asset. price * buy_amount = sell_amount must be true up to the number of decimals required for buy_asset.
Example
GET /quote/de762cda-a193-4961-861e-57b31fed6eb3
{
  "id": "de762cda-a193-4961-861e-57b31fed6eb3",
  "expires_at": "2021-04-30T07:42:23",
  "price": "5.42",
  "sell_asset": "iso4217:BRL",
  "sell_amount": "500",
  "buy_asset": "stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN&",
  "buy_amount": "92.25"
}

Changelog

  • v1.6.1: Add note about expires_at and expires_after and their relationship. (#1147)
  • v1.6.0: Make SEP-10 authentication token optional for the GET /info, GET /price and GET /prices endpoints. (#1144)