Skip to content

Commit

Permalink
Merge branch 'main' into o-az/vite-dev-server
Browse files Browse the repository at this point in the history
  • Loading branch information
0xOlias committed Nov 7, 2023
2 parents 27bd3e1 + 584b541 commit 91959db
Show file tree
Hide file tree
Showing 140 changed files with 10,206 additions and 10,015 deletions.
10 changes: 10 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
"changelog": ["@changesets/changelog-github", { "repo": "0xOlias/ponder" }],
"commit": false,
"fixed": [["@ponder/core", "create-ponder", "eslint-config-ponder"]],
"ignore": [
"ponder-examples-ethfs",
"ponder-examples-art-gobblers",
"ponder-examples-factory-llama",
"ponder-examples-friendtech",
"ponder-examples-token-erc20",
"ponder-examples-token-erc721",
"ponder-examples-token-reth",
"ponder-examples-with-docker"
],
"linked": [],
"access": "public",
"baseBranch": "main",
Expand Down
7 changes: 0 additions & 7 deletions .changeset/large-buckets-flash.md

This file was deleted.

21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ Join [Ponder's telegram chat](https://t.me/ponder_sh) for support, feedback, and
&nbsp;Supports all Ethereum-based blockchains, including test nodes like [Anvil](https://book.getfoundry.sh/anvil)<br/>
&nbsp;Index events from multiple chains in the same app<br/>
&nbsp;Reconciles chain reorganization<br/>
🏗️ &nbsp;Transaction call event handlers<br/>
🏗️ &nbsp;Support for factory contracts like Uniswap V2/V3<br/>
&nbsp;Factory contracts<br/>
🏗️ &nbsp;Process transactions calls (in addition to logs)<br/>
🏗️ &nbsp;Run effects (e.g. send an API request) in indexing code<br/>

## Quickstart

### 1. Run `create-ponder`

You will be asked for a project name, and if you are using an Etherscan or Graph Protocol [template](https://ponder.sh/api-reference/create-ponder) (recommended).
You will be asked for a project name, and if you are using a [template](https://ponder.sh/api-reference/create-ponder#templates) (recommended). Then, the CLI will create a project directory, install dependencies, and initialize a git repository.

```bash
npm init ponder@latest
Expand All @@ -45,7 +46,7 @@ yarn create ponder

### 2. Start the development server

The development server automatically reloads your app when you save changes in any project file, and prints `console.log` statements and errors in your code.
Just like Next.js and Vite, Ponder has a development server that automatically reloads when you save changes in any project file. It also prints `console.log` statements and errors encountered while running your code. First, `cd` into your project directory, then start the server.

```bash
npm run dev
Expand All @@ -57,7 +58,7 @@ yarn dev

### 3. Add contracts & networks

Ponder fetches event logs for the contracts added to `ponder.config.ts`, and passes those events to the handler functions you write.
Ponder fetches event logs for the contracts added to `ponder.config.ts`, and passes those events to the indexing functions you write.

```ts
// ponder.config.ts
Expand Down Expand Up @@ -85,7 +86,7 @@ export const config = {

### 4. Define your schema

The `schema.graphql` file specifies the shape of your application's data.
The `schema.graphql` file contains a model of your application data. The entity types defined here correspond to database tables.

```ts
// schema.graphql
Expand All @@ -98,9 +99,9 @@ type EnsName @entity {
}
```

### 5. Write event handlers
### 5. Write indexing functions

Use event handler functions to convert raw blockchain events into application data.
Files in the `src/` directory contain **indexing functions**, which are TypeScript functions that process a contract event. The purpose of these functions is to insert data into the entity store.

```ts
// src/BaseRegistrar.ts
Expand All @@ -122,9 +123,11 @@ ponder.on("BaseRegistrar:NameRegistered", async ({ event, context }) => {
});
```

See the [create & update entities](https://ponder.sh/guides/create-update-entities) docs for a detailed guide on writing indexing functions.

### 6. Query the GraphQL API

Ponder automatically generates a frontend-ready GraphQL API based on your project's `schema.graphql`. The API will serve the data that you inserted in your event handler functions.
Ponder automatically generates a frontend-ready GraphQL API based on your project's `schema.graphql`. The API serves the data that you inserted in your indexing functions.

```ts
{
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/src/ponder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const waitForSyncComplete = async () => {
const metrics = await fetchPonderMetrics();
const latestProcessedTimestamp =
metrics.find(
(m) => m.name === "ponder_handlers_latest_processed_timestamp"
(m) => m.name === "ponder_indexing_latest_processed_timestamp"
)?.metrics[0].value ?? 0;
console.log(
`Latest processed timestamp: ${latestProcessedTimestamp}/${END_BLOCK_TIMESTAMP}`
Expand Down
4 changes: 2 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"dependencies": {
"@segment/analytics-node": "^1.1.0",
"next": "^13.4.12",
"nextra": "^2.10.0",
"nextra-theme-docs": "^2.10.0",
"nextra": "^2.13.2",
"nextra-theme-docs": "^2.13.2",
"react": "^18.1.0",
"react-dom": "^18.1.0"
},
Expand Down
6 changes: 3 additions & 3 deletions docs/pages/advanced/factory-contracts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ export const config: Config = {
};
```

### Register event handlers
### Register indexing functions

When you register a handler function for a child contract event, that function will process events for **every** instance of that child contract. The `event.log.address` field contains the address of the specific child contract that emitted the event.
When you register an indexing function for a child contract event, that function will process events for **every** instance of that child contract. The `event.log.address` field contains the address of the specific child contract that emitted the event.

This event handler function will run for every `SudoswapPool` contract created by the factory.
This indexing function will run for every `SudoswapPool` contract created by the factory.

```ts filename="src/index.ts"
import { ponder } from "@/generated";
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/advanced/proxy-contracts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Callout } from "nextra-theme-docs";

# Proxy contracts

Ponder supports [EIP-1967 proxy contracts](https://docs.openzeppelin.com/contracts/4.x/api/proxy) (Transparent and UUPS). Ponder handles proxy contracts by merging the ABI of the proxy contract with the ABI of the implementation contract.
Ponder supports [EIP-1967 proxy contracts](https://docs.openzeppelin.com/contracts/4.x/api/proxy) (Transparent and UUPS) by merging the ABI of the proxy contract with the ABI of the implementation contract.

The `create-ponder` Etherscan [contract link template](/api-reference/create-ponder#etherscan-contract-link) automatically detects proxy contracts and fetches all implementation contract ABIs.

Expand Down Expand Up @@ -45,7 +45,7 @@ export const config: Config = {
};
```

3. Add event handlers for events defined in the implementation ABI. That's it!
3. Add indexing functions for events defined in the implementation ABI. That's it!

```ts filename="src/index.ts"
import { ponder } from "@/generated";
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/api-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: "Table of contents for Ponder API reference"

[Create Ponder →](/api-reference/create-ponder)

[Event handlers](/api-reference/event-handlers)
[Indexing functions](/api-reference/indexing-functions)

[`ponder.config.ts`](/api-reference/ponder-config)

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/api-reference/_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ponder-config": "ponder.config.ts",
"schema-graphql": "schema.graphql",
"event-handlers": "Event handlers",
"indexing-functions": "Indexing functions",
"create-ponder": "Create Ponder"
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
description: "API reference for Ponder event handlers"
description: "API reference for Ponder indexing functions"
---

import { Callout } from "nextra-theme-docs";

# Event handler API
# Indexing function API

Event handlers are user-defined functions that process blockchain data. They can be registered within any `.ts` file inside the `src/` directory. There are two kinds of events: **log events** and the **`"setup"` event**.
Indexing functions are user-defined functions that process blockchain data. They can be registered within any `.ts` file inside the `src/` directory. There are two kinds of events: **log events** and the **`"setup"` event**.

## Log events

Log events correspond to a smart contract event log that has occurred. The Ponder engine fetches event logs for all contracts defined in `ponder.config.ts`, then passes that data to the corresponding handler function.
Log events correspond to a smart contract event log that has occurred. The Ponder engine fetches event logs for all contracts defined in `ponder.config.ts`, then passes that data to the corresponding indexing function.

```ts filename="src/index.ts"
import { ponder } from "@/generated";
Expand All @@ -25,14 +25,12 @@ ponder.on("ContractName:EventName", async ({ event, context }) => {

### Options

| name | description |
| :------------------------------------------------- | :--------------------------------------------------------------- |
| [`event`](/api-reference/event-handlers#event) | Event-specific data (log arguments, log, block, and transaction) |
| [`context`](/api-reference/event-handlers#context) | Global resources (entity objects, read-only contract objects) |
| name | description |
| :----------------------------------------------------- | :--------------------------------------------------------------- |
| [`event`](/api-reference/indexing-functions#event) | Event-specific data (log arguments, log, block, and transaction) |
| [`context`](/api-reference/indexing-functions#context) | Global resources (entity objects, read-only contract objects) |

<Callout type="info">
The value returned by event handler functions is ignored.
</Callout>
<Callout type="info">Value returned by indexing functions are ignored.</Callout>

### `Event`

Expand Down Expand Up @@ -183,7 +181,7 @@ See [Create & update entities](/guides/create-update-entities) for a complete AP

`ReadOnlyContract` objects are used to read data directly from a contract. These objects have a method for each read-only function present in the contract's ABI (functions with state mutability of `"pure"` or `"view"`). The `context.contracts` object has a `ReadOnlyContract` for each contract defined in [ponder.config.ts](/api-reference/ponder-config#contracts).

A `ReadOnlyContract` is a [viem Contract Instance](https://viem.sh/docs/contract/getContract.html#contract-instances) that has been modified to cache contract read results. By default, contract reads use the `eth_call` RPC method with `blockNumber` set to the block number of the event being handled (`event.block.number`). You can read the contract at a different block number (e.g. the contract deployment block number or `"latest"`) by passing the `blockNumber` or `blockTag` option, but this will disable caching.
A `ReadOnlyContract` is a [viem Contract Instance](https://viem.sh/docs/contract/getContract.html#contract-instances) that has been modified to cache contract read results. By default, contract reads use the `eth_call` RPC method with `blockNumber` set to the block number of the event being processed (`event.block.number`). You can read the contract at a different block number (e.g. the contract deployment block number or `"latest"`) by passing the `blockNumber` or `blockTag` option, but this will disable caching.

```ts filename="src/index.ts"
import { ponder } from "@/generated";
Expand All @@ -192,7 +190,7 @@ ponder.on("MyERC20:Transfer", async ({ event, context }) => {
const { MyERC20 } = context.contracts;

// This read will occur at the block number of the event being
// handled (event.block.number) and will be served from the cache
// processed (event.block.number) and will be served from the cache
// on hot reloads / reployments.
const totalSupply = await MyERC20.read.totalSupply();

Expand All @@ -206,7 +204,7 @@ ponder.on("MyERC20:Transfer", async ({ event, context }) => {

## The `"setup"` event

You can also define a handler for a special event called `"setup"` that runs before all other event handlers.
You can also define an indexing function for a special event called `"setup"` that runs before all other events.

```ts filename="src/index.ts"
import { ponder } from "@/generated";
Expand All @@ -220,6 +218,6 @@ ponder.on("setup", async ({ context }) => {

### Options

| name | description |
| :------------------------------------------------- | :------------------------------------------------------------ |
| [`context`](/api-reference/event-handlers#context) | Global resources (entity objects, read-only contract objects) |
| name | description |
| :----------------------------------------------------- | :------------------------------------------------------------ |
| [`context`](/api-reference/indexing-functions#context) | Global resources (entity objects, read-only contract objects) |
6 changes: 3 additions & 3 deletions docs/pages/api-reference/ponder-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Networks are Ethereum-based blockchains like Ethereum mainnet, Goerli, or Foundr

### Contracts

Contracts are smart contracts deployed to a network. All contracts defined here will become available as `ReadOnlyContract` objects in the event context. Ponder will fetch and handle event logs emitted by all contracts with `isLogEventSource: true` (the default).
Contracts are smart contracts deployed to a network. All contracts defined here will become available as `ReadOnlyContract` objects in the event context. Ponder will fetch and process event logs emitted by all contracts with `isLogEventSource: true` (the default).

| field | type | |
| :------------------- | :---------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -45,7 +45,7 @@ Contracts are smart contracts deployed to a network. All contracts defined here
| **startBlock** | `number \| undefined` | **Default: `0`**. Block number to start handling events. Usually set to the contract deployment block number. **Default: `0`** |
| **endBlock** | `number \| undefined` | **Default: `undefined`**. Block number to stop handling events. If this field is specified, Ponder will not listen to "live" events. This field can be used alongside `startBlock` to only process events for a range of blocks. |
| **maxBlockRange** | `number \| undefined` | The maximum block range that Ponder will use when calling `eth_getLogs`. If not provided, Ponder uses a sane default based on the network. |
| **isLogEventSource** | `boolean \| undefined` | **Default: `true`**. Specifies if events should be handled for this contract. If `false`, this contrat will still be available on the event handler `context.contracts`. |
| **isLogEventSource** | `boolean \| undefined` | **Default: `true`**. Specifies if events should be processed for this contract. If `false`, this contract will still be available on the indexing function `context.contracts`. |

#### Factory

Expand All @@ -57,7 +57,7 @@ Contracts are smart contracts deployed to a network. All contracts defined here

### Filters

Filters are custom event log filters that are more flexible than `contracts`. Ponder will fetch and handle event logs that match the `filter` field.
Filters are custom event log filters that are more flexible than `contracts`. Ponder will fetch and process event logs that match the `filter` field.
| field | type | |
| :------------- | :--------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **name** | `string` | A unique name for the custom filter. Must be unique across all contracts & filters. |
Expand Down
2 changes: 0 additions & 2 deletions docs/pages/api-reference/schema-graphql.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,5 @@ Ponder currently supports a subset of the Graph Protocol schema definition langu

- `BigDecimal` and `ID` GraphQL field types
- Full text search
- Call handlers
- Block handlers
- Anonymous events
- The `immutable` argument to the `@entity` type directive is allowed for compatibility, but immutability is not enforced
2 changes: 1 addition & 1 deletion docs/pages/compared-to-subgraphs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ description: "A comparison between Ponder and Graph Protocol subgraphs"
| Cross-chain support |&nbsp;Any number of chains per app |&nbsp;Each subgraph indexes one chain |
| Chain reorganizations |||
| Time-travel queries |||
| Factory contracts | 🚧 (in progress) ||
| Factory contracts | ||
| Transaction call handlers | 🚧 (planned) ||
| Block handlers | 🚧 (planned) ||
Loading

0 comments on commit 91959db

Please sign in to comment.