### Start the Ponder development server Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/get-started.mdx After installation, start the local development server to connect to the database, start the HTTP server, and begin indexing. ```bash pnpm dev ``` ```bash yarn dev ``` ```bash npm run dev ``` ```bash bun dev ``` -------------------------------- ### Basic Hono App Setup Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/api-endpoints.mdx Demonstrates the basic structure of a Hono app in `src/api/index.ts` with a simple GET endpoint. ```APIDOC ## Basic Hono App Setup ### Description This example shows the minimal setup for a Hono application in Ponder, including how to define a default export for the Hono app and register a simple GET route. ### Method GET ### Endpoint /hello ### Request Example (No request body) ### Response #### Success Response (200) - `text/plain`: "Hello, world!" ### Code Example ```ts import { Hono } from "hono"; const app = new Hono(); app.get("/hello", (c) => { return c.text("Hello, world!"); }); export default app; ``` ``` -------------------------------- ### Install @ponder/client Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder-client.mdx Install the @ponder/client package using your preferred package manager. ```bash pnpm add @ponder/client ``` ```bash yarn add @ponder/client ``` ```bash npm add @ponder/client ``` ```bash bun add @ponder/client ``` -------------------------------- ### Start Ponder with Automated View Creation Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/production/self-hosting.mdx When starting Ponder with 'ponder start', use the '--views-schema' flag to automatically run the 'ponder db create-views' command once the deployment is ready. This ensures views always point to the latest deployment. ```bash pnpm start --schema=deployment-123 --views-schema=project-name ``` -------------------------------- ### Create a New Ponder Project with a Template Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/create-ponder.mdx Initialize a new Ponder project using a specific template by providing the `--template` option. This is useful for starting with pre-configured example projects. ```bash pnpm create ponder --template feature-factory ``` ```bash yarn create ponder --template feature-factory ``` ```bash npm init ponder@latest --template feature-factory ``` ```bash bun --bun create ponder --template feature-factory ``` -------------------------------- ### ponder start Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/cli.mdx Starts the Ponder production server. Project files are built once on startup and file changes are ignored. ```APIDOC ## start ### Description Start the app in production mode. Project files are built once on startup, and file changes are ignored. The terminal UI is disabled. ### Usage `ponder start [options]` ### Options - **--schema** (SCHEMA) - Database schema (max: 45 characters) - **--views-schema** (SCHEMA) - Views database schema (max: 45 characters) - **-p, --port** (PORT) - Port for the web server (default: 42069) - **-H, --hostname** (HOSTNAME) - Hostname for the web server (default: "0.0.0.0" or "::") - **-h, --help** - display help for command ``` -------------------------------- ### Ponder Start Command Usage Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/cli.mdx Usage for the `ponder start` command, used to start the production server. ```bash Usage: ponder start [options] Start the production server Options: --schema Database schema (max: 45 characters) --views-schema Views database schema (max: 45 characters) -p, --port Port for the web server (default: 42069) -H, --hostname Hostname for the web server (default: "0.0.0.0" or "::") -h, --help display help for command ``` -------------------------------- ### Start Ponder Development Server Source: https://github.com/ponder-sh/ponder/blob/main/examples/with-foundry/README.md Start the Ponder development server to begin indexing your smart contract data. This command assumes your project is set up with pnpm. ```shell pnpm ponder dev ``` -------------------------------- ### Install Ponder Core v0.7 Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/migration-guide.mdx Install version 0.7 of the `@ponder/core` package using your preferred package manager. ```bash pnpm add @ponder/core@0.7 ``` ```bash yarn add @ponder/core@0.7 ``` ```bash npm add @ponder/core@0.7 ``` ```bash bun add @ponder/core@0.7 ``` -------------------------------- ### Start Ponder Development Server Source: https://context7.com/ponder-sh/ponder/llms.txt Start the local development server for Ponder projects. This includes hot reloading, a terminal UI, and an embedded database. ```bash pnpm dev ``` -------------------------------- ### Install @ponder/react with package managers Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder-react.mdx Install the @ponder/react package along with its peer dependencies, @ponder/client and @tanstack/react-query, using your preferred package manager. ```bash pnpm add @ponder/react @ponder/client @tanstack/react-query ``` ```bash yarn add @ponder/react @ponder/client @tanstack/react-query ``` ```bash npm add @ponder/react @ponder/client @tanstack/react-query ``` ```bash bun add @ponder/react @ponder/client @tanstack/react-query ``` -------------------------------- ### Example: Get persons with age greater than 32 Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx This example demonstrates how to query for `person` records where the `age` is greater than 32. ```APIDOC ## Example: Get all `person` records with an `age` greater than `32`. :::code-group ```graphql [Query] query { persons(where: { age_gt: 32 }) { name age } } ``` ```json [Result] { "persons": [ { "name": "Barry", "age": 57 }, { "name": "Pablo", "age": 71 }, ] } ``` ::: ``` -------------------------------- ### Start Local Anvil Node Source: https://github.com/ponder-sh/ponder/blob/main/examples/with-foundry/README.md Start a local Ethereum node using Anvil with a block time of 1 second for faster development cycles. ```shell anvil --block-time 1 ``` -------------------------------- ### Get Cast Help Source: https://github.com/ponder-sh/ponder/blob/main/examples/with-foundry/foundry/README.md Display help information for the Cast command-line tool. ```shell cast --help ``` -------------------------------- ### Backward Pagination Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx This example demonstrates how to paginate backward by using the `startCursor` from a previous response as the `before` argument in a new query. ```APIDOC ## Backward Pagination ### Description To paginate backward, use the `startCursor` from a previous response as the `before` argument in the next query. This allows you to retrieve records that appeared earlier in the dataset based on the sorting and limit. ### GraphQL Query ```graphql query { persons( orderBy: "age", orderDirection: "asc", limit: 2, before: "MxhcdoP9CVBhY" ) { items { name age } pageInfo { startCursor endCursor hasPreviousPage hasNextPage } totalCount } } ``` ### Response Example (Success) ```json { "persons": { "items": [ { "name": "Lucile", "age": 32 } ], "pageInfo": { "startCursor": "Mxhc3NDb3JlLTA=", "endCursor": "Mxhc3NDb3JlLTA=", "hasPreviousPage": true, "hasNextPage": true }, "totalCount": 4 } } ``` ``` -------------------------------- ### Start Ponder Development Server Source: https://github.com/ponder-sh/ponder/blob/main/README.md Run the development server to automatically reload on changes and view logs. Navigate to your project directory first. ```bash bun dev # or pnpm dev # or npm run dev ``` -------------------------------- ### Forward Pagination Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx This example shows how to paginate forward by using the `endCursor` from a previous response as the `after` argument in a new query. ```APIDOC ## Forward Pagination ### Description To paginate forward, use the `endCursor` from the previous response as the `after` argument in the next query. This retrieves the next set of records based on the established sorting and limit. ### GraphQL Query ```graphql query { persons( orderBy: "age", orderDirection: "asc", limit: 2, after: "Mxhc3NDb3JlLTA=" ) { items { name age } pageInfo { startCursor endCursor hasPreviousPage hasNextPage } totalCount } } ``` ### Response Example (Success) ```json { "persons": { "items": [ { "name": "Barry", "age": 57 }, { "name": "Pablo", "age": 71 } ], "pageInfo": { "startCursor": "MxhcdoP9CVBhY", "endCursor": "McSDfVIiLka==", "hasPreviousPage": true, "hasNextPage": false }, "totalCount": 4 } } ``` ``` -------------------------------- ### JSON Log Output Example Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/advanced/observability.mdx Example output when using the JSON log format. Each line is a distinct JSON object containing event details. ```json {"level":30,"time":1760372079306,"msg":"Indexed block","chain":"mainnet","chain_id":1,"number":23569912,"event_count":17,"duration":27.752416999996058} {"level":30,"time":1760372080106,"msg":"Indexed block","chain":"polygon","chain_id":137,"number":77633702,"event_count":0,"duration":3.4684160000033444} {"level":30,"time":1760372080122,"msg":"Indexed block","chain":"optimism","chain_id":10,"number":142386651,"event_count":0,"duration":2.3179999999993015} {"level":30,"time":1760372080314,"msg":"Indexed block","chain":"base","chain_id":8453,"number":36791366,"event_count":10,"duration":18.320999999996275} {"level":30,"time":1760372082131,"msg":"Indexed block","chain":"optimism","chain_id":10,"number":142386652,"event_count":0,"duration":3.074124999999185} {"level":30,"time":1760372082258,"msg":"Indexed block","chain":"polygon","chain_id":137,"number":77633703,"event_count":0,"duration":1.7850829999952111} {"level":30,"time":1760372082328,"msg":"Indexed block","chain":"base","chain_id":8453,"number":36791367,"event_count":4,"duration":9.394625000000815} {"level":30,"time":1760372084153,"msg":"Indexed block","chain":"optimism","chain_id":10,"number":142386653,"event_count":0,"duration":2.679999999993015} ``` -------------------------------- ### Get Forge Help Source: https://github.com/ponder-sh/ponder/blob/main/examples/with-foundry/foundry/README.md Display help information for the Forge command-line tool. ```shell forge --help ``` -------------------------------- ### Get Anvil Help Source: https://github.com/ponder-sh/ponder/blob/main/examples/with-foundry/foundry/README.md Display help information for the Anvil command-line tool. ```shell anvil --help ``` -------------------------------- ### Start Local Node with Anvil Source: https://github.com/ponder-sh/ponder/blob/main/examples/with-foundry/foundry/README.md Launch a local Ethereum node using Anvil. This provides a local environment for testing and development. ```shell anvil ``` -------------------------------- ### Set Database Schema using CLI Option Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/database.mdx Configure the database schema for a Ponder instance using the `--schema` CLI option when starting the application. This is necessary for `ponder start`. ```bash ponder start --schema my_schema ``` -------------------------------- ### Basic Hono App Setup Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/api-endpoints.mdx Default export a Hono app instance from `src/api/index.ts`. This is the entry point for Ponder's API server. ```typescript import { Hono } from "hono"; const app = new Hono(); app.get("/hello", (c) => { return c.text("Hello, world!"); }); export default app; ``` -------------------------------- ### Configure Sudoswap Pool Factory with Start Block Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/guides/factory.mdx Configure the Sudoswap factory contract to index new pairs, specifying a `startBlock` for collecting factory children. This allows indexing child contracts from a specific block while the factory itself might start later. ```typescript import { createConfig, factory } from "ponder"; // [!code focus] import { parseAbiItem } from "viem"; import { SudoswapPoolAbi } from "./abis/SudoswapPool"; export default createConfig({ chains: { /* ... */ }, contracts: { SudoswapPool: { abi: SudoswapPoolAbi, chain: "mainnet", address: factory({ address: "0xb16c1342E617A5B6E4b631EB114483FDB289c0A4", event: parseAbiItem("event NewPair(address poolAddress)"), parameter: "poolAddress", startBlock: 14645816, // [!code focus] }), // [!code focus] startBlock: "latest", // [!code focus] }, }, }); ``` -------------------------------- ### Add viem to Project Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/migration-guide.mdx Update the `viem` peer dependency to `>=2` by installing the latest version using your preferred package manager. ```bash pnpm add viem@latest ``` ```bash yarn add viem@latest ``` ```bash npm install viem@latest ``` ```bash bun add viem@latest ``` -------------------------------- ### Create Ponder App Source: https://github.com/ponder-sh/ponder/blob/main/benchmark/README.md Use this command to create the database objects for a Ponder app. Ensure you have the Ponder CLI installed. ```bash pnpm create:app [app id] ``` -------------------------------- ### Create a new Ponder project Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/get-started.mdx Use create-ponder to quickly set up a new Ponder project. Choose between the default template or an ERC-20 example. ```bash pnpm create ponder ``` ```bash yarn create ponder ``` ```bash npm init ponder@latest ``` ```bash bun --bun create ponder ``` -------------------------------- ### ponder serve Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/cli.mdx Starts the Ponder production HTTP server without the indexer, suitable for horizontally scaling the HTTP server. ```APIDOC ## serve ### Description Start the app in server-only mode. This option can be used to horizontally scale the HTTP server in production. Only works with Postgres. Project files are built once on startup, and file changes are ignored. Indexing is disabled. The HTTP server runs as normal, serving data from the connected database. ### Usage `ponder serve [options]` ### Options - **--schema** (SCHEMA) - Database schema (max: 45 characters) - **-p, --port** (PORT) - Port for the web server (default: 42069) - **-H, --hostname** (HOSTNAME) - Hostname for the web server (default: "0.0.0.0" or "::") - **-h, --help** - display help for command ``` -------------------------------- ### Add hono to Project Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/migration-guide.mdx Install `hono` as a peer dependency after upgrading to a version that requires it. ```bash pnpm add hono@latest ``` ```bash yarn add hono@latest ``` ```bash npm install hono@latest ``` ```bash bun add hono@latest ``` -------------------------------- ### Query Persons with Pagination Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx This example demonstrates how to query the 'persons' field with sorting and limiting, and how to interpret the pagination information. ```APIDOC ## Query Persons with Sorting and Limit ### Description This query retrieves a list of persons, ordered by age in ascending order, and limits the results to the first 2 records. It also includes pagination information. ### GraphQL Query ```graphql query { persons(orderBy: "age", orderDirection: "asc", limit: 2) { items { name age } pageInfo { startCursor endCursor hasPreviousPage hasNextPage } totalCount } } ``` ### Response Example (Success) ```json { "persons": { "items": [ { "name": "Sally", "age": 22 }, { "name": "Lucile", "age": 32 } ], "pageInfo": { "startCursor": "MfgBzeDkjs44", "endCursor": "Mxhc3NDb3JlLTA=", "hasPreviousPage": false, "hasNextPage": true }, "totalCount": 4 } } ``` ``` -------------------------------- ### Ponder Serve Command Usage Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/cli.mdx Usage for the `ponder serve` command, used to start the production HTTP server without the indexer. ```bash Usage: ponder serve [options] Start the production HTTP server without the indexer Options: --schema Database schema (max: 45 characters) -p, --port Port for the web server (default: 42069) -H, --hostname Hostname for the web server (default: "0.0.0.0" or "::") -h, --help display help for command ``` -------------------------------- ### Configure Database Connection Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/config.mdx Define database connection settings using the `DatabaseConfig` type. This example shows how to configure a PostgreSQL database connection. ```typescript import { createConfig, type DatabaseConfig } from "ponder"; const database = { kind: "postgres", connectionString: process.env.DATABASE_URL, } as const satisfies DatabaseConfig; export default createConfig({ database, // ... }); ``` -------------------------------- ### Configure Ponder with Contracts Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/indexing/read-contracts.mdx Define your project's contracts, including their chain, ABI, address, and start block, in the `ponder.config.ts` file. ```typescript import { createConfig } from "ponder"; import { BlitmapAbi } from "./abis/Blitmap"; export default createConfig({ chains: { mainnet: { id: 1, rpc: process.env.PONDER_RPC_URL_1 }, }, contracts: { Blitmap: { chain: "mainnet", abi: BlitmapAbi, address: "0x8d04...D3Ff63", startBlock: 12439123, }, }, }); ``` -------------------------------- ### Set up Ponder SQL Server Source: https://context7.com/ponder-sh/ponder/llms.txt Configure the Ponder client to handle SQL queries over HTTP. This setup is typically used on the server-side. ```typescript // Server setup: src/api/index.ts import { db } from "ponder:api"; import schema from "ponder:schema"; import { Hono } from "hono"; import { client } from "ponder"; const app = new Hono(); app.use("/sql/*", client({ db, schema })); export default app; ``` -------------------------------- ### Ponder DB List Command Result Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/cli.mdx Example output from the `ponder db list` command, showing active and historical deployments. ```bash │ Schema │ Active │ Last active │ Table count │ ├───────────────┼──────────┼────────────────┼─────────────┤ │ indexer_prod │ yes │ --- │ 10 │ │ test │ no │ 26m 58s ago │ 10 │ │ demo │ no │ 1 day ago │ 5 │ ``` -------------------------------- ### Example: Case-insensitive string filtering Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx This example shows how to perform case-insensitive filtering using `_starts_with_nocase`. It retrieves persons whose name starts with 'p', regardless of case. ```APIDOC ## Example: Get all `person` records with a `name` that starts with `"p"` regardless of case. :::code-group ```graphql [Query] query { persons(where: { name_starts_with_nocase: "p" }) { name age } } ``` ```json [Result] { "persons": [ { "name": "Pablo", "age": 71 }, ] } ``` ::: ``` -------------------------------- ### Configure Block Tracking Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/config.mdx Define block tracking settings using the `BlockConfig` type. This example configures tracking for the Chainlink Price Oracle contract, specifying the start block and interval. ```typescript import { createConfig, type BlockConfig } from "ponder"; const ChainlinkPriceOracle = { chain: "mainnet", startBlock: 19_750_000, interval: 5, } as const satisfies BlockConfig; export default createConfig({ blocks: { ChainlinkPriceOracle, }, // ... }); ``` -------------------------------- ### Initialize Ponder Project Source: https://github.com/ponder-sh/ponder/blob/main/README.md Use the create-ponder CLI to scaffold a new Ponder project. Supports npm, pnpm, and bun. ```bash bun create ponder # or pnpm create ponder # or npm init ponder@latest ``` -------------------------------- ### Using `ponder:api` `publicClients` Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/api-endpoints.mdx Demonstrates how to access Viem public clients for different chains via `publicClients` from `ponder:api`. ```APIDOC ## Using `ponder:api` `publicClients` ### Description This example shows how to use the `publicClients` object exported from `ponder:api` to interact with blockchain data. It fetches the balance of a given address on the 'base' chain. ### Method GET ### Endpoint /balance/:address ### Parameters #### Path Parameters - **address** (string) - Required - The address to check the balance for. ### Request Example (No request body) ### Response #### Success Response (200) - `application/json`: An object containing the address and its balance. ### Code Example ```ts import { publicClients } from "ponder:api"; // [!code focus] import { Hono } from "hono"; const app = new Hono(); app.get("/balance/:address", async (c) => { const address = c.req.param("address"); const balance = await publicClients["base"].getBalance({ address }); // [!code focus] return c.json({ address, balance }); }); export default app; ``` ``` -------------------------------- ### Run Ponder Development Server with Bun Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/guides/bun.mdx After updating `package.json`, you can start the Ponder development server using the `bun dev` command, which will now utilize the Bun runtime. ```bash bun dev ``` -------------------------------- ### GraphQL Schema Example Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx Example of a generated GraphQL schema for a `person` table, including singular and plural query fields. ```APIDOC ## GraphQL Schema Example ### Description Example of a generated GraphQL schema for a `person` table, including singular and plural query fields. ### Method N/A (Schema definition) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) ```graphql type person { id: Int! name: String! age: Int } type personPage { items: [person!]! pageInfo: PageInfo! totalCount: Int! } type Query { person(id: Int!): person persons( where: personFilter, orderBy: String, orderDirection: String, before: String, after: String, offset: Int, limit: Int, ): personPage! } ``` #### Response Example N/A ``` -------------------------------- ### Update Railway Start Command Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/migration-guide.mdx Railway users should update their start command to include the database schema, referencing the deployment ID. ```bash pnpm start --schema $RAILWAY_DEPLOYMENT_ID ``` ```bash yarn start --schema $RAILWAY_DEPLOYMENT_ID ``` ```bash npm run start -- --schema $RAILWAY_DEPLOYMENT_ID ``` ```bash bun start -- --schema $RAILWAY_DEPLOYMENT_ID ``` -------------------------------- ### Start Ponder Development Server Source: https://github.com/ponder-sh/ponder/blob/main/packages/core/README.md Run the development server to automatically reload on file changes and view logs. Supports npm, pnpm, and bun. ```bash bun dev ``` ```bash pnpm dev ``` ```bash npm run dev ``` -------------------------------- ### Registering a Basic GET Route Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/api-endpoints.mdx Registers a simple GET route '/hello' that returns 'Hello, world!'. This demonstrates how to add custom endpoints to the Hono app. ```typescript import { Hono } from "hono"; const app = new Hono(); app.get("/hello", (c) => { // [!code focus] return c.text("Hello, world!"); // [!code focus] }); // [!code focus] export default app; ``` -------------------------------- ### GraphQL Schema Example Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx Example of a GraphQL schema generated for a 'person' table defined in `ponder.schema.ts`. It includes singular and plural query fields with offset and cursor pagination. ```typescript import { onchainTable } from "ponder"; export const person = onchainTable("person", (t) => ({ id: t.integer().primaryKey(), name: t.text().notNull(), age: t.integer(), })); ``` ```graphql type person { id: Int! name: String! age: Int } type personPage { items: [person!]! pageInfo: PageInfo! totalCount: Int! } type Query { person(id: Int!): person persons( where: personFilter, orderBy: String, orderDirection: String, before: String, after: String, offset: Int, limit: Int, ): personPage! } ``` -------------------------------- ### Update Start Command for Railway Deployments Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/production/railway.mdx Use this command to enable zero-downtime deployments on Railway. Ensure the `--schema` option is included with the deployment ID. ```bash pnpm start --schema $RAILWAY_DEPLOYMENT_ID ``` ```bash yarn start --schema $RAILWAY_DEPLOYMENT_ID ``` ```bash npm run start -- --schema $RAILWAY_DEPLOYMENT_ID ``` ```bash bun start --schema $RAILWAY_DEPLOYMENT_ID ``` -------------------------------- ### Get Indexing Status via GraphQL Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/advanced/observability.mdx Query the `_meta` field in the GraphQL API to get the indexing status. This is useful for confirming that a specific block number has been ingested. ```graphql query { _meta { status } } ``` ```json { "_meta": { "status": { "mainnet": { "id": 1, "block": { "number": 20293464, "timestamp": 1720823939 } }, "base": { "id": 8453, "block": null } } } } ``` -------------------------------- ### Backward Pagination with GraphQL Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx Illustrates backward pagination in GraphQL by using the `startCursor` from a previous result as the `before` argument. ```graphql query { persons( orderBy: "age", orderDirection: "asc", limit: 2, before: "MxhcdoP9CVBhY" # [!code focus] ) { items { name age } pageInfo { startCursor endCursor hasPreviousPage hasNextPage } totalCount } } ``` ```json { "persons" { "items": [ { "name": "Lucile", "age": 32 }, ], "pageInfo": { "startCursor": "Mxhc3NDb3JlLTA=", "endCursor": "Mxhc3NDb3JlLTA=", "hasPreviousPage": true, "hasNextPage": true, }, "totalCount": 4, } } ``` -------------------------------- ### Run Migrations Source: https://github.com/ponder-sh/ponder/blob/main/simulation-test/README.md Run migrations to create necessary metadata and RPC cache tables. This is a prerequisite for all apps and tests. ```bash pnpm migrate ``` -------------------------------- ### Example: Combine filters with `AND` Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx This example shows how to combine multiple filter conditions using the `AND` operator. It retrieves persons whose name does not end with 'y' AND whose age is greater than or equal to 60. ```APIDOC ## Example: Get all `person` records with a `name` that does not end with `"y"` _and_ an age greater than `60`. Note that when you include multiple filter conditions, they are combined with a logical `AND`. :::code-group ```graphql [Query] query { persons( where: { AND: [ { name_not_ends_with: "y" }, { age_gte: 60 } ] } ) { name age } } ``` ```json [Result] { "persons": [ { "name": "Pablo", "age": 71 }, ] } ``` ::: ``` -------------------------------- ### Use 'setup' Event for Initial Data in Ponder Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/indexing-functions.mdx Demonstrates using the 'setup' event to initialize a singleton 'world' record once at the beginning of indexing. Subsequent events like 'NewPlayer' then update this record. ```typescript import { ponder } from "ponder:registry"; import { world } from "ponder:schema"; ponder.on("FunGame:setup", async ({ context }) => { await context.db.insert(world).values({ id: 1, playerCount: 0, }); }); ponder.on("FunGame:NewPlayer", async ({ context }) => { await context.db .update(world, { id: 1 }) .set((row) => ({ playerCount: row.playerCount + 1, })); }); ``` -------------------------------- ### Example: Combine filters with `OR` Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx This example demonstrates using the `OR` operator to retrieve records that satisfy at least one of the specified conditions. It fetches persons whose name contains 'll' OR whose age is greater than or equal to 50. ```APIDOC ## Example: Get all `person` records with a `name` that contains `"ll"` _or_ an age greater than or equal to `50`. In this case, we use the special `OR` operator to combine multiple filter conditions. :::code-group ```graphql [Query] query { persons( where: { OR: [ { name_contains: "ll" }, { age_gte: 50 } ] } ) { name age } } ``` ```json [Result] { "persons": [ { "name": "Barry", "age": 57 }, { "name": "Sally", "age": 22 }, { "name": "Pablo", "age": 71 }, ] } ``` ::: ``` -------------------------------- ### Create Ponder Project Source: https://github.com/ponder-sh/ponder/blob/main/packages/core/README.md Use the create-ponder CLI to scaffold a new Ponder project. Supports npm, pnpm, and bun. ```bash bun create ponder ``` ```bash pnpm create ponder ``` ```bash npm init ponder@latest ``` -------------------------------- ### Update Start Command for Views Schema Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/migration-guide.mdx When enabling the database views pattern, update the start command to include the `--views-schema` flag. This flag specifies the schema where Ponder will create views pointing to the latest deployment's tables. ```bash pnpm start --schema $RAILWAY_DEPLOYMENT_ID # [!code --] pnpm start --schema $RAILWAY_DEPLOYMENT_ID --views-schema my_project # [!code ++] ``` -------------------------------- ### getEnsAvatar Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/indexing/read-contracts.mdx Gets the avatar associated with an ENS name. ```APIDOC ## getEnsAvatar ### Description Retrieves the avatar (usually an IPFS URL or image URL) associated with an ENS name. ### Method Not specified (assumed to be a client method call) ### Endpoint Not applicable (SDK method) ### Parameters Refer to Viem documentation for specific parameters. ### Request Example ```javascript // Example usage with Ponder SDK (syntax may vary) const avatarUrl = await context.client.getEnsAvatar({ name: 'vitalik.eth' }); ``` ### Response #### Success Response - **avatarUrl** (string) - The URL of the avatar image. #### Response Example ```json { "avatarUrl": "ipfs://Qm..." } ``` ``` -------------------------------- ### Create a New Ponder Project Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/create-ponder.mdx Use the `create-ponder` command with your preferred package manager to initialize a new Ponder project. This command sets up the basic project structure and configuration files. ```bash pnpm create ponder {...options} ``` ```bash yarn create ponder {...options} ``` ```bash npm init ponder@latest {...options} ``` ```bash bun --bun create ponder {...options} ``` -------------------------------- ### Pagination Overview Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/query/graphql.mdx Explains Ponder's support for cursor and offset pagination, outlining their trade-offs in complexity and performance. ```APIDOC ## Pagination Ponder supports both **cursor** and **offset** pagination through a unified interface on each plural query field and `many()` relationship field. Here are some trade-offs to consider when choosing between cursor and offset pagination. | | Complexity | Query performance | Jump to any page | | :-------------------- | :----------- | :------------------------- | :--------------- | | **Cursor pagination** | More complex | Consistently fast | Not supported | | **Offset pagination** | Simple | Slow for large result sets | Supported | ### Page Each plural field and `many()` relationship field returns a `Page` type which includes a list of items, a `PageInfo` object, and the total count of records that match the query. ```ts [ponder.schema.ts] import { onchainTable } from "ponder"; export const pet = onchainTable("pet", (t) => ({ id: t.text().primaryKey(), name: t.text().notNull(), })); ``` ```graphql [Generated schema] { type petPage { # [!code focus] items: [pet!]! # [!code focus] pageInfo: PageInfo! # [!code focus] totalCount: Int! # [!code focus] } # [!code focus] type pet { id: String! name: String! } type PageInfo { startCursor: String endCursor: String hasPreviousPage: Boolean! hasNextPage: Boolean! } } ``` The `Page` type is the same for both pagination strategies. ### Page info The `PageInfo` object contains information about the position of the current page within the result set. | name | type | | | :------------------ | :------------------- | :---------------------------------------------- | | **startCursor** | `String` | Cursor of the first record in `items` | | **endCursor** | `String` | Cursor of the last record in `items` | | **hasPreviousPage** | `Boolean!` | Whether there are more records before this page | | **hasNextPage** | `Boolean!` | Whether there are more records after this page | The `PageInfo` type is the same for both pagination strategies, but the `startCursor` and `endCursor` values will always be `null` when using offset pagination. ### Total count The `totalCount` field returns the number of records present in the database that match the specified query. The value is the same regardless of the current pagination position and the `limit` argument. Only the `where` argument, or changes to the underlying dataset, can change the value of `totalCount`. :::warning The SQL query that backs `totalCount` can be slow. To avoid performance issues, consider including `totalCount` for the first page, then exclude it for subsequent pages. ::: ### Cursor pagination Cursor pagination works by taking the `startCursor` or `endCursor` value from the previous page's `PageInfo` and passing it as the `before` or `after` argument in the next query. :::info Note that plural query fields for views (`onchainView`) do not support cursor pagination. [Read more](/docs/schema/views). ::: #### Cursor values Each cursor value is an opaque string that encodes the position of a record in the result set. - Cursor values should not be decoded or manipulated by the client. The only valid use of a cursor value is an argument, e.g. `after: previousPage.endCursor`. - Cursor pagination works with any filter and sort criteria. However, do not change the filter or sort criteria between paginated requests. This will cause validation errors or incorrect results. ``` -------------------------------- ### getEnsName Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/indexing/read-contracts.mdx Gets the primary ENS name for a given address. ```APIDOC ## getEnsName ### Description Resolves an Ethereum address to its primary ENS name, if one is set. ### Method Not specified (assumed to be a client method call) ### Endpoint Not applicable (SDK method) ### Parameters Refer to Viem documentation for specific parameters. ### Request Example ```javascript // Example usage with Ponder SDK (syntax may vary) const ensName = await context.client.getEnsName({ address: '0xd8dA6BFc517074577d5E69395070DC95B3156329' }); ``` ### Response #### Success Response - **ensName** (string) - The primary ENS name for the address. #### Response Example ```json { "ensName": "vitalik.eth" } ``` ``` -------------------------------- ### Get Token Owner Source: https://github.com/ponder-sh/ponder/blob/main/examples/reference-erc20/README.md Find accounts that are designated as the owner of the token contract. ```APIDOC ## Get Token Owner ### Description Retrieves accounts that are identified as the owner of the token contract. ### Method GraphQL Query ### Endpoint N/A (GraphQL) ### Parameters #### Path Parameters None #### Query Parameters - **where** (Object) - Optional - Filtering criteria. - **isOwner** (Boolean) - Filters for accounts that are the owner. #### Request Body None ### Request Example ```graphql { accounts(where: { isOwner: true }) { id } } ``` ### Response #### Success Response (200) - **id** (String) - The account address of the owner. #### Response Example ```json { "data": { "accounts": [ { "id": "0xOwnerAddress1234567890abcdef1234567890abcdef1234" } ] } } ``` ``` -------------------------------- ### Configure Ethereum Mainnet and Optimism Chains Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/config/chains.mdx Set up multiple chains by providing their unique names, chain IDs, and RPC endpoints. Ensure RPC URLs are correctly set in environment variables. ```typescript import { createConfig } from "ponder"; export default createConfig({ chains: { mainnet: { id: 1, rpc: process.env.PONDER_RPC_URL_1, }, optimism: { id: 10, rpc: [ process.env.PONDER_RPC_URL_10, "https://optimism.llamarpc.com", ], }, }, contracts: { /* ... */ }, }); ``` -------------------------------- ### Create New Ponder Project with Bun Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/guides/bun.mdx Use this command to create a new Ponder project, leveraging Bun as both the package manager and runtime. ```bash bun --bun create ponder {...options} ``` -------------------------------- ### Set Log Format to Pretty Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/advanced/observability.mdx Use the --log-format pretty CLI option to enable the default human-readable log format. ```bash ponder start --log-format pretty ``` -------------------------------- ### getEnsAddress Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/indexing/read-contracts.mdx Gets the Ethereum Name Service (ENS) address for a given ENS name. ```APIDOC ## getEnsAddress ### Description Resolves an ENS name to its corresponding Ethereum address. ### Method Not specified (assumed to be a client method call) ### Endpoint Not applicable (SDK method) ### Parameters Refer to Viem documentation for specific parameters. ### Request Example ```javascript // Example usage with Ponder SDK (syntax may vary) const address = await context.client.getEnsAddress({ name: 'vitalik.eth' }); ``` ### Response #### Success Response - **address** (string) - The Ethereum address associated with the ENS name. #### Response Example ```json { "address": "0xd8dA6BFc517074577d5E69395070DC95B3156329" } ``` ``` -------------------------------- ### Using `ponder:api` `db` client Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/api-endpoints.mdx Shows how to use the `db` client exported from `ponder:api` for database operations. ```APIDOC ## Using `ponder:api` `db` client ### Description This example shows how to import the `db` client from the `ponder:api` virtual module and use it to perform database queries. It fetches a specific account by its address. ### Method GET ### Endpoint /account/:address ### Parameters #### Path Parameters - **address** (string) - Required - The address of the account to retrieve. ### Request Example (No request body) ### Response #### Success Response (200) - `application/json`: An array containing the account object if found, otherwise an empty array. ### Code Example ```ts import { db } from "ponder:api"; // [!code focus] import { accounts } from "ponder:schema"; import { Hono } from "hono"; import { eq } from "ponder"; const app = new Hono(); app.get("/account/:address", async (c) => { const address = c.req.param("address"); const account = await db // [!code focus] .select() // [!code focus] .from(accounts) // [!code focus] .where(eq(accounts.address, address)); // [!code focus] return c.json(account); }); export default app; ``` ``` -------------------------------- ### Get Account Balance and Approvals Source: https://github.com/ponder-sh/ponder/blob/main/examples/reference-erc20/README.md Retrieve the current balance and all approvals for a specific account. ```APIDOC ## Get Account Balance and Approvals ### Description Retrieves the current balance and all approvals for a given account. ### Method GraphQL Query ### Endpoint N/A (GraphQL) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```graphql { account(id: "0x1337f7970E8399ccbc625647FCE58a9dADA5aA66") { balance approvals { spender amount } } } ``` ### Response #### Success Response (200) - **balance** (String) - The current balance of the account. - **approvals** (Array of Objects) - A list of approvals granted by the account. - **spender** (String) - The address of the spender. - **amount** (String) - The approved amount. #### Response Example ```json { "data": { "account": { "balance": "1000000000000000000", "approvals": [ { "spender": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", "amount": "500000000000000000" } ] } } } ``` ``` -------------------------------- ### ponder dev Source: https://github.com/ponder-sh/ponder/blob/main/docs/pages/docs/api-reference/ponder/cli.mdx Starts the Ponder development server with hot reloading and an auto-updating terminal UI. ```APIDOC ## dev ### Description Start the app in development mode. The app automatically restarts when changes are detected in any project file. An auto-updating terminal UI displays useful information. ### Usage `ponder dev [options]` ### Options - **--schema** (SCHEMA) - Database schema (max: 45 characters) - **--disable-ui** - Disable the terminal UI - **-p, --port** (PORT) - Port for the web server (default: 42069) - **-H, --hostname** (HOSTNAME) - Hostname for the web server (default: "0.0.0.0" or "::") - **-h, --help** - display help for command ``` -------------------------------- ### Get Account Transfer Events Source: https://github.com/ponder-sh/ponder/blob/main/examples/reference-erc20/README.md Retrieve all transfer events associated with an account, both as a sender and receiver. ```APIDOC ## Get Account Transfer Events ### Description Retrieves all transfer events where the specified account is either the sender or the receiver. ### Method GraphQL Query ### Endpoint N/A (GraphQL) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```graphql { account(id: "0x1337f7970E8399ccbc625647FCE58a9dADA5aA66") { transferEventsTo { from amount } transferEventsFrom { to amount } } } ``` ### Response #### Success Response (200) - **transferEventsTo** (Array of Objects) - Events where the account received tokens. - **from** (String) - The address of the sender. - **amount** (String) - The amount transferred. - **transferEventsFrom** (Array of Objects) - Events where the account sent tokens. - **to** (String) - The address of the receiver. - **amount** (String) - The amount transferred. #### Response Example ```json { "data": { "account": { "transferEventsTo": [ { "from": "0xSenderAddress1234567890abcdef1234567890abcdef12", "amount": "100000000000000000" } ], "transferEventsFrom": [ { "to": "0xReceiverAddress1234567890abcdef1234567890abcdef12", "amount": "50000000000000000" } ] } } } ``` ``` -------------------------------- ### Compile Contracts with Forge Source: https://github.com/ponder-sh/ponder/blob/main/examples/with-foundry/README.md Compile your smart contracts using the Forge build command. ```shell forge build ```