### Starknet Indexer Setup Source: https://www.apibara.com/docs/getting-started/indexers Example of setting up a basic indexer for Starknet using the Apibara SDK. It imports necessary modules and defines the indexer structure. ```typescript import { StarknetStream } from "@apibara/starknet"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(StarknetStream)({ /* ... */ }); ``` -------------------------------- ### EVM (Ethereum) Indexer Setup Source: https://www.apibara.com/docs/getting-started/indexers Example of setting up a basic indexer for the EVM (Ethereum) using the Apibara SDK. It imports necessary modules and defines the indexer structure. ```typescript import { EvmStream } from "@apibara/evm"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(EvmStream)({ /* ... */ }); ``` -------------------------------- ### Beacon Chain Indexer Setup Source: https://www.apibara.com/docs/getting-started/indexers Example of setting up a basic indexer for the Beacon Chain using the Apibara SDK. It imports necessary modules and defines the indexer structure. ```typescript import { BeaconChainStream } from "@apibara/beaconchain"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(BeaconChainStream)({ /* ... */ }); ``` -------------------------------- ### OpenTelemetry Guides for Sentry Integration Source: https://docs.sentry.io/platforms/javascript/guides/node/opentelemetry/ Provides links to guides for managing OpenTelemetry setups with Sentry. Covers using existing custom OpenTelemetry setups and leveraging OpenTelemetry APIs within Sentry. ```APIDOC Guide: Using Your Existing OpenTelemetry Setup URL: /platforms/javascript/guides/node/opentelemetry/custom-setup Description: Learn how to use your existing custom OpenTelemetry setup with Sentry. Guide: Using OpenTelemetry APIs URL: /platforms/javascript/guides/node/opentelemetry/using-opentelemetry-apis Description: Learn how to use OpenTelemetry APIs with Sentry. ``` -------------------------------- ### Install Project Dependencies Source: https://context7_llms Installs the project dependencies using `pnpm`. This command is run after the Apibara project has been initialized. ```bash pnpm install ``` -------------------------------- ### EVM (Ethereum) Indexer Setup Source: https://www.apibara.com/docs/getting-started/indexers Defines an indexer for the EVM (Ethereum) stream using the `@apibara/evm` and `@apibara/indexer` libraries. This snippet demonstrates the basic setup for an Ethereum indexer. ```typescript import { EvmStream } from "@apibara/evm"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(EvmStream)({ /* ... */ }); ``` -------------------------------- ### Apibara Runtime Configuration Example Source: https://context7_llms Defines runtime configuration for an Apibara indexer within `apibara.config.ts`. This allows external configuration of parameters like starting block and stream URL, enhancing flexibility. ```typescript import { defineConfig } from "apibara/config"; export default defineConfig({ runtimeConfig: { strkStaking: { startingBlock: 900_000, streamUrl: "https://mainnet.starknet.a5a.ch", contractAddress: "0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a", }, }, }); ``` -------------------------------- ### Apibara Indexer Configuration Example Source: https://www.apibara.com/docs/getting-started/plugins An example of how to define an Apibara indexer using TypeScript. It demonstrates importing necessary streams, configuring the stream URL, filter, and defining lifecycle hooks like `connect:before`. ```typescript import { BeaconChainStream } from "@apibara/beaconchain"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(BeaconChainStream)({ streamUrl: "https://beaconchain.preview.apibara.org", filter: { /* ... */ }, async transform({ block: { header, validators } }) { /* ... */ }, hooks: { async "connect:before"({ request, options }) { // Do something before the indexer connects to the DNA stream. }, }, }); ``` -------------------------------- ### Apibara Starknet Client Setup Source: https://www.apibara.com/docs/networks/starknet/upgrade-from-v1 Demonstrates how to import necessary types and functions from Apibara's protocol and Starknet packages, initialize a Starknet stream client, and define a basic filter for events. This setup is crucial for subscribing to real-time Starknet data. ```typescript import { createClient, ClientError, Status } from "@apibara/protocol"; import { Filter, StarknetStream } from "@apibara/starknet"; const client = createClient(StarknetStream, process.env.STREAM_URL); const filter: Filter = { events: [ { address: "", } ] }; ``` -------------------------------- ### Indexer Module Using Runtime Configuration Source: https://context7_llms An example of an indexer module that accepts and uses runtime configuration. It defines a function that takes `ApibaraRuntimeConfig` and returns an indexer instance, enabling dynamic setup. ```typescript import { defineIndexer } from "apibara/indexer"; import { useLogger } from "apibara/plugins"; import { StarknetStream } from "@apibara/starknet"; import { ApibaraRuntimeConfig } from "apibara/types"; export default function (runtimeConfig: ApibaraRuntimeConfig) { const config = runtimeConfig.strkStaking; const { startingBlock, streamUrl } = config; return defineIndexer(StarknetStream)({ streamUrl, startingBlock: BigInt(startingBlock), filter: { events: [ { address: config.contractAddress as `0x${string}`, }, ], }, async transform({ block }) { // Unchanged. }, }); } ``` -------------------------------- ### Apibara v1 Indexer Example Source: https://context7_llms An example of an older Apibara indexer configuration and transform function. ```ts export const config = { streamUrl: "https://mainnet.starknet.a5a.ch", startingBlock: 800_000, network: "starknet", finality: "DATA_STATUS_ACCEPTED", filter: { header: {}, }, sinkType: "console", sinkOptions: {}, }; export default function transform(block) { return block; } ``` -------------------------------- ### Install Viem using npm Source: https://viem.sh/ This command installs the Viem library into your project using npm, the Node Package Manager. It fetches the latest stable version and adds it as a dependency. ```bash npm i viem ``` -------------------------------- ### Uniswap V2 Indexer Factory Example Source: https://www.apibara.com/docs/getting-started/indexers A minimal indexer example using the Apibara factory function to stream `PairCreated` events from Uniswap V2. It demonstrates how to define the stream URL, filter logs, and implement the factory and transform functions. ```typescript import { EvmStream } from "@apibara/evm"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(EvmStream)({ streamUrl: "https://mainnet.ethereum.a5a.ch", filter: { logs: [ { /* ... */ }, ], }, async factory({ block }) { const { logs } = block; return { /* ... */ }; }, async transform({ block }) { const { header, logs } = block; console.log(header); console.log(logs); }, }); ``` -------------------------------- ### Build and Run Indexer with Sentry Source: https://context7_llms Commands to build and start an Apibara indexer, with Sentry error tracking enabled via OpenTelemetry. ```bash pnpm build pnpm start --indexer=your-indexer ``` -------------------------------- ### Add Apibara Dependencies Source: https://context7_llms Installs the necessary Apibara packages for building indexers, including the next versions. ```bash npm add --save apibara@next @apibara/protocol@next @apibara/starknet@next ``` -------------------------------- ### Install Beacon Chain Typescript Package Source: https://context7_llms Installs the necessary TypeScript package for interacting with Beacon Chain data streams provided by Apibara. Use the '@next' tag for the latest version. ```bash npm install @apibara/beaconchain@next ``` -------------------------------- ### Drizzle ORM Setup Source: https://orm.drizzle.team/docs/rqb This TypeScript code demonstrates the basic setup for Drizzle ORM, showing how to import schema definitions and initialize the `drizzle` instance with a database connection. It highlights Drizzle's typed layer over SQL. ```typescript import * as schema from './schema'; import { drizzle } from 'drizzle-orm/...'; const db = drizzle({ schema }); ``` -------------------------------- ### Apibara Beacon Chain Indexer Setup Source: https://www.apibara.com/docs/getting-started/plugins Defines an Apibara indexer for the Beacon Chain. It specifies the stream URL, a placeholder filter, and includes a custom plugin. This setup is crucial for processing blockchain data streams. ```typescript import { BeaconChainStream } from "@apibara/beaconchain"; import { defineIndexer } from "@apibara/indexer"; import { myAwesomePlugin } from "@/lib/my-plugin.ts"; export default defineIndexer(BeaconChainStream)({ streamUrl: "https://beaconchain.preview.apibara.org", filter: { /* ... */ }, plugins: ["myAwesomePlugin()"], async transform(block) { // ... processing logic ... } }); ``` -------------------------------- ### Apibara Indexer Middleware Example Source: https://www.apibara.com/docs/getting-started/plugins Illustrates how to wrap indexer operations, such as database calls, within middleware using the `handler:middleware` hook. This example shows how to register a transaction middleware that manages database transactions for each processing step. ```ts import type { Cursor } from \"@apibara/protocol\"; import { defineIndexerPlugin } from \"@apibara/indexer/plugins\"; export function myAwesomePlugin() { return defineIndexerPlugin((indexer) => { const db = openDatabase(); indexer.hooks.hook(\"handler:middleware\", ({ use }) => { use(async (context, next) => { // Start a transaction. await db.transaction(async (txn) => { // Add the transaction to the context. context.db = txn; try { // Call the next middleware or the transform function. await next(); } finally { // Remove the transaction from the context. context.db = undefined; } }); }); }); }); } ``` -------------------------------- ### Install Drizzle and Apibara Dependencies Source: https://www.apibara.com/docs/storage/drizzle-pg Commands to install necessary packages for Drizzle ORM, PostgreSQL integration, and Apibara plugins. Includes development tools like Drizzle Kit and PGLite for local development. ```terminal npm install drizzle-orm pg @apibara/plugin-drizzle@next ``` ```terminal npm install --save-dev drizzle-kit ``` ```terminal npm install @electric-sql/pglite ``` -------------------------------- ### Drizzle ORM with PostgreSQL Component Example Source: https://www.apibara.com/docs/storage/drizzle-pg A React component demonstrating the structure and content related to Drizzle with PostgreSQL documentation. It includes headings for installation, manual setup, and code blocks for terminal commands. ```javascript var Component=(()=>{ var p=Object.create; var r=Object.defineProperty; var y=Object.getOwnPropertyDescriptor; var m=Object.getOwnPropertyNames; var D=Object.getPrototypeOf,B=Object.prototype.hasOwnProperty; var u=(n,l)=>()=>(l||n((l={exports:{}}).exports,l),l.exports); var C=(n,l)=>{for(var s in l)r(n,s,{get:l[s],enumerable:!0})}; var i=(n,l,s,a)=>{ if(l&&typeof l=="object"||typeof l=="function") for(let c of m(l)) !B.call(n,c)&&c!==s&&r(n,c,{get:()=>l[c],enumerable:!(a=y(l,c))||a.enumerable}); return n }; var F=(n,l,s)=>( s=n!=null?p(D(n)):{}, i(l||!n||!n.__esModule?r(s, "default",{value:n,enumerable:!0}):s,n) ); var g=n=>i(r({},"__esModule",{value:!0}),n); var t=u((z,o)=>{o.exports=_jsx_runtime}); var A={}; C(A,{default:()=>h,frontmatter:()=>f}); var e=F(t()); var f={"title":"Drizzle with PostgreSQL","description":"Store your indexer's data to PostgreSQL using Drizzle ORM.","diataxis":"reference","updatedAt":"2025-05-01"}; function d(n){ let l={"a":"a","code":"code","em":"em","h1":"h1","h2":"h2","h3":"h3","li":"li","p":"p","pre":"pre","span":"span","strong":"strong","ul":"ul",...n.components}; return( (0,e.jsxs)(e.Fragment,{ children:[ (0,e.jsx)(l.h1,{id:"drizzle-with-postgresql",children:"Drizzle with PostgreSQL"}), `\n`, (0,e.jsx)(l.p,{children:"The Apibara Indexer SDK supports Drizzle ORM for storing data to PostgreSQL."}), `\n`, (0,e.jsx)(l.h2,{id:"installation",children:"Installation"}), `\n`, (0,e.jsx)(l.h3,{id:"using-the-cli",children:"Using the CLI"}), `\n`, (0,e.jsx)(l.p,{children:`You can add an indexer that uses Drizzle for storage by selecting \"PostgreSQL\"\nin the \"Storage\" section when creating an indexer.`}), `\n`, (0,e.jsxs)(l.p,{children:["The CLI automatically updates your ",(0,e.jsx)(l.code,{children:"package.json"})," to add all necessary dependencies."]}), `\n`, (0,e.jsx)(l.h3,{id:"manually",children:"Manually"}), `\n`, (0,e.jsx)(l.p,{children:"To use Drizzle with PostgreSQL, you need to install the following dependencies:"}), `\n`, (0,e.Fragment,{ children:( (0,e.jsx)(l.pre,{ className:"shiki catppuccin-mocha", style:{backgroundColor:"#1e1e2e",color:"#cdd6f4"}, tabIndex:"0", "data-title":"Terminal", "data-lang":"bash", children:(0,e.jsx)(l.code,{ children:(0,e.jsxs)(l.span,{className:"line",children:[ (0,e.jsx)(l.span,{style:{color:"#89B4FA",fontStyle:"italic"},children:"npm"}), (0,e.jsx)(l.span,{style:{color:"#A6E3A1"},children:" install "}), (0,e.jsx)(l.span,{style:{color:"#A6E3A1"},children:" drizzle-orm"}), (0,e.jsx)(l.span,{style:{color:"#A6E3A1"},children:" pg"}), (0,e.jsx)(l.span,{style:{color:"#A6E3A1"},children:" @apibara/plugin-drizzle@next"}) ]}) }) }) ) }), `\n`, (0,e.jsx)(l.p,{children:"We recommend using Drizzle Kit to manage the database schema."}), `\n`, (0,e.Fragment,{ children:( (0,e.jsx)(l.pre,{ className:"shiki catppuccin-mocha", style:{backgroundColor:"#1e1e2e",color:"#cdd6f4"}, tabIndex:"0", "data-title":"Terminal", "data-la ``` -------------------------------- ### Example UI Rendering Code Source: https://www.apibara.com/docs/networks/starknet/upgrade-from-v1 A JavaScript/JSX code snippet demonstrating how UI elements might be rendered, potentially for displaying documentation or interactive components. It includes styling and text content. ```javascript l.jsx(e.div,{className:\"container\",children:[`\\n`,(0,l.jsx)(e.h1,{children:\"Apibara LLM\"}),`\\n`,(0,l.jsx)(e.p,{children:\"Documentation for Apibara LLM.\"}),`\\n`,(0,l.jsx)(e.h2,{id:\"filter\",children:\"Filter\"}),`\\n`,(0,l.jsx)(e.h3,{id:\"header\",children:\"Header\"}),`\\n`,(0,l.jsxs)(e.ul,{children:[`\\n`,(0,l.jsxs)(e.li,{children:[\"The \\",(0,l.jsx)(e.code,{children:\"header\"}),\" field is now an enum. See the \\",(0,l.jsx)(e.a,{href:\"/docs/networks/starknet/filter#header\",children:\"dedicated section\"}),`\\nin the filter documentation for more information.`]}),`\\n]}),`\\n`,(0,l.jsx)(e.h3,{id:\"events\",children:\"Events\"}),`\\n`,(0,l.jsxs)(e.ul,{children:[`\\n`,(0,l.jsxs)(e.li,{children:[(0,l.jsx)(e.code,{children:\"fromAddress\"}),\" is now \\",(0,l.jsx)(e.code,{children:\"address\"}),\".\"]}),`\\n`,(0,l.jsxs)(e.li,{children:[\"The \\",(0,l.jsx)(e.code,{children:\"keys\"}),\" field accepts \\",(0,l.jsx)(e.code,{children:\"null\"}),\" values to match any key at that position.\\"]}),`\\n`,(0,l.jsxs)(e.li,{children:[\"The \\",(0,l.jsx)(e.code,{children:\"data\"}),\" field was removed.\\"]}),`\\n`,(0,l.jsxs)(e.li,{children:[\"Use \\",(0,l.jsx)(e.code,{children:'transactionStatus: \\"all\"'}),\" instead of \\",(0,l.jsx)(e.code,{children:\"includeReverted\"}),\" to include reverted transactions.\\"]}),`\\n`,(0,l.jsxs)(e.li,{children:[(0,l.jsx)(e.code,{children:\"includeReceipt\"}),\" and \\",(0,l.jsx)(e.code,{children:\"includeTransaction\"}),\" are now \\",(0,l.jsx)(e.code,{children:\"false\"}),\" by default.\\"]}),`\\n]}),`\\n`,(0,l.jsx)(e.h3,{id:\"transactions\",children:\"Transactions\"}),`\\n`,(0,l.jsxs)(e.ul,{children:[`\\n`,(0,l.jsx)(e.li,{children:\"Now you can only filter by transaction type.\"}),`\\n`,(0,l.jsx)(e.li,{children:\"We will add transaction-specific filters in the future.\"}),`\\n`,(0,l.jsxs)(e.li,{children:[\"Use \\",(0,l.jsx)(e.code,{children:'transactionStatus: \\"all\"'}),\" instead of \\",(0,l.jsx)(e.code,{children:\"includeReverted\"}),\" to include reverted transactions.\\"]}),`\\n`,(0,l.jsxs)(e.li,{children:[(0,l.jsx)(e.code,{children:\"includeReceipt\"}),\" is now \\",(0,l.jsx)(e.code,{children:\"false\"}),\" by default.\\"]}),`\\n]}),`\\n`,(0,l.jsx)(e.h3,{id:\"messages\",children:\"Messages\"}),`\\n`,(0,l.jsxs)(e.ul,{children:[`\\n`,(0,l.jsxs)(e.li,{children:[\"Can now filter by \\",(0,l.jsx)(e.code,{children:\"fromAddress\"}),\" and \\",(0,l.jsx)(e.code,{children:\"toAddress\"}),\".\"]}),`\\n`,(0,l.jsxs)(e.li,{children:[\"Use \\",(0,l.jsx)(e.code,{children:'transactionStatus: \\"all\"'}),\" instead of \\",(0,l.jsx)(e.code,{children:\"includeReverted\"}),\" to include reverted transactions.\\"]}),`\\n`,(0,l.jsxs)(e.li,{children:[(0,l.jsx)(e.code,{children:\"includeReceipt\"}),\" and \\",(0,l.jsx)(e.code,{children:\"includeTransaction\"}),\" are now \\",(0,l.jsx)(e.code,{children:\"false\"}),\" by default.\\"]}),`\\n]}),`\\n`,(0,l.jsx)(e.h3,{id:\"state-update\",children:\"State Update\"}),`\\n`,(0,l.jsxs)(e.ul,{children:[`\\n`,(0,l.jsx)(e.li,{children:`State update has been `})]})]})}),`\\n`,(0,l.jsx)(e.span,{className:\"line\",children:(0,l.jsx)(e.span,{style:{color:\"#EBA0AC\",fontStyle:\"italic\"},children:\"r\"}),(0,l.jsx)(e.span,{style:{color:\"#9399B2\"},children:\"\"}),(0,l.jsx)(e.span,{style:{color:\"#94E2D5\"},children:\" =>\"}),(0,l.jsx)(e.span,{style:{color:\"#89B4FA\",fontStyle:\"italic\"},children:\" setTimeout\"}),(0,l.jsx)(e.span,{style:{color:\"#CDD6F4\"},children:\"(r\"}),(0,l.jsx)(e.span,{style:{color:\"#9399B2\"},children:\",\"}),(0,l.jsx)(e.span,{style:{color:\"#FAB387\"},children:\" 2_000\"}),(0,l.jsx)(e.span,{style:{color:\"#CDD6F4\"},children:\"))\"}),(0,l.jsx)(e.span,{style:{color:\"#9399B2\"},children:\";\"})]}),`\\n`,(0,l.jsx)(e.span,{className:\"line\",children:(0,l.jsx)(e.span,{style:{color:\"#9399B2\"},children:\" }\"})}),`\\n`,(0,l.jsx)(e.span,{className:\"line\",children:(0,l.jsx)(e.span,{style:{color:\"#9399B2\"},children:\" }\"})}),`\\n`,(0,l.jsx)(e.span,{className:\"line\",children:(0,l.jsx)(e.span,{style:{color:\"#9399B2\"},children:\"}\"})})]})} ``` -------------------------------- ### Get DNA Server Status Source: https://context7_llms Retrieves the current state of the DNA server. The request is an empty message, and the response provides information about the last ingested, finalized, and starting blocks. ```APIDOC Status: Description: Retrieves the state of the DNA server. Request: Empty message. Response: last_ingested: The most recent block available for streaming. finalized: The most recent finalized block. starting: The first available block (genesis or pruned). ``` -------------------------------- ### Starknet Indexer Setup Source: https://www.apibara.com/docs/getting-started/indexers Defines an indexer for the Starknet stream using the `@apibara/starknet` and `@apibara/indexer` libraries. This snippet illustrates the basic structure for a Starknet indexer. ```typescript import { StarknetStream } from "@apibara/starknet"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(StarknetStream)({ /* ... */ }); ``` -------------------------------- ### Example: Filter All Transactions in a Block Source: https://www.apibara.com/docs/networks/evm/filter Demonstrates how to fetch all transactions within a block by providing an empty filter object. This is a common starting point for processing block data. ```javascript const filter = { transactions: [ {} ] }; ``` -------------------------------- ### Initialize Node.js Project Source: https://context7_llms Initializes a new Node.js project, creating a package.json file. ```bash npm init -y ``` -------------------------------- ### Define Indexer Plugin Source: https://www.apibara.com/docs/getting-started/plugins Demonstrates the structure for defining an indexer plugin. This function is used to register custom logic for Apibara indexers, allowing for pre-processing or setup before the indexer starts its main execution loop. ```javascript return defineIndexerPlugin< TFilter, TBlock, TTxnParams >("indexer", ( ) => { return { // Plugin logic here }; }); ``` -------------------------------- ### Define Starknet Indexer Source: https://www.apibara.com/docs/getting-started/indexers Example of defining a Starknet indexer using the Apibara SDK. This snippet demonstrates the basic structure for setting up an indexer for Starknet data. ```ts import { defineIndexer } from "@apibara/indexer"; // Assuming StarknetStream is imported similarly if available // import { StarknetStream } from "@apibara/starknet"; // Example structure for Starknet indexer definition // export default defineIndexer( // (StarknetStream)( // { // /* ... */ // } // ); ``` -------------------------------- ### Placeholder in `offset` Clause Source: https://orm.drizzle.team/docs/rqb Shows how to implement `placeholder()` in the `offset` clause for database queries. This is crucial for building paginated results by dynamically specifying the starting point for fetching records. Examples cover PostgreSQL, MySQL, and SQLite. ```javascript (PostgreSQL) const prepared = db.query.users.findMany({ offset: placeholder('offset'), with: { posts: true, }, }).prepare('query_name'); const usersWithPosts = await prepared.execute({ offset: 1 }); ``` ```javascript (MySQL) const prepared = db.query.users.findMany({ offset: placeholder('offset'), with: { posts: true, }, }).prepare(); const usersWithPosts = await prepared.execute({ offset: 1 }); ``` ```javascript (SQLite) const prepared = db.query.users.findMany({ offset: placeholder('offset'), with: { posts: true, }, }).prepare(); const usersWithPosts = await prepared.execute({ offset: 1 }); ``` -------------------------------- ### Add EVM Indexer with Apibara CLI Source: https://context7_llms Demonstrates the command-line interface (CLI) process for adding a new EVM indexer. It outlines the interactive prompts for selecting the indexer ID, chain, network, and storage solution, and shows the typical output indicating successful project updates and file creation. ```bash pnpm apibara add ``` ```text ✔ Indexer ID: … rocket-pool ✔ Select a chain: › Ethereum ✔ Select a network: › Mainnet ✔ Select a storage: › None ✔ Updated apibara.config.ts ✔ Updated package.json ✔ Created rocket-pool.indexer.ts ℹ Before running the indexer, run pnpm run install & pnpm run prepare ``` -------------------------------- ### Drizzle ORM with PostgreSQL Setup Source: https://www.apibara.com/docs/storage/drizzle-pg This section outlines the process of setting up Drizzle ORM for PostgreSQL storage within an Apibara indexer. It includes manual installation steps for required packages and mentions the CLI's automatic dependency management. ```bash npm install drizzle-orm pg @apibara/plugin-drizzle@next ``` -------------------------------- ### Implement EVM Indexer Logic Source: https://context7_llms Provides an example of an EVM indexer implementation in TypeScript. It details how to define an indexer using `defineIndexer` with `EvmStream`, specifying stream URL, finality, starting block, and a filter for logs. The `transform` function processes block data, logging block numbers and transaction details. ```typescript import { defineIndexer } from "apibara/indexer"; import { useLogger } from "apibara/plugins"; import { EvmStream } from "@apibara/evm"; import type { ApibaraRuntimeConfig } from "apibara/types"; export default function (runtimeConfig: ApibaraRuntimeConfig) { const { startingBlock, streamUrl } = runtimeConfig.rocketPool; return defineIndexer(EvmStream)({ streamUrl, finality: "accepted", startingBlock: BigInt(startingBlock), filter: { logs: [ { address: "0xae78736Cd615f374D3085123A210448E74Fc6393", }, ], }, plugins: [], async transform({ block }) { const logger = useLogger(); const { logs, header } = block; logger.log(`Block number ${header?.blockNumber}`); for (const log of logs) { logger.log( `Log ${log.logIndex} from ${log.address} tx=${log.transactionHash}` ); } }, }); } ``` -------------------------------- ### Build and Run Apibara Indexer (Bash) Source: https://context7_llms Commands to build and start your Apibara indexer. This is typically run after setting up instrumentation to observe its telemetry data. ```bash pnpm build pnpm start --indexer=your-indexer ``` -------------------------------- ### Running Indexer with Sepolia Preset Source: https://context7_llms Example CLI command to run an Apibara indexer using a specific preset ('sepolia') for development, overriding default configurations. ```bash npm run dev -- --indexers=strk-staking --preset=sepolia ``` -------------------------------- ### Example Blob Filter with Transaction Source: https://context7_llms Shows an example of creating a blob filter to fetch blobs along with the transaction that included them. ```ts const filter = [ { blobs: [ { includeTransaction: true, }, ], }, ]; ``` -------------------------------- ### Initialize Apibara Project with TypeScript Source: https://context7_llms Initializes a new Apibara project using the Apibara CLI. This command creates project files and sets the language to TypeScript. It requires `pnpm` to be installed. ```bash mkdir my-indexer cd my-indexer pnpm dlx apibara@next init . --language="ts" --no-create-indexer ``` -------------------------------- ### Install Apibara EVM Package Source: https://context7_llms Installs the Apibara EVM package for TypeScript, enabling access to EVM chain types and functionalities. ```bash npm install @apibara/evm@next ``` -------------------------------- ### Withdrawal Filtering Examples Source: https://context7_llms Provides examples of using the WithdrawalFilter to retrieve Ethereum withdrawals, demonstrating filtering by validator index and withdrawal address. ```typescript // All withdrawals const filter1 = { withdrawals: [{}], }; // All withdrawals from validator with index 1234. const filter2 = { withdrawals: [ { validatorIndex: 1234, }, ], }; // All withdrawals from validators with index 1234 OR 7890. const filter3 = { withdrawals: [ { validatorIndex: 1234, }, { validatorIndex: 7890, }, ], }; // All withdrawals to address 0xAB... const filter4 = { withdrawals: [ { address: "0xAB...", }, ], }; ``` -------------------------------- ### Apibara Indexer Lifecycle and Hooks Source: https://www.apibara.com/docs/getting-started/plugins This pseudocode illustrates the lifecycle of an Apibara indexer, detailing the sequence of hook calls during its execution. It covers phases like initialization, middleware registration, data streaming, and message handling. ```javascript function run(indexer) { indexer.callHook("run:before"); const { use, middleware } = registerMiddleware(indexer); indexer.callHook("handler:middleware", { use }); // Create the request based on the indexer's configuration. const request = Request.create({ filter: indexer.filter, startingCursor: indexer.startingCursor, finality: indexer.finality, }); // Stream options. const options = {}; indexer.callHook("connect:before", { request, options }); let stream = indexer.streamData(request, options); indexer.callHook("connect:after"); while (true) { const { message, done } = stream.next(); if (done) { break; } indexer.callHook("message", { message }); switch (message._tag) { case "data": { const { block, endCursor, finality } = message.data middleware(() => { if (indexer.isFactoryMode()) { // Handle the factory portion of the indexer data. // Implementation detail is not important here. const newFilter = indexer.factory(); const request = Request.create(/* ... */); indexer.callHook("connect:factory", { request, endCursor }); stream = indexer.streamData(request, options); } indexer.transform({ block, endCursor, finality }); }); break; } case "invalidate": { indexer.callHook("message:invalidate", { message }); break; } case "finalize": { indexer.callHook("message:finalize", { message }); break; } case "heartbeat": { indexer.callHook("message:heartbeat", { message }); break; } case "systemMessage": { indexer.callHook("message:systemMessage", { message }); break; } } } indexer.callHook("run:after"); } ``` -------------------------------- ### Install PGLite Package Source: https://www.apibara.com/docs/storage/drizzle-pg Installs the @electric-sql/pglite package using npm. This package enables the use of PGLite for running a PostgreSQL-compatible database in-memory. ```bash npm install \n @electric-sql/pglite ``` -------------------------------- ### Starknet Stream Client with Reconnection Source: https://www.apibara.com/docs/networks/starknet/upgrade-from-v1 Example of connecting to the Starknet stream, handling data, and implementing reconnection logic for internal errors. It demonstrates setting up a request with filters and cursors, and iterating over incoming messages. ```js 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)) { // Process message } } 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)); } } } ``` -------------------------------- ### Install Prometheus Dependencies (Bash) Source: https://context7_llms Installs the necessary OpenTelemetry packages for Prometheus integration using pnpm. These packages enable metric collection and exposition for Prometheus. ```bash pnpm install @opentelemetry/api @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-prometheus @opentelemetry/resources @opentelemetry/sdk-node @opentelemetry/semantic-conventions ``` -------------------------------- ### Configure Starknet Indexer Settings Source: https://context7_llms Illustrates how to configure specific parameters for a Starknet indexer within the `apibara.config.ts` file. Key settings include the `startingBlock` for data synchronization and the `streamUrl` for connecting to the network. ```typescript // ... export default defineConfig({ runtimeConfig: { // ... strkStaking: { startingBlock: 900_000, streamUrl: "https://mainnet.starknet.a5a.ch", }, }, // ... }); ``` -------------------------------- ### Install OpenTelemetry dependencies for Apibara Source: https://context7_llms Install the necessary OpenTelemetry packages using pnpm to enable metrics and traces collection. These packages are required for integrating with the OpenTelemetry Collector. ```bash pnpm install @opentelemetry/api @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-metrics-otlp-grpc @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/resources @opentelemetry/sdk-node @opentelemetry/sdk-metrics @opentelemetry/sdk-trace-node @opentelemetry/semantic-conventions ``` -------------------------------- ### Install Drizzle Kit Dev Dependency Source: https://www.apibara.com/docs/storage/drizzle-pg Installs the Drizzle Kit package as a development dependency using npm. This package is essential for working with Drizzle ORM. ```bash npm install \n --save-dev \n drizzle-kit ``` -------------------------------- ### Install Sentry Dependencies (Bash) Source: https://context7_llms Installs the Sentry Node.js SDK package using pnpm, which is required for integrating Sentry error tracking and performance monitoring into your Apibara indexer. ```bash pnpm install @sentry/node ``` -------------------------------- ### Beacon Chain Indexer Setup Source: https://www.apibara.com/docs/getting-started/indexers Defines an indexer for the Beacon Chain stream using the `@apibara/beaconchain` and `@apibara/indexer` libraries. This snippet shows the basic structure for initializing an indexer for a specific chain stream. ```typescript import { BeaconChainStream } from "@apibara/beaconchain"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(BeaconChainStream)({ /* ... */ }); ``` -------------------------------- ### Indexer Connection Hook Example Source: https://www.apibara.com/docs/getting-started/plugins Demonstrates the 'connect:before' hook, which is called before the indexer establishes a connection to the DNA stream. It shows how to pass request and options to the connection. ```javascript hooks: { async connect:before({ request, options }) { // Do something before the indexer connects to the DNA stream. } } ``` -------------------------------- ### SQL Update Record Example Source: https://supabase.com/blog/postgres-audit Provides an example of how to update an existing record in a 'members' table. It specifies the table, the column to update, the new value, and the condition for the update. ```sql -- edit the record update public.members set name = 'bar' where id = 1; ``` -------------------------------- ### Define Starknet Indexer with Apibara Source: https://www.apibara.com/docs/getting-started/indexers Example of defining a basic Starknet indexer using the `defineIndexer` function and `StarknetStream` from the Apibara library. This sets up a stream for Starknet data. ```javascript import { StarknetStream } from "@apibara/starknet"; import { defineIndexer } from "@apibara/indexer"; export default defineIndexer(StarknetStream)({ /* ... */ }); ``` -------------------------------- ### Start Apibara Indexer with Specific Name Source: https://context7_llms Command to start a specific Apibara indexer after it has been built. The `--indexer` flag specifies which indexer to run, useful when a project contains multiple indexers. ```bash pnpm run start --indexer rocket-pool ``` ```text > apibara-app@0.1.0 start /tmp/my-indexer > apibara start "--indexer" "rocket-pool" ◐ Starting indexer rocket-pool rocket-pool | log Block number 21000071 rocket-pool | log Log 239 from 0xae78736cd615f374d3085123a210448e74fc6393 tx=0xe3b7e285c02e9a1dad654ba095ee517cf4c15bf0c2c0adec555045e86ea1de89 rocket-pool | log Block number 21000097 rocket-pool | log Log 265 from 0xae78736cd615f374d3085123a210448e74fc6393 tx=0x8946aaa1ae303a19576d6dca9abe0f774709ff6c3f2de40c11dfda2ab276fbba rocket-pool | log Log 266 from 0xae78736cd615f374d3085123a210448e74fc6393 tx=0x8946aaa1ae303a19576d6dca9abe0f774709ff6c3f2de40c11dfda2ab276fbba rocket-pool | log Block number 21000111 ... ``` -------------------------------- ### Implement Starknet Indexer Logic Source: https://context7_llms Provides a TypeScript example for implementing a Starknet indexer. It defines how to connect to a stream, filter events from a specific contract address, and process block data, including logging event details. ```typescript import { defineIndexer } from "apibara/indexer"; import { useLogger } from "apibara/plugins"; import type { ApibaraRuntimeConfig } from "apibara/types"; import { StarknetStream } from "@apibara/starknet"; export default function (runtimeConfig: ApibaraRuntimeConfig) { const { startingBlock, streamUrl } = runtimeConfig.strkStaking; return defineIndexer(StarknetStream)({ streamUrl, finality: "accepted", startingBlock: BigInt(startingBlock), filter: { events: [ { address: "0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a", }, ], }, plugins: [], async transform({ block }) { const logger = useLogger(); const { events, header } = block; logger.log(`Block number ${header?.blockNumber}`); for (const event of events) { logger.log(`Event ${event.eventIndex} tx=${event.transactionHash}`); } }, }); } ``` -------------------------------- ### Install Drizzle and PostgreSQL Dependencies Source: https://www.apibara.com/docs/storage/drizzle-pg Install the necessary packages for Drizzle ORM, PostgreSQL integration, and optional PGLite for local development. These commands are typically run in your project's terminal. ```bash npm install drizzle-orm pg @apibara/plugin-drizzle@next ``` ```bash npm install --save-dev drizzle-kit ``` ```bash npm install @electric-sql/pglite ``` -------------------------------- ### JavaScript/TypeScript: LLM Indexer Factory and Request Creation Source: https://www.apibara.com/docs/getting-started/plugins Demonstrates the creation of an LLM indexer factory and a request object. This snippet shows how to initialize components for LLM data processing, including setting up a factory for indexer data and creating a request object with placeholder comments. ```javascript // Handle the factory portion of the indexer data. // Implementation detail is not important here. const newFilter = indexer.factory(); const request = Request.create("/* ... */"); ``` -------------------------------- ### Add Starknet Indexer to Project Source: https://context7_llms Demonstrates the process of adding a new indexer, specifically for Starknet, to an existing Apibara project. This command interactively prompts for indexer details and updates configuration files. ```bash pnpm apibara add ``` -------------------------------- ### SQL Delete Record Example Source: https://supabase.com/blog/postgres-audit Illustrates a SQL statement to delete records from a 'members' table. This example shows a simple DELETE statement without a WHERE clause, which would remove all records. ```sql -- delete the record delete from public.members; ```