Queries

A convenient HTTP API for accessing Stellar is provided by the Stellar Development Foundation (SDF) through a component called Horizon. The Scala Stellar SDK provides access to these endpoints via methods on the interface. These methods mirror the REST API provided by Horizon.

The SDF supports two main networks, the primary public network and another for testing. These are represented separately by the objects PublicNetwork and TestNetwork.

If it is your use-case that you are deploying a separate, private Stellar network, then you can implement the Network trait to provide access to the Horizon endpoints on your network.

Queries fall into several categories.

Accounts

s are the entities through which users can interact with the network. They are represented by a key pair. Account details can be found given an account’s or .

val accountId = "GCXYKQF35XWATRB6AWDDV2Y322IFU2ACYYN5M2YB44IBWAIITQ4RYPXK"
val publicKey = KeyPair.fromAccountId(accountId)

// account details
val accountDetails: Future[AccountResponse] = TestNetwork.account(publicKey)

// account datum value
val accountData: Future[Array[Byte]] = TestNetwork.accountData(publicKey, "data_key")

Assets

s are the items that are traded on the network. They can be searched for by their code, issuer, neither or both.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

// stream of all assets from all issuers
val allAssets: Future[LazyList[AssetResponse]] = TestNetwork.assets()

// stream of the last 20 assets created
val last20Assets =
  TestNetwork.assets(cursor = Now, order = Desc).map(_.take(20))

// stream of assets with the code HUG
val hugAssets: Future[LazyList[AssetResponse]] = TestNetwork.assets(code = Some("HUG"))

// stream of assets from the specified issuer
val issuerAssets: Future[LazyList[AssetResponse]] =
  TestNetwork.assets(issuer = Some(publicKey))

// LazyList (of max length 1) of HUG assets from the issuer
val issuersHugAsset: Future[LazyList[AssetResponse]] =
  TestNetwork.assets(code = Some("HUG"), issuer = Some(publicKey))

Effects

s are the changes that have been effected on the network as a result of operations successfully processed.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

// stream of all effects
val allEffects: Future[LazyList[EffectResponse]] = TestNetwork.effects()

// stream of the last 20 effects
val last20Effects =
  TestNetwork.effects(cursor = Now, order = Desc).map(_.take(20))

// stream of effects related to a specific account
val effectsForAccount = TestNetwork.effectsByAccount(publicKey)

// stream of effects related to a specific transaction hash
val effectsForTxn: Future[LazyList[EffectResponse]] =
  TestNetwork.effectsByTransaction("f00cafe...")

// stream of effects related to a specific operation id
val effectsForOperationId: Future[LazyList[EffectResponse]] =
  TestNetwork.effectsByOperation(123L)

// stream of effects for a specific ledger
val effectsForLedger = TestNetwork.effectsByLedger(1234)

Fee Statistics

When transacting, it is possible to nominate a fee that is greater than the base fee. Transactions paying higher fees are prioritised at times of high load.

This parameterless endpoint provides statistics about the fees paid during the last known ledger.

val feeStats: Future[FeeStatsResponse] = TestNetwork.feeStats()
val minAcceptedFee: Future[NativeAmount] = feeStats.map(_.chargedFees.min)
val percentileFee99: Future[NativeAmount] =
  feeStats.map(_.chargedFees.percentiles(99))

Ledgers

s represent the state of the network at any time. They are created sequentially as the state of the network changes.

It is possible to stream all ledgers or query for a specific ledger by its sequential id. Each returned value provides meta-data about the changes in that ledger, as well as a summary of the network at that point of time.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

// details of a specific ledger
val ledger: Future[LedgerResponse] = TestNetwork.ledger(1234)

// stream of all ledgers
val ledgers: Future[LazyList[LedgerResponse]] = TestNetwork.ledgers()

// stream of the last 20 ledgers
val last20Ledgers =
  TestNetwork.ledgers(cursor = Now, order = Desc).map(_.take(20))

Network Info

Meta information about the network itself is available via the info() endpoint. Data provided in the response includes the network passphrase, software versions for Horizon and Core, the current and max supported core protocol versions, and the earliest and latest ledger ids.

val info: Future[NetworkInfo] = TestNetwork.info()
val passphrase: Future[String] = info.map(_.passphrase)

Offers

s can be issued by accounts to buy or sell assets. Querying for offers is available only by account. Additional offers are found by searching the OrderBook.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

// all offers for a specified account
val offersByAccount: Future[LazyList[OfferResponse]] =
  TestNetwork.offersByAccount(publicKey)

