Upgrading from v1

This page contains a list of changes between DNA v1 and DNA v2.

@apibara/starknet package

This package now works in combination with @apibara/protocol to provide a DNA stream that automatically encodes and decodes the Protobuf data. This means tha field elements are automatically converted to 0x${string} values.

Notice that the data stream is now unary.

import { createClient } from "@apibara/protocol";
import { Filter, StarknetStream } from "@apibara/starknet";

const client = createClient(StarknetStream, process.env.STREAM_URL);

const filter = Filter.make({
  events: [{
    address:
      "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
  }],
});

const request = StarknetStream.Request.make({
  filter: [filter],
  finality: "accepted",
  startingCursor: {
    orderKey: 800_000n,
  },
});

for await (const message of client.streamData(request)) {
  switch (message._tag) {
    case "data": {
      break;
    }
    case "invalidate": {
      break;
    }
    default: {
      break;
    }
  }
}

Reconnecting on error

The client now doesn't automatically reconnect on error. This is because the reconnection step is very delicate and depends on your indexer's implementation. The recommended approach is to wrap your indexer's main loop in a try/catch block.

import { createClient, type ClientError, type Status } from "@apibara/protocol";
import { Filter, StarknetStream } from "@apibara/starknet";

const client = createClient(StarknetStream, process.env.STREAM_URL);

const filter = Filter.make({
  events: [{
    address:
      "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
  }],
});

while (true) {
  try {
    const startingCursor = await loadCursorFromDatabase();
    const request = StarknetStream.Request.make({
      filter: [filter],
      finality: "accepted",
      startingCursor,
    });
  
    for await (const message of client.streamData(request)) {
    }
  } catch (err) {
    if (err instanceof ClientError) {
      // It's a gRPC error.
      if (err.status !== Status.INTERNAL) {
        // NON-INTERNAL errors are not recoverable.
        throw err;
      }
  
      // INTERNAL errors are caused by a disconnection.
      // Sleep and reconnect.
      await new Promise(r => setTimeout(r, 2_000));
    }
  }
}

Filter

  • The header field is now an enum. See the dedicated section in the filter documentation for more information.

Events

  • fromAddress is now address.
  • The keys field accepts null values to match any key at that position.
  • The data field was removed.
  • Use transactionStatus: "all" instead of includeReverted to include reverted transactions.
  • includeReceipt and includeTransaction are now false by default.

Transactions

  • Now you can only filter by transaction type.
  • We will add transaction-specific filters in the future.
  • Use transactionStatus: "all" instead of includeReverted to include reverted transactions.
  • includeReceipt is now false by default.

Messages

  • Can now filter by fromAddress and toAddress.
  • Use transactionStatus: "all" instead of includeReverted to include reverted transactions.
  • includeReceipt and includeTransaction are now false by default.

State Update

  • State update has been split into separate filters for storage diffs, contract changes, and nonce updates.
  • Declared and deployed contracts, declared classes, and replaced classes are now a single contractChanges filter.

Block data

  • Block data has been "flattened". Use the *Index field to access related data. For example, the following code iterates over all events and looks up their transactions.
for (const event of block.events) {
  const transaction = block.transactions.find(tx => tx.transactionIndex === event.transactionIndex);
}

Events

  • fromAddress is now address.
  • index is now eventIndex.
  • Events now include transactionIndex, transactionHash, and transactionStatus.

Transactions

  • TransactionMeta now includes transactionIndex, transactionHash, and transactionStatus.
  • The transaction type is now an enum using the _tag field as discriminator.
  • For other minor changes, see the transaction documentation.

Receipts

Messages

  • index is now messageIndex.
  • Messages now include transactionIndex, transactionHash, and transactionStatus.
Last modified
Apibara

Apibara is the fastest platform to build production-grade indexers that connect onchain data to web2 services.

© 2024 GNC Labs Limited. All rights reserved.