/stellar_sdk

Elixir library to interact with the Stellar blockchain

Primary LanguageElixirMIT LicenseMIT

Elixir Stellar SDK

stability-beta Build Badge Coverage Status Version Badge Downloads Badge License badge OpenSSF Best Practices OpenSSF Scorecard

The Stellar SDK enables the construction, signing and encoding of Stellar transactions and operations in Elixir, as well as provides a client for interfacing with Horizon server REST endpoints to retrieve ledger information, and to submit transactions.

This library is aimed at developers building Elixir applications that interact with the Stellar network.

Note

If you are a smart contract developer building on Soroban, we recommend using Soroban.ex, a library built on top of Stellar SDK which offers a developer-friendly interface for interacting with Soroban smart contracts and Soroban-RPC server.

Protocol Version Support

Protocol Version
18 >= v0.8
19 >= v0.9
20 >= v0.20
21 >= v0.21.2

Documentation

The Stellar SDK is composed of two complementary components: TxBuild + Horizon.

Installation

Available in Hex, add stellar_sdk to your list of dependencies in mix.exs:

def deps do
  [
    {:stellar_sdk, "~> 0.21.2"}
  ]
end

Configuration

The default HTTP Client is :hackney. Options to :hackney can be passed through configuration params.

config :stellar_sdk, hackney_opts: [{:connect_timeout, 1000}, {:recv_timeout, 5000}]

Custom HTTP Client

Stellar allows you to use your HTTP client of choice. Specification in Stellar.Horizon.Client.Spec

config :stellar_sdk, :http_client_impl, YourApp.CustomClientImpl

Building transactions

Accounts

Accounts are the central data structure in Stellar. They hold balances, sign transactions, and issue assets. All entries that persist on the ledger are owned by a particular account.

# initialize an account
account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

Muxed accounts

A muxed (or multiplexed) account is an account that exists “virtually” under a traditional Stellar account address. It combines the familiar GABC... address with a 64-bit integer ID and can be used to distinguish multiple “virtual” accounts that share an underlying “real” account. More details in CAP-27.

# initialize an account with a muxed address
account = Stellar.TxBuild.Account.new("MBXV5U2D67J7HUW42JKBGD4WNZON4SOPXXDFTYQ7BCOG5VCARGCRMAAAAAAAAAAAARKPQ")

account.account_id
# GBXV5U2D67J7HUW42JKBGD4WNZON4SOPXXDFTYQ7BCOG5VCARGCRMQQH

account.muxed_id
# 4

Create a muxed account

# create a muxed account
account = Stellar.TxBuild.Account.create_muxed("GBXV5U2D67J7HUW42JKBGD4WNZON4SOPXXDFTYQ7BCOG5VCARGCRMQQH", 4)

account.address
# MBXV5U2D67J7HUW42JKBGD4WNZON4SOPXXDFTYQ7BCOG5VCARGCRMAAAAAAAAAAAARKPQ

KeyPairs

Stellar relies on public key cryptography to ensure that transactions are secure: every account requires a valid keypair consisting of a public key and a private key.

# generate a random key pair
{public_key, secret_seed} = Stellar.KeyPair.random()

# derive a key pair from a secret seed
{public_key, secret_seed} = Stellar.KeyPair.from_secret_seed("SA33J3ACZZCV35FNSS655WXLIPTQOJS6WPQCKKYJSREDQY7KRLECEZSZ")

Transactions

Transactions are commands that modify the ledger state. They consist of a list of operations (up to 100) used to send payments, enter orders into the decentralized exchange, change settings on accounts, and authorize accounts to hold assets.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# initialize a transaction
Stellar.TxBuild.new(source_account) # network_passphrase defaults to Stellar.Network.testnet_passphrase()

# initialize a transaction with options
# allowed options: network_passphrase, memo, sequence_number, base_fee, preconditions
Stellar.TxBuild.new(source_account, network_passphrase: Stellar.Network.public_passphrase(), memo: memo, sequence_number: sequence_number)

Memos

A memo contains optional extra information for the transaction. Memos can be one of the following types:

  • MEMO_TEXT : A string encoded using either ASCII or UTF-8, up to 28-bytes long.
  • MEMO_ID A 64 bit unsigned integer.
  • MEMO_HASH : A 32 byte hash.
  • MEMO_RETURN : A 32 byte hash intended to be interpreted as the hash of the transaction the sender is refunding.
# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# build a memo
memo = Stellar.TxBuild.Memo.new(:none)
memo = Stellar.TxBuild.Memo.new(text: "MEMO")
memo = Stellar.TxBuild.Memo.new(id: 123_4565)
memo = Stellar.TxBuild.Memo.new(hash: "0859239b58d3f32972fc9124559cea7251225f2dbc6f0d83f67dc041e6608510")
memo = Stellar.TxBuild.Memo.new(return: "d83f67dc041e66085100859239b58d3f32924559cea72512272fc915f2dbc6f0")

# add a memo for the transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.add_memo(memo)

Sequence number

Each transaction has a sequence number associated with the source account. Transactions follow a strict ordering rule when it comes to processing transactions per account in order to prevent double-spending.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# fetch next account's sequence number from Horizon
{:ok, seq_num} =
  Stellar.Horizon.Accounts.fetch_next_sequence_number(
    Stellar.Horizon.Server.testnet(),
    "GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW"
  )

# set the sequence number
sequence_number = Stellar.TxBuild.SequenceNumber.new(seq_num)

# set the sequence number for the transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.set_sequence_number(sequence_number)

Base fee

Each transaction incurs a fee, which is paid by the source account. When you submit a transaction, you set the maximum that you are willing to pay per operation, but you’re charged the minimum fee possible based on network activity.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# build a fee
base_fee = Stellar.TxBuild.BaseFee.new(1_000)

# set a fee for the transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.set_base_fee(base_fee)

Preconditions

Proposed on the Stellar protocol-19 implementation, Preconditions are conditions that determines if a transaction is valid or not, and implements the following conditions:

  • Time bounds: TimeBounds are optional UNIX timestamps (in seconds), determined by ledger time. A lower and upper bound of when this transaction will be valid.

  • Ledger bounds: LedgerBounds are like Time Bounds, except they apply to ledger numbers. With them set, a transaction will only be valid for ledger numbers that fall into the range you set.

  • Minimum Sequence Number: Minimum sequence number if is set, the transaction will only be valid when S (the minimum sequence number) satisfies minSeqNum <= S < tx.seqNum. If is not set, the default behavior applies (the transaction’s sequence number must be exactly one greater than the account’s sequence number)

  • Minimum Sequence Age: Minimum sequence age is based on the account's sequence number age. When is set, the transaction is only valid after a particular duration (in seconds) elapses since the account’s sequence number age.

  • Minimum Sequence Ledger Gap: Minimum sequence ledger gap is based on the account's sequence number age, this is similar to the minimum sequence age, except it’s expressed as a number of ledgers rather than a duration of time.

  • Extra Signers: A transaction can specify up to two Extra signers (of any type) even if those signatures would not otherwise be required to authorize the transaction.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# TimeBounds ---------------------------------------------------------------------------

# no time bounds for a transaction
time_bounds = Stellar.TxBuild.TimeBounds.new(:none)

# time bounds using UNIX timestamps
time_bounds = Stellar.TxBuild.TimeBounds.new(
    min_time: 1_643_558_792,
    max_time: 1_643_990_815
  )

# time bounds using DateTime
time_bounds = Stellar.TxBuild.TimeBounds.new(
    min_time: ~U[2022-01-30 16:06:32.963238Z],
    max_time: ~U[2022-02-04 16:06:55.734317Z]
  )

# timeout
time_bounds = Stellar.TxBuild.TimeBounds.set_timeout(1_643_990_815)

# LedgerBounds -------------------------------------------------------------------------

# no ledger bounds for a transaction
ledger_bounds = Stellar.TxBuild.LedgerBounds.new(:none)

# ledger bounds with ledger numbers
ledger_bounds = Stellar.TxBuild.LedgerBounds.new(min_ledger: 0, max_ledger: 1_234_567_890)

# SequenceNumber -----------------------------------------------------------------------

# minimum sequence number for a transaction with value 0
min_seq_num = Stellar.TxBuild.SequenceNumber.new()

# minimum sequence number
min_seq_num = Stellar.TxBuild.SequenceNumber.new(1_000_000)

# ExtraSigners

extra_signers = ["GA2YG3YULNTUEMMLN4HUQVL7B37GJTYSRZYH6HZUFLXFDCCGKLXIXMDT"]

# Preconditions ------------------------------------------------------------------------

preconditions =
  Stellar.TxBuild.Preconditions.new(
    time_bounds: time_bounds,
    ledger_bounds: ledger_bounds,
    min_seq_num: min_seq_num,
    min_seq_age: 30,
    min_seq_ledger_gap: 5,
    extra_signers: extra_signers
  )

# set the preconditions for the transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.set_preconditions(preconditions)

Operations

