Skip to content

Exchanges

Exchanges allow you to convert one asset to another in String Theory. This article will cover what that means and the basics of how to use them.

An exchange is the conversion of one asset to another. We may want to trade USD for EUR, record the sale of a piece of real estate, or capture the real currency value of a customer spending loyalty points. These can all be modeled as exchanges. The key to understanding exchanges is that 1) they occur at a specific exchange rate and 2) at least for currencies, this rate tends to be highly volatile. Because of this volatility, accurately recording exchanges is a difficult problem! That’s where we come in.

An exchange rate describes the value (as a multiplier) of exchanging one asset class for another. So, as an example, an exchange rate of 0.86 for USD to EUR means we will receive 0.86 EUR for every 1 USD we exchange.

So, where do exchange rates come from? Ultimately, some service or platform is responsible for making exchanges. We’ll call these providers . The providers are responsible for providing exchange rates and honoring actual exchanges at those rates (with some terms and limitations such as, usually, time elapsed since the quote). In order to recall this specific requested rate, these providers tend to use a unique index called an exchange rate key .

So, there’s the picture of exchanges in the wild. A provider offers to satisfy a requested exchange at a provided rate, and can recall that rate via a unique exchange rate key. How does String Theory fit in? To assist in accurately making and recording exchanges, String Theory depends on two intertwined concepts: Exchange Rate Providers and Exchange Rate Keys .

Before we dive into the details of exchanges, we need to understand one of the basic building blocks of String Theory: amounts . While this document is sufficient for understanding exchanges, it is recommended to read the amounts document first.

In String Theory all amounts are represented by 3 fields:

  • Unit Type: The general class of asset, sometimes with a precision. Example: “currency_micros”
  • Unit Token: The specific type of asset inside that class. Example: “USD”
  • Unit Count: The whole number of units of the asset. Example: “1000000”

We call the combination of unit type and unit token an asset class . From here on out, we will use this term extensively, as the viability and outcome of any exchange is dependent on the asset classes involved.

An exchange in String Theory is an operation that converts one asset class to another. This results in a change to the amounts type, token, and/or count.

String Theory’s amounts are designed to provide enough information to be able to exchange between two amounts (or tell if they are incompatible) without having to look at additional metadata. Here is an example of how you would use amount data to exchange amounts:

$3.53 USD
Unit type: currency_micros
Unit token: USD
Unit count: 3530000
€3.22 EUR
Unit type: currency_micros
Unit token: EUR
Unit count: 3224500
  1. Check that asset classes are exchangeable
  2. Look up conversion rate between asset classes
  3. Find 0.91 USD → EUR
  4. Produce a new amount, with the target asset class and converted count

In this case the unit type and unit count are both changed as a result of the exchange. Since both asset classes have type currency_micros, the unit type is not changed.

Just like in the wild, String Theory uses a combination of exchange rate keys and providers to make this happen.

An exchange rate key is a unique index for a permissible exchange via a specific provider. In String Theory, these keys are made up of two parts:

  • Type - The unique identifier for an exchange rate provider in the system. This usually corresponds to the name of a provider. Example: “oanda”
  • Token - A unique id of a point-in-time exchange rate. It will look different depending on the type. Example: “USD_EUR_2025-06-20T12:00:00Z”

To map an exchange rate key to a numerical exchange rate, String Theory uses exchange rate providers.

An exchange rate provider is a software plugin which is responsible for 1) defining what exchanges are permissible and 2) associating exchange rate keys with a specific exchange rate. Optionally, they may also provide spot rates, which are current-time estimates of the rate of a certain exchange. This plugin lives and runs alongside String Theory, but likely interfaces with some third-party platform in order to provide rates. Exchange rates often vary wildly based on contractual terms between your company and the exchanging partners, so we expect that most clients will build custom provider plugins that capture this unique business context.

It is also required to implement your own exchange rate provider for most non-currency asset classes (e.g. loyalty points).

String Theory can support multiple exchange rate providers at once. As an example, you could easily use a custom provider for currency exchanges and a separate provider for redeeming loyalty points. Exchanges are a broad and powerful concept, so we made our implementation flexible.

A spot rate is the most current exchange rate between two asset classes. Exchange rate providers can optionally provide spot rates between asset classes. It’s important to note that some exchanges do not have a sensible spot rate. As an example, when selling real estate there is no ongoing exchange rate, only the actual sale price. Similarly, with loyalty points the exchange rate depends on the specific things being purchased, so a generic spot rate isn’t meaningful.

It is strongly discouraged to use spot rates for hard exchanges, as they are so time sensitive that they are often incorrect by the time the exchange is recorded. Instead, use an exchange rate key that points to a point-in-time exchange rate for the actual rate of exchange.

Exchanges aren’t limited just to exchanging currencies! You can exchange between any two asset classes that have a valid exchange rate. Here are some other examples of exchanges:

$3.53 USD
Unit type: currency_micros
Unit token: USD
Unit count: 3530000
$3.53 USD
Unit type: currency
Unit token: USD
Unit count: 3.53
Real estate
Unit type: real_estate
Unit token: holding_e1f29e8fd139963
Unit count: 1
$750,000 USD
Unit type: currency_micros
Unit token: USD
Unit count: 750000000000

Converting Bitcoin to a USD stablecoin (USDT)

Section titled “Converting Bitcoin to a USD stablecoin (USDT)”
1 BTC
Unit type: btc_satoshis
Unit token: wallet_1A1z...
Unit count: 100000000
$103,276.00 USD
Unit type: currency_micros
Unit token: USD
Unit count: 103276000000
500,000 loyalty points
Unit type: loyalty_points
Unit token: china_loyalty
Unit count: 500000
€4.75 EUR
Unit type: currency_micros
Unit token: EUR
Unit count: 47500

From here, we discuss the specifics of implementing exchange rate providers in String Theory. As such, the rest of this document will likely be of interest to developers, but may not be relevant to you if you are only interested in understanding exchanges conceptually.

Exchange rate providers are required to implement two core functions and one optional function:

canExchange(from: AssetClass, to: AssetClass): boolean
getSpotRate(from: AssetClass, to: AssetClass): ExchangeRate
getExchangeRate(from: AssetClass, to: AssetClass, exchangeRateKey: ExchangeRateKey): ExchangeRate

The canExchange function is used to determine if an exchange between two asset classes is possible. It is called by String Theory when an exchange is requested and should return true if the exchange is possible and false otherwise.

Returns the exchange rate between the two asset classes as of right now.

Returns the exchange rate between the two asset classes for a given exchange rate key. This should always return the same result given the same inputs.