ponder.config.ts
The ponder.config.ts
file defines chain IDs, RPC URLs, contract addresses & ABIs, and database configuration.
File requirements
The ponder.config.ts
file must default export the object returned by createConfig
.
import { createConfig } from "ponder";
export default createConfig({
chains: { /* ... */ },
contracts: { /* ... */ },
});
By default, ponder dev
and start
look for ponder.config.ts
in the current working directory. Use the --config-file
CLI option to specify a different path.
createConfig
database
Here is the logic Ponder uses to determine which database to use:
- If the
database.kind
option is specified, use the specified database. - If the
DATABASE_URL
environment variable is defined, use Postgres with that connection string. - If
DATABASE_URL
is not defined, use PGlite.
field | type | |
---|---|---|
kind | "pglite" | "postgres" | Default: See above. Database to use. |
PGlite
field | type | |
---|---|---|
kind | "pglite" | |
directory | string | Default: .ponder/pglite . Directory path to use for PGlite database files. |
import { createConfig } from "ponder";
export default createConfig({
database: {
kind: "pglite",
directory: "./.ponder/pglite",
},
// ...
});
Postgres
field | type | |
---|---|---|
kind | "postgres" | |
connectionString | string | Default: DATABASE_URL env var. Postgres database connection string. |
poolConfig | PoolConfig | Default: { max: 30 } . Pool configuration passed to node-postgres . |
import { createConfig } from "ponder";
export default createConfig({
database: {
kind: "postgres",
connectionString: "postgresql://user:password@localhost:5432/dbname",
poolConfig: {
max: 100,
ssl: true,
},
},
// ...
});
ordering
Specifies how events across multiple chains should be ordered. For single-chain apps, ordering
has no effect.
Usage
import { createConfig } from "ponder";
export default createConfig({
ordering: "multichain",
chains: { /* ... */ },
// ... more config
});
Parameters
field | type | |
---|---|---|
ordering | "omnichain" | "multichain" | Default: "omnichain" . Event ordering strategy. |
Guarantees
The omnichain and multichain ordering strategies offer different guarantees. Multichain ordering is generally faster, but will fail or produce a non-deterministic database state if your indexing logic attempts to access the same database row(s) from multiple chains.
Omnichain (default) | Multichain | |
---|---|---|
Event order for any individual chain | Deterministic, by EVM execution | Deterministic, by EVM execution |
Event order across chains | Deterministic, by (block timestamp, chain ID, block number) | Non-deterministic, no ordering guarantee |
Realtime indexing latency | Medium-high, must wait for the slowest chain to maintain ordering guarantee | Low, each chain indexes blocks as soon as they arrive |
Indexing logic constraints | None | Must avoid cross-chain writes or use commutative logic |
Use cases | Bridges, cross-chain contract calls, global constraints | Same protocol deployed to multiple chains |
chains
An object mapping chain names to chain configuration.
Usage
import { createConfig } from "ponder";
import { BlitmapAbi } from "./abis/Blitmap";
export default createConfig({
chains: {
mainnet: {
id: 1,
rpc: process.env.PONDER_RPC_URL_1,
},
},
// ...
});
Parameters
field | type | |
---|---|---|
name | string | Required. A unique name for the chain. Must be unique across all chains. Provided as the object property name. |
id | number | Required. The chain ID for the chain. |
transport | Transport | Required. A Viem Transport e.g. http or fallback . |
pollingInterval | number | Default: 1_000 . Frequency (in ms) used when polling for new events on this chain. |
maxRequestsPerSecond | number | Default: 50 . Maximum number of RPC requests per second. Can be reduced to work around rate limits. |
disableCache | boolean | Default: false . Disables the RPC request cache. Use when indexing a local node like Anvil. |
contracts
An object mapping contract names to contract configuration. Ponder will fetch RPC data and run indexing functions according to the options you provide.
Usage
import { createConfig } from "ponder";
import { BlitmapAbi } from "./abis/Blitmap";
export default createConfig({
contracts: {
Blitmap: {
abi: BlitmapAbi,
chain: "mainnet",
address: "0x8d04a8c79cEB0889Bdd12acdF3Fa9D207eD3Ff63",
startBlock: 12439123,
},
},
// ...
});
Parameters
field | type | |
---|---|---|
name | string | Required. A unique name for the smart contract. Must be unique across all contracts. Provided as the object property name. |
abi | abitype.Abi | Required. The contract ABI as an array as const. Must be asserted as constant, see ABIType documentation for details. |
chain | string | ChainConfig | Required. The name of the chain this contract is deployed to. References the chains field. Also supports multiple chains. |
address | 0x{string} | 0x{string}[] | Factory | Default: undefined . One or more contract addresses or factory configuration. |
startBlock | number | "latest" | Default: 0 . Block number or tag to start indexing. Usually set to the contract deployment block number. |
endBlock | number | "latest" | Default: undefined . Block number or tag to stop indexing. If this field is specified, the contract will not be indexed in realtime. This field can be used alongside startBlock to index a specific block range. |
filter | Filter | Default: undefined . Event filter criteria. Read more. |
includeTransactionReceipts | boolean | Default: false . If this field is true , transactionReceipt will be included in event . |
includeCallTraces | boolean | Default: false . If this field is true , each function in the abi will be available as an indexing function event name. Read more. |
filter
The filter
option is used to filter event logs by argument value. Read more about log filters.
field | type | |
---|---|---|
event | string | string[] | Required. One or more event names present in the provided ABI. |
args | object | Required. An object containing indexed argument values to filter for. Only allowed if one event name was provided in event . |
accounts
An object mapping account names to account configuration. Accounts are used to index transactions or native transfers.
Usage
import { createConfig } from "ponder";
export default createConfig({
accounts: {
coinbasePrime: {
chain: "mainnet",
address: "0xCD531Ae9EFCCE479654c4926dec5F6209531Ca7b",
startBlock: 12111233,
},
},
// ...
});
Parameters
field | type | |
---|---|---|
name | string | Required. A unique name for the smart contract. Must be unique across all contracts. Provided as the object property name. |
chain | string | Required. The name of the chain this contract is deployed to. References the chains field. Also supports multiple chains. |
address | 0x{string} | 0x{string}[] | Factory | Default: undefined . One or more contract addresses or factory configuration. |
startBlock | number | Default: 0 . Block number to start syncing events. |
endBlock | number | Default: undefined . Block number to stop syncing events. If this field is specified, the contract will not be indexed in realtime. This field can be used alongside startBlock to index a specific block range. |
includeTransactionReceipts | boolean | Default: false . If this field is true , transactionReceipt will be included in event . |
blocks
An object mapping block interval names to block interval configuration.
Usage
import { createConfig } from "ponder";
export default createConfig({
blocks: {
ChainlinkPriceOracle: {
chain: "mainnet",
startBlock: 19_750_000,
interval: 5, // every minute
},
},
// ...
});
Parameters
field | type | |
---|---|---|
name | string | Required. A unique name for the block interval. Must be unique across all block intervals. Provided as the object property name. |
chain | string | Required. The name of the chain this block interval is deployed to. References the chains field. Also supports multiple chains. |
startBlock | number | Default: 0 . Block number to start syncing events. |
endBlock | number | Default: undefined . Block number to stop syncing events. If this field is specified, the contract will not be indexed in realtime. This field can be used alongside startBlock to index a specific block range. |
interval | number | Default: 0 . The interval between blocks to index. |
factory
Specifies a list of addresses collected from decoded event logs. Both contracts
and accounts
support factory()
in their address
field. Read more in the factory pattern guide.
field | type | |
---|---|---|
address | 0x{string} | 0x{string}[] | Required. Address of the factory contract that creates instances of this contract. |
event | AbiEvent | Required. ABI item of the event that announces the creation of a new child contract. |
parameter | string | Required. Name of the parameter within event that contains child contract addresses. |
import { createConfig, factory } from "ponder";
export default createConfig({
contracts: {
uniswapV2: {
// ...
address: factory({
address: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
event: parseAbiItem(
"event PairCreated(address indexed token0, address indexed token1, address pair, uint256)"
),
parameter: "pair",
}),
},
},
// ...
});
Types
The ponder
package exports several utility types. Use these types to maintain type safety when generating config options dynamically.
DatabaseConfig
import { createConfig, type DatabaseConfig } from "ponder";
const database = {
kind: "postgres",
connectionString: process.env.DATABASE_URL,
} as const satisfies DatabaseConfig;
export default createConfig({
database,
// ...
});
ChainConfig
import { createConfig, type ChainConfig } from "ponder";
const mainnet = {
id: 1,
rpc: process.env.PONDER_RPC_URL_1,
} as const satisfies ChainConfig;
export default createConfig({
chains: {
mainnet,
}
// ...
});
ContractConfig
import { createConfig, type ContractConfig } from "ponder";
import { Erc20Abi } from "./abis/Erc20Abi.ts";
const Erc20 = {
chain: "mainnet"
abi: Erc20Abi,
address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
} as const satisfies ContractConfig;
export default createConfig({
contracts: {
Erc20,
},
// ...
});
BlockConfig
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,
},
// ...
});