Operations represent a desired change to the ledger: payments, offers to exchange currency, changes made to account options, etc. Operations are submitted to the Stellar network grouped in a Transaction. Single transactions may have up to 100 operations.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# build a create_account operation
# the destination account does not exist in the ledger
create_account_op = Stellar.TxBuild.CreateAccount.new(
    destination: "GDWD36NCYNN4UFX63F2235QGA2XVGTXG7NQW6MN754SHTQM4XSLTXLYK",
    starting_balance: 2
  )

# build a payment operation
# the destination account should exist in the ledger
payment_op = Stellar.TxBuild.Payment.new(
    destination: "GDWD36NCYNN4UFX63F2235QGA2XVGTXG7NQW6MN754SHTQM4XSLTXLYK",
    asset: :native,
    amount: 5
  )

# add a single operation to a transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.add_operation(create_account_op)


# add multiple operations to a transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.add_operations([create_account_op, payment_op])

Signing and multi-sig

Stellar uses signatures as authorization. Transactions always need authorization from at least one public key in order to be considered valid.

It is possible to use different signature types settled by the SetOptions operation into the network.

# ed25519
# ed25519 keypair or ed25519 secret key.
signer_key_pair = Stellar.KeyPair.from_secret_seed("SBJJSBBXGKNXALBZ3F3UTHAPKJSESACSKPLW2ZEMM5E5WPVNNKTW55XN")
signature = Stellar.TxBuild.Signature.new(signer_key_pair)

signature = Stellar.TxBuild.Signature.new(ed25519: "SC7SEV3LXAIA727BI3QY67YMHXXNWATIZEW7GY4DUSR6KDVGMF546W7T")

# hash_x
# signatures of type hash(x) require the preimage (x) in hex generated by a 256-bit random value.
signature = Stellar.TxBuild.Signature.new(hash_x: "dea550a5e5897ef98a37a828e183d8d313486159329df646c1137147e766282c")

# signed_payload - {payload, ed25519}
# payload is a hex string, maximum 32 bytes.
# ed25519 is a ed25519 secret key.
signature =
  Stellar.TxBuild.Signature.new(
    signed_payload: [
      payload: "01020304",
      ed25519: "SACHJRYLY43MUXRRCRFA6CZ5ZW5JVPPR4CWYWIX6BWRAOHOFVPVYDO5Z"
    ]
  )

In some cases, a transaction may need more than one signature. If the transaction has operations with multiple source accounts, it requires the source account signature for each operation. Additional signatures are required if the account associated with the transaction has multiple public keys.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# build an operation
# the destination account should exist in the ledger
operation = Stellar.TxBuild.Payment.new(
    destination: "GDWD36NCYNN4UFX63F2235QGA2XVGTXG7NQW6MN754SHTQM4XSLTXLYK",
    asset: :native,
    amount: 5
  )

# build transaction signatures
# signer accounts should exist in the ledger
signature1 = Stellar.TxBuild.Signature.new(ed25519: "SBJJSBBXGKNXALBZ3F3UTHAPKJSESACSKPLW2ZEMM5E5WPVNNKTW55XN")
signature2 = Stellar.TxBuild.Signature.new(ed25519: "SA2NWVOPQMQYAU5RATOE7HJLMPLQZRNPGSOQGGEG6P2ZSYTWFORY5AV5")

# add a single signature to a transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.add_operation(operation)
  |> Stellar.TxBuild.sign(signature1)


# add multiple signatures to a transaction
{:ok, tx_build} =
  source_account
  |> Stellar.TxBuild.new()
  |> Stellar.TxBuild.add_operation(operation)
  |> Stellar.TxBuild.sign([signature1, signature2])

Transaction envelope

Once a transaction has been filled out, it is wrapped in a Transaction envelope containing the transaction as well as a set of signatures.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# build an operation
# the destination account should exist in the ledger
operation = Stellar.TxBuild.Payment.new(
    destination: "GDWD36NCYNN4UFX63F2235QGA2XVGTXG7NQW6MN754SHTQM4XSLTXLYK",
    asset: :native,
    amount: 5
  )

# build the transaction signatures
# signer account should exist in the ledger
signature = Stellar.TxBuild.Signature.new(ed25519: "SBJJSBBXGKNXALBZ3F3UTHAPKJSESACSKPLW2ZEMM5E5WPVNNKTW55XN")

# build a base64 transaction envelope
source_account
|> Stellar.TxBuild.new()
|> Stellar.TxBuild.add_operation(operation)
|> Stellar.TxBuild.sign(signature)
|> Stellar.TxBuild.envelope()

