Stacks Blockchain API Overview
The Stacks blockchain API allows you to query the Stacks blockchain and interact with smart contracts. It was built to maintain paginated, materialized views of the Stacks Blockchain.
The Stacks Blockchain API is hosted by Hiro. Using it requires you to trust us as the hosted server, but in return we provide a faster development experience. If you want a fully trustless architecture for your app, you may wish to consider running your own API instance.
NOTE:
To explore the detailed documentation for the API endpoints, request and response formats, you can refer to the API Reference.
The source code for this project is available in our GitHub repository. You can explore the codebase, contribute, and raise issues or pull requests.
Architecture
The
stacks-node
has its own minimal set of http endpoints referred to asRPC endpoints
- The
stacks-blockchain-api
allows clients to access these endpoints by proxying them through to a load-balanced pool ofstacks-nodes
. - See: https://github.com/blockstack/stacks-blockchain/blob/master/docs/rpc-endpoints.md -- some common ones:
POST /v2/transactions
- broadcast a transaction.GET /v2/pox
- get current PoX-relevant information.POST /v2/contracts/call-read/<contract>/<function>
- evaluate and return the result of calling a Clarity function.POST /v2/fees/transaction
- evaluate a given transaction and return transaction fee estimation data.GET /v2/accounts/<address>
- get the currentnonce
required for creating transactions.
- The
The endpoints implemented by
stacks-blockchain-api
provide data that thestacks-node
can't due to various constraints.- Typically this is either data that the
stacks-node
doesn't persist, or data that it cannot efficiently serve to many clients. For example, thestacks-node
can return the current STX balance of an account, but it can't return a history of account transactions. - The API also implements the Rosetta spec created by Coinbase -- "an open standard designed to simplify blockchain deployment and interaction."
- The API also implements the BNS (Blockchain Naming System) endpoints.
- See
/src/api/routes
for the Express.js routes.
- Typically this is either data that the
The API creates an "event observer" http server which listens for events from a
stacks-node
"event emitter"- These events are http POST requests that contain things like blocks, transactions, byproducts of executed transactions.
- Transaction "byproducts" are things like asset transfers, smart-contract log data, execution cost data.
- The API processes and stores these as relational data in postgres.
- See
/src/event-stream
for the "event observer" code.
- These events are http POST requests that contain things like blocks, transactions, byproducts of executed transactions.
All http endpoints and responses are defined in OpenAPI and JSON Schema.
- See
/docs/openapi.yaml
- These are used to auto generate the docs at https://hirosystems.github.io/stacks-blockchain-api/
- The JSON Schemas are converted into Typescript interfaces, which are used internally by the db controller module to transform SQL query results into the correct object shapes.
- ALSO the OpenAPI + JSONSchemas are used to generate a standalone
@stacks/blockchain-api-client
.
- See
The easiest/quickest way to develop in this repo is using the VS Code debugger. It uses docker-compose to setup a
stacks-node
and Postgres instance.- Alternatively, you can run
npm run dev:integrated
which does the same thing but without a debugger.
- Alternatively, you can run
OpenAPI Spec
The Stacks API was designed using the OpenAPI specification, making it compatible with a variety of developer tools.
The OpenAPI specification file for Stacks is used to generate the TypeScript client library. You can use the specification file to generate client libraries for other programming languages using the openapi-generator tool
TypeScript client library
A Typescript client library is available for use of the Stacks API. The client library enables type-safe REST and WebSocket communication with the Stacks API endpoints.
The client is made up of three components:
- Generated HTTP API client
- Typescript definitions for Clarity values
- WebSocket client
The following sections demonstrate common usages of the TypeScript API client.
HTTP API client sample
The Typescript client library requires you to specify the underlying HTTP request library to handle HTTP communication. The example below uses the universal fetch API cross-fetch
:
import fetch from 'cross-fetch';
import { Configuration, AccountsApi } from '@stacks/blockchain-api-client';
(async () => {
const apiConfig = new Configuration({
fetchApi: fetch,
// for mainnet, replace `testnet` with `mainnet`
basePath: 'https://api.testnet.hiro.so', // defaults to http://localhost:3999
});
// initiate the /accounts API with the basepath and fetch library
const accountsApi = new AccountsApi(apiConfig);
// get transactions for a specific account
const txs = await accountsApi.getAccountTransactions({
principal: 'ST000000000000000000002AMW42H',
});
console.log(txs);
})().catch(console.error);
TypeScript sample
The following sample shows how generated TypeScript models can be used for type-safety:
import fetch from 'cross-fetch';
import {
Configuration,
AccountsApi,
AccountsApiInterface,
AddressBalanceResponse,
AddressBalanceResponseStx,
} from '@stacks/blockchain-api-client';
(async () => {
const apiConfig: Configuration = new Configuration({
fetchApi: fetch,
// for mainnet, replace `testnet` with `mainnet`
basePath: 'https://api.testnet.hiro.so', // defaults to http://localhost:3999
});
const principal: string = 'ST000000000000000000002AMW42H';
// initiate the /accounts API with the basepath and fetch library
const accountsApi: AccountsApiInterface = new AccountsApi(apiConfig);
// get balance for a specific account
const balance: AddressBalanceResponse = await accountsApi.getAccountBalance({
principal,
});
// get STX balance details
const stxAmount: AddressBalanceResponseStx = balance.stx;
console.log(stxAmount);
})().catch(console.error);
WebSocket sample
The WebSocket components enable you to subscribe to specific updates, providing a near real-time display of updates on transactions and accounts.
import { connectWebSocketClient } from '@stacks/blockchain-api-client';
const client = await connectWebSocketClient('ws://stacks-node-api.blockstack.org/');
const sub = await client.subscribeAddressTransactions(contractCall.txId, event => {
console.log(event);
});
await sub.unsubscribe();