Apibara Typescript SDK
The Typescript SDK enables developers to connect to DNA streams using Typescript.
The Typescript SDK is great to develop applications that:
- use web3 libraries like ethers.js and starknet.js,
- reuse code between frontend and backend,
- leverage the vast ecosystem of Typescript packages.
Packages#
The Typescript SDK is comprised of the following packages:
@apibara/protocol
: use this package to connect to Apibara and stream data from it.@apibara/starknet
: use this package to parse data from one of the StarkNet streams.
Examples#
Starknet stream#
The following example shows how to connect to a DNA stream to consume Starknet data.
We start by installing the @apibara/protocol
and @apibara/starknet
packages:
npm add @apibara/protocol @apibara/starknet
yarn install @apibara/protocol @apibara/starknet
pnpm add @apibara/protocol @apibara/starknet
Then we can create a DNA client. If you're using a DNA stream hosted by Apibara, you will need to specify an API token. You can create an API token for free on the Apibara website.
import { StreamClient } from '@apibara/protocol'// Grab Apibara DNA token from environment, if any.const AUTH_TOKEN = process.env.AUTH_TOKENconst client = new StreamClient({url: 'mainnet.starknet.a5a.ch',token: AUTH_TOKEN,})
We need to configure the client to start streaming data. To do that, we need to specify the following:
- filter: a DNA filter that is used to decide what data to send for each block.
- finality: block data finality. Can be finalized to receive blocks that have accepted on L1 and are extremely unlikely to be part of a chain reorganization, accepted for blocks accepted on L2, and pending for pending blocks.
- batch size: finalized data is sent in batches to speedup the syncing process. This parameter controls the size of each batch.
- cursor: the starting cursor.
In this example, we create a Starknet filter for all Transfer
events of the ETH token.
Together with events, we want to receive block headers and storage changes.
import { StarkNetCursor, Filter, FieldElement, v1alpha2 as starknet } from '@apibara/starknet'const address = FieldElement.fromBigInt('0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7')const transferKey = [FieldElement.fromBigInt(hash.getSelectorFromName('Transfer'))]// Create stream filter. The client will only receive the specified data.//// - header: included only if any other filter matches (`weak: true`)// - events: all transfer events from the eth contract// - state update: all storage diffs from the eth contractconst filter = Filter.create().withHeader({ weak: true }).addEvent((ev) => ev.withFromAddress(address).withKeys(transferKey)).withStateUpdate((su) => su.addStorageDiff((st) => st.withContractAddress(address))).encode()
Finally, we send the filter together with the rest of the configuration to the server and start streaming block data. The server to client stream is an async iterator that handles low-level details such as reconnecting after disconnect.
const cursor = StarkNetCursor.createWithBlockNumber(1045)client.configure({filter,batchSize: 10,finality: v1alpha2.DataFinality.DATA_STATUS_ACCEPTED,cursor,})for await (const message of client) {if (message.data?.data) {for (let item of message.data.data) {const block = starknet.Block.decode(item)// use data in block}}}