{:ok, "AAAAAgAAAACuy1AULv6LOdXRYjVYl9u0g62aLg/LPRx+KKAgsCUp2wAAAGQAAA+pAAAAFAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAL5xix0HYeCnnvADhMs2eqCLBfE+WT3Kh7axgdzPzWX0AAAAAAAAAAAC+vCAAAAAAAAAAAKwJSnbAAAAQMhnGfygZvau5bXFHnJ1rCLIiqiZiI+C4Xf4bWCrxTERPOM/nJKuDottj48bep8NlI42WIUgqZVeQAKykWE74AXPzWX0AAAAQHp0wWKyv80frbOkX3QgOFtflxExX9H46b8ws8fMznSt6/9Le567cqoPxLb/SYvw3Wh6j3B5Vl04CBWyKnLYUwg="}

Submitting a transaction

The transaction can now be submitted to the Stellar network.

# set the source account (this account should exist in the ledger)
source_account = Stellar.TxBuild.Account.new("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# fetch next account's sequence number from Horizon
{:ok, seq_num} = Stellar.Horizon.Accounts.fetch_next_sequence_number("GDC3W2X5KUTZRTQIKXM5D2I5WG5JYSEJQWEELVPQ5YMWZR6CA2JJ35RW")

# set the sequence number
sequence_number = Stellar.TxBuild.SequenceNumber.new(seq_num)

# set a memo
memo = Stellar.TxBuild.Memo.new(text: "MEMO")

# build an operation
# the destination account should exist in the ledger
operation = Stellar.TxBuild.Payment.new(
    destination: "GDWD36NCYNN4UFX63F2235QGA2XVGTXG7NQW6MN754SHTQM4XSLTXLYK",
    asset: :native,
    amount: 5
  )

# build the transaction signatures
# signer account should exist in the ledger
signature = Stellar.TxBuild.Signature.new(ed25519: "SBJJSBBXGKNXALBZ3F3UTHAPKJSESACSKPLW2ZEMM5E5WPVNNKTW55XN")

# build a base64 transaction envelope
{:ok, base64_envelope} =
  source_account
  |> Stellar.TxBuild.new(sequence_number: sequence_number)
  |> Stellar.TxBuild.add_memo(memo)
  |> Stellar.TxBuild.add_operation(operation)
  |> Stellar.TxBuild.sign(signature)
  |> Stellar.TxBuild.envelope()

# submit transaction to Horizon
{:ok, submitted_tx} = Stellar.Horizon.Transactions.create(base64_envelope)

More examples can be found in the tests.

Querying Horizon

Horizon is an API for interacting with the Stellar network.

To query Horizon, you need to specify the Horizon server to use.

# public horizon server
Stellar.Horizon.Server.public()

# testnet horizon server
Stellar.Horizon.Server.testnet()

# futurenet horizon server
Stellar.Horizon.Server.futurenet()

# local horizon server
Stellar.Horizon.Server.local()

# custom horizon server
Stellar.Horizon.Server.new("https://horizon-standalone.com")

See Stellar.Horizon.Server for more details.

To make it possible to explore the millions of records for resources like transactions and operations, this library paginates the data it returns for collection-based resources. Each individual transaction, operation, ledger, etc. is returned as a record.

{:ok,
 %Ledger{
   base_fee_in_stroops: 100,
   closed_at: ~U[2015-09-30 17:16:29Z],
   failed_transaction_count: 0,
   fee_pool: 3.0e-5,
   ...
 }} = Ledgers.retrieve(Stellar.Horizon.Server.testnet(), 1234)

A group of records is called a collection, records are returned as a list in the Stellar.Horizon.Collection structure. To move between pages of a collection of records, use the next and prev attributes.

{:ok,
 %Stellar.Horizon.Collection{
   next: #Function<1.1390483/0 in Stellar.Horizon.Collection.paginate/1>,
   prev: #Function<1.1390483/0 in Stellar.Horizon.Collection.paginate/1>,
   records: [
     %Stellar.Horizon.Ledger{...},
     %Stellar.Horizon.Ledger{...},
     %Stellar.Horizon.Ledger{...}
   ]
 }} = Stellar.Horizon.Ledgers.all(Stellar.Horizon.Server.testnet())

Pagination

The HAL format links returned with the Horizon response are converted into functions you can call on the returned structure. This allows you to simply use next.() and prev.() to page through results.

{:ok,
 %Stellar.Horizon.Collection{
   next: paginate_next_fn,
   prev: paginate_prev_fn,
   records: [...]
 }} = Stellar.Horizon.Transactions.all(Stellar.Horizon.Server.testnet())

# next page records for the collection
paginate_next_fn.()

{:ok,
 %Stellar.Horizon.Collection{
   next: paginate_next_fn,
   prev: paginate_prev_fn,
   records: [...]
 }}

# prev page records for the collection
paginate_prev_fn.()

{:ok,
 %Stellar.Horizon.Collection{
   next: paginate_next_fn,
   prev: paginate_prev_fn,
   records: []
 }}

Accounts

# retrieve an account
Stellar.Horizon.Accounts.retrieve(
  Stellar.Horizon.Server.testnet(),
  "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)

# fetch the ledger's sequence number for the account
Stellar.Horizon.Accounts.fetch_next_sequence_number(
  Stellar.Horizon.Server.testnet(),
  "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)

# list accounts
Stellar.Horizon.Accounts.all(
  Stellar.Horizon.Server.testnet(),
  limit: 10,
  order: :asc
)

# list accounts by sponsor
Stellar.Horizon.Accounts.all(
  Stellar.Horizon.Server.testnet(),
  sponsor: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)

# list accounts by signer
Stellar.Horizon.Accounts.all(
  Stellar.Horizon.Server.testnet(),
  signer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  order: :desc
)

# list accounts by canonical asset address
Stellar.Horizon.Accounts.all(
  Stellar.Horizon.Server.testnet(),
  asset: "TEST:GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  limit: 20
)

# list account's transactions
Stellar.Horizon.Accounts.list_transactions(
  Stellar.Horizon.Server.testnet(),
  "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  limit: 20
)

# list account's payments
Stellar.Horizon.Accounts.list_payments(
  Stellar.Horizon.Server.testnet(),
  "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  limit: 20
)

See Stellar.Horizon.Accounts for more details.

Transactions

# submit a transaction
Stellar.Horizon.Transactions.create(Stellar.Horizon.Server.testnet(), base64_tx_envelope)

# retrieve a transaction
Stellar.Horizon.Transactions.retrieve(Stellar.Horizon.Server.testnet(), "5ebd5c0af4385500b53dd63b0ef5f6e8feef1a7e1c86989be3cdcce825f3c0cc")

# list transactions
Stellar.Horizon.Transactions.all(Stellar.Horizon.Server.testnet(), limit: 10, order: :asc)

# include failed transactions
Stellar.Horizon.Transactions.all(Stellar.Horizon.Server.testnet(), limit: 10, include_failed: true)

# list transaction's effects
Stellar.Horizon.Transactions.list_effects(
  Stellar.Horizon.Server.testnet(),
  "6b983a4e0dc3c04f4bd6b9037c55f70a09c434dfd01492be1077cf7ea68c2e4a",
  limit: 20
)

# list transaction's operations
Stellar.Horizon.Transactions.list_operations(
  Stellar.Horizon.Server.testnet(),
  "6b983a4e0dc3c04f4bd6b9037c55f70a09c434dfd01492be1077cf7ea68c2e4a",
  limit: 20
)

# join transactions in the operations response
Stellar.Horizon.Transactions.list_operations(
  Stellar.Horizon.Server.testnet(),
  "6b983a4e0dc3c04f4bd6b9037c55f70a09c434dfd01492be1077cf7ea68c2e4a",
  join: "transactions"
)

See Stellar.Horizon.Transactions for more details.

Operations

# retrieve an operation
Stellar.Horizon.Operations.retrieve(Stellar.Horizon.Server.testnet(), 121693057904021505)

# list operations
Stellar.Horizon.Operations.all(Stellar.Horizon.Server.testnet(), limit: 10, order: :asc)

# include failed operations
Stellar.Horizon.Operations.all(Stellar.Horizon.Server.testnet(), limit: 10, include_failed: true)

# include operation's transactions
Stellar.Horizon.Operations.all(Stellar.Horizon.Server.testnet(), limit: 10, join: "transactions")

# list operation's payments
Stellar.Horizon.Operations.list_payments(Stellar.Horizon.Server.testnet(), limit: 20)

# list operation's effects
Stellar.Horizon.Operations.list_effects(Stellar.Horizon.Server.testnet(), 121693057904021505, limit: 20)

See Stellar.Horizon.Operations for more details.

Assets

# list ledger's assets
Stellar.Horizon.Assets.all(Stellar.Horizon.Server.testnet(), limit: 20, order: :desc)

# list assets by asset issuer
Stellar.Horizon.Assets.all(Stellar.Horizon.Server.testnet(), asset_issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD")

# list assets by asset code
Stellar.Horizon.Assets.list_by_asset_code(Stellar.Horizon.Server.testnet(), "TEST")
Stellar.Horizon.Assets.all(Stellar.Horizon.Server.testnet(), asset_code: "TEST")

# list assets by asset issuer
Stellar.Horizon.Assets.all(
  Stellar.Horizon.Server.testnet(),
  asset_issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)
Stellar.Horizon.Assets.list_by_asset_issuer(
  Stellar.Horizon.Server.testnet(),
  "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)

See Stellar.Horizon.Assets for more details.

Ledgers

# retrieve a ledger
Stellar.Horizon.Ledgers.retrieve(Stellar.Horizon.Server.testnet(), 27147222)

# list ledgers
Stellar.Horizon.Ledgers.all(Stellar.Horizon.Server.testnet(), limit: 10, order: :asc)

# list ledger's transactions
Stellar.Horizon.Ledgers.list_transactions(Stellar.Horizon.Server.testnet(), 27147222, limit: 20)

# list ledger's operations
Stellar.Horizon.Ledgers.list_operations(Stellar.Horizon.Server.testnet(), 27147222, join: "transactions")

# list ledger's payments including failed transactions
Stellar.Horizon.Ledgers.list_payments(Stellar.Horizon.Server.testnet(), 27147222, include_failed: true)

# list ledger's effects
Stellar.Horizon.Ledgers.list_effects(Stellar.Horizon.Server.testnet(), 27147222, limit: 20)

See Stellar.Horizon.Ledgers for more details.

Offers

# list offers
Stellar.Horizon.Offers.all(Stellar.Horizon.Server.testnet(), limit: 20, order: :asc)

# list offers by sponsor
Stellar.Horizon.Offers.all(
  Stellar.Horizon.Server.testnet(),
  sponsor: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)

# list offers by seller
Stellar.Horizon.Offers.all(
  Stellar.Horizon.Server.testnet(),
  seller: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  order: :desc
)

# list offers by selling_asset
Stellar.Horizon.Offers.all(
  Stellar.Horizon.Server.testnet(),
  selling_asset: [
    code: "TEST",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ]
)

# list offers by buying_asset
Stellar.Horizon.Offers.all(
  Stellar.Horizon.Server.testnet(),
  buying_asset: [
    code: "TEST",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ]
)

# list offers by selling_asset and buying_asset
Stellar.Horizon.Trades.all(
  Stellar.Horizon.Server.testnet(),
  selling_asset: [
    code: "TEST",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ],
  buying_asset: [
    code: "TOKEN",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ]
)

Stellar.Horizon.Offers.all(
  Stellar.Horizon.Server.testnet(),
  selling_asset: [
    code: "TEST",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ],
  buying_asset: :native
)

# list offer's trades
Stellar.Horizon.Offers.list_trades(Stellar.Horizon.Server.testnet(), 165563085, limit: 20)

See Stellar.Horizon.Offers for more details.

Trades

# list tardes
Stellar.Horizon.Trades.all(Stellar.Horizon.Server.testnet(), limit: 20, order: :asc)

# list trades by offer_id
Stellar.Horizon.Trades.all(Stellar.Horizon.Server.testnet(), offer_id: 165563085)

# list trades by specific orderbook
Stellar.Horizon.Trades.all(
  Stellar.Horizon.Server.testnet(),
  base_asset: [
    code: "TEST",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ],
  counter_asset: [
    code: "TOKEN",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ]
)

Stellar.Horizon.Trades.all(
  Stellar.Horizon.Server.testnet(),
  base_asset: [
    code: "TEST",
    issuer: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
  ],
  counter_asset: :native
)

# list trades by trade_type
Stellar.Horizon.Trades.all(Stellar.Horizon.Server.testnet(), trade_type: "liquidity_pools", limit: 20)

See Stellar.Horizon.Trades for more details.

ClaimableBalances

# retrieve a claimable balance
Stellar.Horizon.ClaimableBalances.retrieve(
  Stellar.Horizon.Server.testnet(),
  "00000000ca6aba5fb0993844e0076f75bee53f2b8014be29cd8f2e6ae19fb0a17fc68695"
)

# list claimable balances
Stellar.Horizon.ClaimableBalances.all(Stellar.Horizon.Server.testnet(), limit: 2, order: :asc)

# list claimable balances by sponsor
Stellar.Horizon.ClaimableBalances.list_by_sponsor(
  Stellar.Horizon.Server.testnet(),
  "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)
Stellar.Horizon.ClaimableBalances.all(
  Stellar.Horizon.Server.testnet(),
  sponsor: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)

# list claimable balances by claimant
Stellar.Horizon.ClaimableBalances.list_by_claimant(
  Stellar.Horizon.Server.testnet(),
  "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)
Stellar.Horizon.ClaimableBalances.all(
  Stellar.Horizon.Server.testnet(),
  claimant: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  order: :desc
)

# list claimable balances by canonical asset address
Stellar.Horizon.ClaimableBalances.list_by_asset(
  Stellar.Horizon.Server.testnet(),
  "TEST:GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD"
)
Stellar.Horizon.ClaimableBalances.all(
  Stellar.Horizon.Server.testnet(),
  asset: "TEST:GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  limit: 20
)

# list claimable balance's transactions
Stellar.Horizon.ClaimableBalances.list_transactions(
  Stellar.Horizon.Server.testnet(),
  "00000000ca6aba5fb0993844e0076f75bee53f2b8014be29cd8f2e6ae19fb0a17fc68695",
  limit: 20
)

# list claimable balance's operations
Stellar.Horizon.ClaimableBalances.list_operations(
  Stellar.Horizon.Server.testnet(),
  "00000000ca6aba5fb0993844e0076f75bee53f2b8014be29cd8f2e6ae19fb0a17fc68695",
  limit: 20
)

# join transactions in the operations response
Stellar.Horizon.ClaimableBalances.list_operations(
  Stellar.Horizon.Server.testnet(),
  "00000000ca6aba5fb0993844e0076f75bee53f2b8014be29cd8f2e6ae19fb0a17fc68695",
  join: "transactions"
)

See Stellar.Horizon.Balances for more details.

LiquidityPools

# retrieve a liquidity pool
Stellar.Horizon.LiquidityPools.retrieve(
  Stellar.Horizon.Server.testnet(),
  "001365fc79ca661f31ba3ee0849ae4ba36f5c377243242d37fad5b1bb8912dbc"
)

# list liquidity pools
Stellar.Horizon.LiquidityPools.all(Stellar.Horizon.Server.testnet(), limit: 2, order: :asc)

# list liquidity pools by reserves
Stellar.Horizon.LiquidityPools.all(
  Stellar.Horizon.Server.testnet(),
  reserves: "TEST:GCXMW..., TEST2:GCXMW..."
)

# list liquidity pools by account
Stellar.Horizon.LiquidityPools.all(
  Stellar.Horizon.Server.testnet(),
  account: "GCXMWUAUF37IWOOV2FRDKWEX3O2IHLM2FYH4WPI4PYUKAIFQEUU5X3TD",
  order: :desc
)

# list liquidity pool's effects
Stellar.Horizon.LiquidityPools.list_effects(
  Stellar.Horizon.Server.testnet(),
  "001365fc79ca661f31ba3ee0849ae4ba36f5c377243242d37fad5b1bb8912dbc",
  limit: 20
)

# list liquidity pool's trades
Stellar.Horizon.LiquidityPools.list_trades(
  Stellar.Horizon.Server.testnet(),
  "001365fc79ca661f31ba3ee0849ae4ba36f5c377243242d37fad5b1bb8912dbc",
  limit: 20
)

# list liquidity pool's transactions
Stellar.Horizon.LiquidityPools.list_transactions(
  Stellar.Horizon.Server.testnet(),
  "001365fc79ca661f31ba3ee0849ae4ba36f5c377243242d37fad5b1bb8912dbc",
  limit: 20
)

# list liquidity pool's operations
Stellar.Horizon.LiquidityPools.list_operations(
  Stellar.Horizon.Server.testnet(),
  "001365fc79ca661f31ba3ee0849ae4ba36f5c377243242d37fad5b1bb8912dbc",
  limit: 20
)

See Stellar.Horizon.Pools for more details.

Effects

# list effects
Stellar.Horizon.Effects.all(
  Stellar.Horizon.Server.testnet(),
  limit: 10,
  order: :asc
)

See Stellar.Horizon.Effects for more details.

FeeStats

# retrieve fee stats
Stellar.Horizon.FeeStats.retrieve(Stellar.Horizon.Server.testnet())

See Stellar.Horizon.FeeStats for more details.

Paths

List paths

This will return information about potential path payments:

  • [Required] source_account. The Stellar address of the sender.
  • [Required] destination_asset. :native or [code: "DESTINATION_ASSET_CODE", issuer: "DESTINATION_ASSET_ISSUER"].
  • [Required] destination_amount. The destination amount specified in the search that found this path.
  • [Optional] destination_account. The Stellar address of the reciever.
Stellar.Horizon.PaymentPaths.list_paths(
  Stellar.Horizon.Server.testnet(),
  source_account: "GBRSLTT74SKP62KJ7ENTMP5V4R7UGB6E5UQESNIIRWUNRCCUO4ZMFM4C",
  destination_asset: :native,
  destination_amount: 5
)

List strict receive payment paths

  • [Required] destination_asset. :native or [code: "DESTINATION_ASSET_CODE", issuer: "DESTINATION_ASSET_ISSUER"].
  • [Required] destination_amount. The amount of the destination asset that should be received.
  • [Optional] source_account. The Stellar address of the sender.
  • [Optional] source_assets. A comma-separated list of assets available to the sender.
Stellar.Horizon.PaymentPaths.list_receive_paths(
  Stellar.Horizon.Server.testnet(),
  destination_asset: :native,
  destination_amount: 5,
  source_account: "GBTKSXOTFMC5HR25SNL76MOVQW7GA3F6CQEY622ASLUV4VMLITI6TCOO"
)

List strict send payment paths

  • [Required] source_asset. :native or [code: "SOURCE_ASSET_CODE", issuer: "SOURCE_ASSET_ISSUER"].
  • [Required] source_amount. The amount of the source asset that should be sent.
  • [Optional] destination_account. The Stellar address of the reciever.
  • [Optional] destination_assets. A comma-separated list of assets that the recipient can receive.
Stellar.Horizon.PaymentPaths.list_send_paths(
  Stellar.Horizon.Server.testnet(),
  source_asset: :native,
  source_amount: 5,
  destination_assets: "TEST:GA654JC6QLA3ZH4O5V7X5NPM7KEWHKRG5GJA4PETK4SOFBUJLCCN74KQ"
)

See Stellar.Horizon.Paths for more details.

Order Books

Retrieve order Books

Provides an order book’s bids and asks:

  • [Required] selling_asset. :native or [code: "SELLING_ASSET_CODE", issuer: "SELLING_ASSET_ISSUER"].
  • [Required] buying_asset. :native or [code: "BUYING_ASSET_CODE", issuer: "BUYING_ASSET_ISSUER"].
  • [Optional] limit. The maximum number of records returned
Stellar.Horizon.OrderBooks.retrieve(
  Stellar.Horizon.Server.testnet(),
  selling_asset: :native,
  buying_asset: :native
)

Stellar.Horizon.OrderBooks.retrieve(
  Stellar.Horizon.Server.testnet(),
  selling_asset: :native,
  buying_asset: [
    code: "BB1",
    issuer: "GD5J6HLF5666X4AZLTFTXLY46J5SW7EXRKBLEYPJP33S33MXZGV6CWFN"
  ],
  limit: 2
)

See Stellar.Horizon.OrderBooks for more details.

Trade Aggregations

List trade aggregations

Displays trade data based on filters set in the arguments:

  • [Required] base_asset. :native or [code: "BASE_ASSET_CODE", issuer: "BASE_ASSET_ISSUER"].
  • [Required] counter_asset. :native or [code: "COUNTER_ASSET_CODE", issuer: "COUNTER_ASSET_ISSUER"].
  • [Required] resolution. The segment duration represented as milliseconds.
  • [Optional] start_time. The lower time boundary represented as milliseconds since epoch.
  • [Optional] end_time. The upper time boundary represented as milliseconds since epoch.
  • [Optional] offset. Segments can be offset using this parameter. Expressed in milliseconds.
  • [Optional] order. A designation of the order in which records should appear.
  • [Optional] limit. The maximum number of records returned.
Stellar.Horizon.TradeAggregations.list_trade_aggregations(
  Stellar.Horizon.Server.testnet(),
  base_asset: :native,
  counter_asset: :native,
  resolution: "60000"
)

Stellar.Horizon.TradeAggregations.list_trade_aggregations(
  Stellar.Horizon.Server.testnet(),
  base_asset: :native,
  counter_asset: [
    code: "EURT",
    issuer: "GAP5LETOV6YIE62YAM56STDANPRDO7ZFDBGSNHJQIYGGKSMOZAHOOS2S"
  ],
  resolution: "3600000",
  start_time: "1582156800000",
  end_time: "1582178400000"
)

See Stellar.Horizon.TradeAggregations for more details.


Development

  • Install any Elixir version above 1.12.
  • Compile dependencies: mix deps.get.
  • Run tests: mix test.

Code of conduct

We welcome everyone to contribute. Make sure you have read the CODE_OF_CONDUCT before.

Contributing

For information on how to contribute, please refer to our CONTRIBUTING guide.

Changelog

Features and bug fixes are listed in the CHANGELOG file.

License

This library is licensed under an MIT license. See LICENSE for details.

Acknowledgements

Made with 💙 by kommitters Open Source