> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# Stellar

The Stellar provider extracts the Stellar network from a Stellar RPC endpoint: the JSON-RPC API Stellar provides for
apps, formerly called Soroban RPC. [Raw datasets](/datasets/raw-datasets) of kind `stellar` extract through it. Their
tables hold Stellar's ledgers, the transactions each ledger applied, and the events those transactions emitted. Their
columns are in [Stellar Tables](/datasets/tables/stellar).

:::warning
In v0.0.42, Amp extracts Stellar datasets, but can't query them: every query fails with
[`blocks table 'blocks' not found`](/providers/stellar#blocks-table-blocks-not-found-in-dataset). The query server looks for a `blocks`
table, and a Stellar dataset keeps its ledgers in `ledgers`.
:::

## Prerequisites

* A running Amp you can manage, like one in [Solo Mode](/running-amp/solo-mode).
* [`ampctl`](/clis/ampctl), which installs with Amp.
* A Stellar RPC endpoint, over HTTP or HTTPS: a Stellar RPC server you run, or a hosted one. It must serve the
  `getLatestLedger`, `getLedgers`, `getTransactions`, and `getEvents` methods, and still hold the ledgers you extract
  (see [Limitations](/providers/stellar#limitations)). Horizon, Stellar's REST API, doesn't work.
* The endpoint's URL, in the environment `ampd` runs in:

  ```bash
  export STELLAR_RPC_URL=http://localhost:8000
  ```

  Amp reads it when it extracts, from its own environment, so set it before you start `ampd`. When it's missing, the
  job fails (see [Environment variables](/providers#environment-variables)).

## Ledgers

A ledger is Stellar's equivalent of a block. Every few seconds, Stellar's validators agree on a set of transactions,
apply them, and close a ledger, numbered by its sequence number. In a `stellar` dataset, the ledger plays the part of
a block: `_block_num` is the ledger's sequence number, and the dataset's start block is one.

Stellar's consensus makes a ledger final as soon as it closes, so Amp extracts up to the latest closed ledger, and
`finalized_blocks_only` makes no difference for this kind.

## Configure the provider

A provider's configuration is a TOML file. The smallest one names the kind, the network, and the endpoint:

```toml [stellar_mainnet.toml]
kind = "stellar"
network = "stellar-mainnet"
url = "${STELLAR_RPC_URL}"
```

* `kind`: always `"stellar"`.
* `network`: the network the endpoint serves, `stellar-mainnet` or `stellar-testnet`. A dataset extracts through the
  providers whose kind and network match its own.
* `url`: the endpoint's URL. Amp sends its requests to this URL as is.

A fuller one, for a hosted endpoint that takes a token:

```toml [stellar_mainnet.toml]
kind = "stellar"
network = "stellar-mainnet"
url = "${STELLAR_RPC_URL}"
auth_token = "${STELLAR_RPC_TOKEN}"
auth_header = "x-api-key"
rate_limit_per_minute = 600
concurrent_request_limit = 8
timeout_secs = 30
```

* `auth_token`: a token Amp sends with every request, as `Authorization: Bearer <token>`.
* `auth_header`: a header to send the token in instead, here as `x-api-key: <token>`. Amp ignores it without
  `auth_token`.
* `rate_limit_per_minute`: the most requests Amp sends the endpoint per minute. There's no limit by default.
* `concurrent_request_limit`: how many ledgers Amp fetches from the endpoint at once, `8` by default and at most. Each
  ledger takes at least three requests, one after the other.
* `timeout_secs`: how long a request can take, in seconds, `30` by default.

The [Provider Configuration Reference](/providers/configuration-reference#stellar) has every field's type and default.

## Create a dataset

::::steps
### Register the provider

```bash
ampctl provider register stellar_mainnet ./stellar_mainnet.toml
```

A provider's name holds lowercase letters, digits, and underscores, and starts with a letter or an underscore.
[Providers](/providers) covers registering and replacing providers.

### Pick a start ledger

The dataset must start at a ledger the endpoint still holds. Stellar RPC's `getHealth` method returns the oldest and
latest ledgers it has:

:::terminal
```bash
curl -s "$STELLAR_RPC_URL" -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'
```

```
{"jsonrpc":"2.0","id":1,"result":{"status":"healthy","latestLedger":65272103,"latestLedgerCloseTime":"1793646299","oldestLedger":65151144,"oldestLedgerCloseTime":"1793041503","ledgerRetentionWindow":120960}}
```
:::

### Generate the manifest

`ampctl manifest generate` writes the dataset's [manifest](/datasets/manifests), with all three tables. This one
starts at ledger 65,271,900, which the endpoint above holds:

```bash
ampctl manifest generate --kind stellar --network stellar-mainnet --start-block 65271900 -o stellar_mainnet.json
```

It prints nothing. Without `--start-block`, the dataset starts at ledger 0, which no endpoint holds, and its job
fails.

### Register the dataset

```bash
ampctl dataset register acme/stellar_mainnet ./stellar_mainnet.json --tag 1.0.0
```

### Deploy it

`--end-block` stops the job at ledger 65,271,909, after 10 ledgers. Without it, the job keeps up with the network.

```bash
ampctl dataset deploy acme/stellar_mainnet@1.0.0 --end-block 65271909
```

### Check its progress

Since v0.0.42 can't query the dataset, its status is how you see what Amp extracted:

:::terminal
```bash
ampctl dataset status acme/stellar_mainnet@1.0.0
```

```
ID:              1
Status:          COMPLETED
Kind:            Raw
Dataset:         acme/stellar_mainnet@1.0.0
tables:
  events:
    files_count: 1
    total_size_bytes: 332.17 KiB
    networks:
      stellar-mainnet:
        start_block: 65271900
        current_block: 65271909
        block_timestamp: 1793645329
        delay_seconds: 989s (16 minutes)
        end_block: 65271909
  ledgers:
    …
  transactions:
    …
```
:::

[Managing Datasets](/managing-amp/datasets) covers following and stopping jobs.
::::

## What Amp extracts

For each ledger, Amp asks the endpoint for the ledger itself (`getLedgers`), then for all its transactions
(`getTransactions`) and all its events (`getEvents`), page by page. It checks that the ledger's hash matches its
header's, and retries the ledger when it doesn't.

| Table                                                   | One row per                                                                                                                                        |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`ledgers`](/datasets/tables/stellar#ledgers)           | Ledger: its header's fields, decoded, and everything the ledger did, as XDR                                                                        |
| [`transactions`](/datasets/tables/stellar#transactions) | Transaction the ledger applied, successful or failed: a decoded summary, like its source account, fee, and result, and the full transaction as XDR |
| [`events`](/datasets/tables/stellar#events)             | Event the ledger's transactions emitted, like a contract's token transfer, with its topics and value as XDR                                        |

XDR is Stellar's binary encoding. Amp stores it as base64 text, which you decode in SQL with the
[Stellar functions](/querying/functions/stellar).

## Limitations

* **Recent history only**: a Stellar RPC server keeps only its most recent ledgers, as many as its retention window
  says. Amp can't extract a ledger the endpoint no longer holds: to extract older history, use an endpoint with a
  longer retention window.
* **HTTP only**: the endpoint's URL must start with `http://` or `https://`.
* **No queries in v0.0.42**: Amp extracts the dataset, but the query server can't read it (see
  [`blocks table 'blocks' not found`](/providers/stellar#blocks-table-blocks-not-found-in-dataset)).

## Errors

### `No provider found for kind 'stellar' and network 'stellar-mainnet'`

The job found no usable provider for the dataset's kind and network. Either none is registered (list them with
`ampctl provider list`), its `network` doesn't match the dataset's exactly, or its configuration refers to an
environment variable that isn't set where `ampd` runs. In that last case, `ampd` also logs
`environment variable substitution failed for provider, skipping`: set the variable and restart `ampd`.

### `getLedgers RPC call failed for ledger 65150144`

The endpoint refused the ledger, with a message like
`start ledger (65150144) must be between the oldest ledger: 65151148 and the latest ledger: 65272107 for this rpc instance`.
Amp retries the ledger, in case another endpoint, or the same one a moment later, has it, and the job fails when it
keeps failing. A ledger before the endpoint's oldest one is gone from it for good: start the dataset at a ledger the
endpoint holds (see [Pick a start ledger](/providers/stellar#pick-a-start-ledger)), or use an endpoint that keeps more history.

### `unsupported URL scheme 'ws'`

The provider's `url` doesn't start with `http://` or `https://`, the only schemes Amp supports for Stellar RPC
endpoints. `ampctl provider register` accepts it, but the job that extracts through the provider fails at once, without
retrying, and `ampd` logs the error. Change the URL, and register the provider again.

### `blocks table 'blocks' not found in dataset`

Every query of a Stellar dataset fails in v0.0.42, like this one:

:::terminal
```bash
ampsql 'SELECT sequence, closed_at FROM "acme/stellar_mainnet".ledgers ORDER BY sequence LIMIT 3'
```

```
✗ query failed
  → gRPC status error
    → code: 'Internal error', message: "failed to resolve batch query snapshot | Caused by: failed to resolve blocks tables for batch snapshot -> blocks table 'blocks' not found in dataset 'acme/stellar_mainnet@a8630db45b07eeb8150cc96f1b30269f35c453ff671e65a320851e61d8b9bfa2' for network 'stellar-mainnet'"
```
:::

To find a dataset's latest block, the query server reads its `blocks` table, which a Stellar dataset doesn't have: its
ledgers are in `ledgers`. Nothing you configure changes it. The extracted data is intact, in Parquet files in Amp's data
directory, which other tools can read.
