Try Astrograph: Your GraphQL lens for Stellar blockchain
Blockchain meets GraphQL with the beta release of Astrograph—a robust Node/TypeScript server that provides a single endpoint to explore the entirety of the Stellar network. It also offers reliable WebSocket-based subscriptions, allowing you to build real-time tools for mature distributed ecosystems faster and with less effort. You can check out the new tool right now in our dedicated playground.
A non-profit Stellar Development Foundation is on a mission to develop the new world economy with a blockchain-based infrastructure designed for natural integration with traditional banks and payment systems. It’s based on a fast, consensus-based protocol that doesn’t involve resource-draining mining and solves the problem of transaction speeds, something that is becoming more and more of an issue in the world of Bitcoin. An integrated distributed exchange makes it easier to trade third-party currencies, including the so-called stable coins that are backed by real currency reserves (one example is the USDC).
With a focus on the real economy, Stellar becomes more and more appealing to financial institutions and large corporations that are looking into ways to move money across borders at high speeds and low costs.
After working on commercial Stellar-based solutions, we contributed to the ecosystem by co-authoring a Stellar Web Authentication proposal. Now we see an even bigger opportunity to give back to the community.
Meet Astrograph, a GraphQL interface to Stellar blockchain.
With this first beta release, we’re open sourcing a research project that we’ve been working on for the past few months. We believe that this new tool will make Stellar even more appealing to developers and lower the barrier for entry into its ecosystem.
You can experiment with GraphQL access to Stellar network by using Astrograph’s playground or by running test requests from your client applications against the API that is publicly available at https://pubnet.astrograph.io/graphql/
.
Just keep in mind: this schema is still a work in progress and is subject to change, so we don’t recommend relying on this endpoint in production.
A GraphQL alternative to Horizon
The promise of any blockchain is full accountability, and Stellar is no exception: anything that happens on a network, be it the creation of a new account, a transfer of an asset, or a token offering, is baked into the ledger. Everything that’s ever happened on the network can be scrutinized, and if you swear by the REST philosophy, Stellar has already got you covered.
While stellar-core implements the blockchain itself, a service called Horizon allows clients to explore the network by sending HTTP requests to a selection of REST API endpoints: one for accounts, one for operations, one for assets, and so on. You can also stream information from certain endpoints by subscribing to Server-Sent Events.
Being a RESTful service, Horizon comes with some inherent limitations: you either get a set of entities or a single entity, depending on the endpoint. If you need more sophisticated filtering, you first have to retrieve a large set of records from the API, then iterate over it in your application code.
Here’s a list of things that are either impossible or require some hackery to implement, like resorting to SQL queries directly into stellar-core or Horizon databases (provided you run your own nodes):
- Monitoring events concerning a specific asset. If you’re a token issuer, it’s not easy to get a grip on all the activities associated with your asset.
- Complex queries, like getting all accounts having a specific signer.
- Filtering operations for a specific account by type, asset involved, or payment destination.
That makes building complex dashboards, which are common in financial applications, less trivial than it might seem at first glance of the Horizon documentation.
As an approach, REST is perfect for the resource-oriented structure of the classic web, but it falls short when we start dealing with replicated state machines, such as Stellar.
The linked-list nature of a blockchain doesn’t map well to relational or RESTful concepts. A ledger is, in fact, an enormous graph, so it’s better to treat it like one.
Astrograph solves most of the problems above by allowing you to make infinitely flexible queries with GraphQL, a format much more suited for that purpose.
Let’s see it in action!
A single endpoint to rule them all
Getting started with Astrograph doesn’t require any installation or setup. If you’re familiar with GraphQL and basic Stellar concepts, you can go directly to the playground on the project’s website, examine the available schema, and form your own queries.
Here’s how to get information on a given account’s balance and its signers with Astrograph:
query {
account(id: "GB6NVEN5HSUBKMYCE5ZOWSK5K23TBWRUQLZY3KNMXUZ3AQ2ESC4MY4AQ") {
id
sequenceNumber
balances {
asset {
native
issuer {
id
}
code
}
balance
limit
authorized
}
signers {
signer
weight
}
}
}
You’ll achieve roughly the same result as you would by sending a traditional GET request to the Horizon’s /accounts
endpoint. In case you also need a list of the last 10 operations involving the account, you’ll need to send another request to the /operations
endpoint.
With Astrograph, you can get all the data you need in a single request to a single endpoint, just by appending a field to your GraphQL query:
query {
account(id: "GB6NVEN5HSUBKMYCE5ZOWSK5K23TBWRUQLZY3KNMXUZ3AQ2ESC4MY4AQ") {
# ...
signers {
signer
weight
}
operations(last: 10) {
nodes {
id
kind
dateTime
# Including the amount and the currency code for payments
... on PaymentOperation {
amount
asset { code }
}
}
}
}
}
Astrograph makes coming up with evolved queries easy and intuitive, as GraphQL is self-documenting by nature, and you can explore the current schema in real time.
In this early release, we support top-level queries for accounts, assets, ledgers, offers, transactions, and operations. Other Horizon endpoints such as effects or paths are still works in progress, and we’ll keep adding support for them in future releases.
Effortless real-time subscriptions
The world of finance as we know it is built on real-time tools: from ticker tape to Bloomberg Terminal and Google Finance—whoever gets their hand on the pulse of a market gets the edge—and the blockchain economy is no exception.
Stellar is designed for trading. Some of the tokens issued on a network are built to represent fiat currencies, with services like StellarX allowing you to engage in Forex-like trading entirely through the blockchain. Such platforms currently rely on Horizon streams which allow receiving push updates from select REST API endpoints.
Real-time functionality in Horizon is implemented with Server-Sent Events. For instance, if you want to follow all the operations for a given account in real time, all you have at your disposal is a regular /operations
endpoint with no filtering options. Your application will get a constant stream of all operations happening on the network, and it will be your duty to pick the ones you want. You can either do this directly on the client (while also keeping in mind that each new subscription with SSE will result in a new open HTTP connection—and there is a browser limit to the number of simultaneous per-server connections), or you can filter an incoming stream on the backend and use your own implementation of SSE or WebSockets to push relevant updates to the client.
With Astrograph, you can get just the real-time data you want without any hassle.
Subscriptions are built into a GraphQL specification and are widely supported in popular frontend and backend libraries, such as Apollo. As everything happens over WebSockets on a single connection to a single endpoint with filtering capabilities built-in, all you need to do is to write a few lines of code and let the ecosystem handle the rest. This makes developing data-intensive real-time applications like online wallets or cryptocurrency exchanges much easier from an engineering point of view.
Try pasting this snippet into the Astrograph Playground to follow operations involving Stellar’s native currency Lumens across the network in real time. Every time the operation is of type Payment, you’ll be able to see the account IDs of a sender and a receiver.
subscription {
operations(asset: "native") {
kind
# You can specify which attributes you need for each operation type
... on PaymentOperation {
amount
sourceAccount {
id
}
destination {
id
}
}
}
}
With the same level of ease, you can subscribe to (and filter) all events related to accounts, offers, trustlines, or data entries. We plan to add more subscriptions as the project evolves. Follow the schema updates on Astrograph Playground to stay in the loop.
We’re also not limiting ourselves to generic subscriptions like the ones offered by Horizon. We are open to adding more specific offerings tailored to common Stellar applications. For demonstration purposes, we came up with a tick
subscription that makes it dead easy to monitor the best bid/ask prices for any pair of assets issued on Stellar.
Let’s say we want to follow the exchange rate between USDC and Stellar Lumens (XLM) in real time, like it’s done on the Astrograph’s landing page. Given an already-configured Apollo Client, here is the simplest possible TypeScript code to just log real-time values to the console:
import { gql } from "graphql-tag";
import ApolloClient from "apollo-client";
// The asset code and the issuer's public key
const SELLING = "USDC-GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN";
// Native Lumens
const BUYING = "native";
// Form the subscription request
const SUBSCRIPTION = gql`
subscription tick($selling: AssetID!, $buying: AssetID!) {
tick(selling: $selling, buying: $buying) {
bestBid
bestAsk
}
}
`;
// assuming apolloClient is initialized
apolloClient
.subscribe({
query: SUBSCRIPTION,
variables: {
selling: SELLING,
buying: BUYING
}
})
.subscribe({
next(data: any) {
const values = data.data.tick;
console.log(
`[${new Date().toISOString()}]`,
"BID/ASK:",
`${values.bestBid}/${values.bestAsk}`
);
}
});
Check the full example for a CLI implementation of the ticker in the examples
folder in the Astrograph’s repo. You can also run this example locally:
git clone https://github.com/astroband/astrograph.git
cd astrograph && yarn && yarn exec ts-node examples/tick.ts
Next challenge: Historical records
In its current form, Astrograph is perfect for browsing the current state of the Stellar network. It does not yet offer a way to perform deep searches over the history of several ledgers as would be required for analytical applications like fraud detection.
The way that storage is currently implemented in stellar-core and Horizon involves a tradeoff between efficiency and querying ease: it’s a combination of disk and database storage with two different approaches to relational schema design. Some of the data remains in the Stellar’s native XDR format, designed to be transmitted quickly and stored efficiently, while some of the data is decoded and repackaged for ease of querying.
This approach works, but the structure of XDR is document-oriented by design. It doesn’t map well to relational databases, plus it changes slightly between protocol versions, forcing to opt for loosely structured JSON columns in PostgreSQL that currently underlies Stellar’s persistence.
Keeping all this in mind, we started working on the implementation of our own ingestion mechanism for Astrograph. As the Stellar network can be seen as a graph with myriads of edges (an account is connected to many assets through trustlines, assets are related to issuing accounts, which are connected to one or more signers, who in turn have their own transactions, and so on), we have invested into experimenting with graph databases and we’ve made particularly good progress with DGraph.
However, our working proof of concept was not suitable for production due to ingestion time and disk space constraints. Now we are looking into augmenting graph-based storage solutions with fast indexing engines such as Elasticsearch, and we have already had some promising progress.
We’re optimistic about adding ingestion capabilities to Astrograph in future releases.
Talk to us
Astrograph is an open source project, currently powered by the Apollo Server on the backend, written entirely in TypeScript. Although we considered both Go and Rust as alternatives, we came to the conclusion that Apollo/TS combination gives us much cleaner, shorter, and more readable code. Plus, the ecosystem around GraphQL is inherently JS-oriented.
Cloning the GitHub repository and making a pull request is a welcome way of contributing to the project, but not the only one.
Since trying out Astrograph doesn’t require any installation or setup and you can explore Stellar through GraphQL right in our playground, we welcome you to start testing your queries.
With this beta release, primarily, we want to see how our current schema fits your real-world needs and how it can be improved. Are you building a product based on a Stellar network and think you can benefit from GraphQL’s flexibility and ease of use? Feel free to tell us about your specific needs so we can introduce more queries, connections, or filters.
Do you have a use case for real-time subscriptions in your application and see the possibility of writing less code for more value? Together, we can come up with a subscription type that can fit your specific needs.
It’s hard for us to imagine all the possible applications for Astrograph without the voice of the blockchain enthusiasts who are passionate about the Stellar ecosystem. Help us make sure that our open source project serves its purpose: providing a modern and powerful tool for any Stellar developer out there.
If you feel like your Stellar-oriented codebase might become leaner with Astrograph, or if you’ve been waiting to start working with blockchain but needed an easier way in—feel free to drop us a line! We’ve got the experience working in commercial projects for Stellar ecosystem necessary to help you out.