// most recent offers from a specified account
val last20Offers = TestNetwork
  .offersByAccount(publicKey, order = Desc, cursor = Now).map(_.take(20))

Operations

s are changes to the ledger. They represent the action, as opposed to the effects resulting from the action.

Operations returned by these queries are wrapped in the type. This indicates that the operation has been part of a successful transaction, and provides details about that transaction.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

There are several ways to search for and filter operations.

// details of a specific operation
val operation: Future[Transacted[Operation]] = TestNetwork.operation(1234)

// stream of all operations
val operations: Future[LazyList[Transacted[Operation]]] = TestNetwork.operations()

// stream of operations from a specified account
val opsForAccount: Future[LazyList[Transacted[Operation]]] =
  TestNetwork.operationsByAccount(publicKey)

// stream of operations from a specified ledger
val opsForLedger: Future[LazyList[Transacted[Operation]]] =
  TestNetwork.operationsByLedger(1234)

// stream of operations from a transaction specified by its hash
val opsForTxn: Future[LazyList[Transacted[Operation]]] =
  TestNetwork.operationsByTransaction("f00cafe...")

OrderBook

s include all the offers to buy or sell a specific asset. They show the depth limited to the value of the limit param, which defaults to 20.

// the XLM/HUG orderbook with up to 20 offers
val hugOrderBook: Future[OrderBook] = TestNetwork.orderBook(
  selling = NativeAsset,
  buying = Asset("HUG", publicKey)
)

// the FabulousBeer/HUG orderbook with up to 100 offers
val beerForHugsBigOrderBook: Future[OrderBook] =
  TestNetwork.orderBook(
    selling = Asset("FabulousBeer", publicKey),
    buying = Asset("HUG", publicKey),
    limit = 100
  )

Payments

s are the subset of Operations that cause payments to be made to an account. This is similar to the Operations query methods, but will only return CreateAccount and Payment operations.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

// stream of all payment operations
val payments: Future[LazyList[Transacted[PayOperation]]] = TestNetwork.payments()

// stream of payment operations involving a specified account
val accountPayments = TestNetwork.paymentsByAccount(publicKey)

// stream of payment operations in a specified ledger
val ledgerPayments = TestNetwork.paymentsByLedger(1234)

// stream of payment operations in a specified transaction
val transactionPayments = TestNetwork.paymentsByTransaction("bee042...")

Payment Paths

In order for a cross-token payment to find the most cost-efficient path through the offers in the distributed ledger, it is necessary to query the network for the available pathways, given the current orderbooks.

s document the source & destination amounts - along with any intermediate assets that would fulfil a path payment.

Trades

s are created when offers in an orderbook are partially or fully matched.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

// stream of all trades
val trades: Future[LazyList[Trade]] = TestNetwork.trades()

// stream of trades belonging to a specified orderbook
val orderBookTrades: Future[LazyList[Trade]] = TestNetwork.tradesByOrderBook(
  base = NativeAsset,
  counter = Asset("HUG", publicKey)
)

// stream of trades that are created as a result of the specified offer
val offerBookTrades: Future[LazyList[Trade]] = TestNetwork.tradesByOfferId(1234)

Trade Aggregations

s are summaries of historical trade data for a given asset pair, time period and time resolution.

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

// stream of all trades
val trades: Future[LazyList[Trade]] = TestNetwork.trades()

// stream of trades belonging to a specified orderbook
val orderBookTrades: Future[LazyList[Trade]] = TestNetwork.tradesByOrderBook(
  base = NativeAsset,
  counter = Asset("HUG", publicKey)
)

// stream of trades that are created as a result of the specified offer
val offerBookTrades: Future[LazyList[Trade]] = TestNetwork.tradesByOfferId(1234)

Transactions

By default the results will be in ascending order from the earliest record. This behaviour can be modified with the cursor and order parameters.

Transactions are the fundamental unit of change in the network and are composed of at least one and at most 100 operations. These queries return validated transactions, in the form of responses (as opposed to transactions that are composed and submitted to the network).

// details of a specific transaction
val transaction: Future[TransactionHistory] =
  TestNetwork.transaction(transactionIdString)

// stream of all transactions
val transactions: Future[LazyList[TransactionHistory]] =
  TestNetwork.transactions()

// stream of transactions affecting the specified account
val accountTxns = TestNetwork.transactionsByAccount(publicKey)

// stream of transactions within the specified ledger
val ledgerTxns = TestNetwork.transactionsByLedger(1234)

Continue reading to learn how to subscribe and respond to future events via Sources.