-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix: unfinalized start block in historical sync * support future end block * support future end block * remove validateHistoricalBlockRange * chore: changeset * nits * initial commit * project foundry * . * prune by source sqlite * foundry example * revive foundry docs * merge stash * prune by source * work on example foundry * cleanup example * readme * cleanup * fix path * docs * fix ui bug * include run latest * lockfile * docs * fix lint * pruneByChainId * disable caching * docs tweaks * readme --------- Co-authored-by: typedarray <[email protected]>
- Loading branch information
1 parent
de9949f
commit 07e39ed
Showing
32 changed files
with
1,345 additions
and
816 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
[submodule "examples/with-foundry/contracts/lib/forge-std"] | ||
path = examples/with-foundry/contracts/lib/forge-std | ||
[submodule "examples/with-foundry/foundry/lib/forge-std"] | ||
path = examples/with-foundry/foundry/lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
export default { | ||
foundry: "Foundry", | ||
logging: "Logging", | ||
telemetry: "Telemetry", | ||
metrics: "Metrics", | ||
metrics: "Metrics" | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
--- | ||
title: "Integrate with Foundry" | ||
description: "A guide for using Ponder with the Foundry smart contract development toolchain." | ||
--- | ||
|
||
import { Callout, Steps } from "nextra/components"; | ||
|
||
# Foundry | ||
|
||
This guide describes how to integrate Ponder and Foundry during local development. | ||
|
||
Foundry projects follow various development workflows (test-driven, deploy to a fresh chain, deploy to a fork, etc). Rather than a one-size-fits-all integration, this page offers patterns that you can adapt to your workflow. | ||
|
||
## Configure the `anvil` network | ||
|
||
### Disable caching | ||
|
||
Ponder's RPC request cache works well for live networks where the chain is generally immutable, but causes issues when indexing a local chain that "resets". | ||
|
||
Use the `disableCache` option to **disable RPC request caching** for the Anvil network. With this option set to true, Ponder will clear the cache on start up and between hot reloads. | ||
|
||
```ts filename="ponder.config.ts" {9} | ||
import { createConfig } from "@ponder/core"; | ||
import { http } from "viem"; | ||
|
||
export default createConfig({ | ||
networks: { | ||
anvil: { | ||
chainId: 31337, | ||
transport: http("http://127.0.0.1:8545"), | ||
disableCache: true, | ||
}, | ||
}, | ||
// ... | ||
}); | ||
``` | ||
|
||
### Chain ID | ||
|
||
We recommend using `31337` (the default Anvil chain ID) even when forking a live chain. This avoids common footguns when working with multiple networks. | ||
|
||
### Mining mode | ||
|
||
We recommend using [interval mining](https://book.getfoundry.sh/reference/anvil/#mining-modes) with a block time of ~2 seconds. This better simulates a live network. | ||
|
||
<Callout type="warning">Known issue: When indexing Anvil with auto mining enabled in an app with multiple networks, indexing progress will get "stuck" at the timestamp of the latest Anvil block. </Callout> | ||
|
||
## Generate ABI files | ||
|
||
To enable end-to-end type safety, the contract ABIs generated by Foundry must be copied into TypeScript (`.ts`) source files. | ||
|
||
### Wagmi CLI | ||
|
||
The Wagmi CLI [Foundry plugin](https://wagmi.sh/cli/api/plugins/foundry) is an excellent tool to automate tedious ABI file management. For more information, visit the [Wagmi CLI documentation](https://wagmi.sh/cli/getting-started). | ||
|
||
Here is the Wagmi CLI config file used by the Foundry [example project](https://github.com/ponder-sh/ponder/tree/main/examples/with-foundry). | ||
|
||
```ts filename="wagmi.config.ts" | ||
import { defineConfig } from "@wagmi/cli"; | ||
import { foundry } from "@wagmi/cli/plugins"; | ||
|
||
export default defineConfig({ | ||
out: "abis/CounterAbi.ts", | ||
plugins: [ | ||
foundry({ | ||
project: "foundry", | ||
include: ["Counter.sol/**"], | ||
}), | ||
], | ||
}); | ||
``` | ||
|
||
## Import broadcast files | ||
|
||
Foundry scripts write transaction inputs and receipts to JSON files in the `broadcast` directory. You can import these files directly into `ponder.config.ts` to automate address management and enable hot reloading. | ||
|
||
<Callout type="info">Remember to enable [broadcast](https://book.getfoundry.sh/tutorials/solidity-scripting?highlight=deploy#deploying-locally) so that `forge script` submits transactions to Anvil.</Callout> | ||
|
||
### Automate address management | ||
|
||
To read the contract address and deployment block number from a broadcast file, import the file directly into `ponder.config.ts` and access properties from the JSON object. | ||
|
||
The `ponder.config.ts` file from the Foundry [example project](https://github.com/ponder-sh/ponder/tree/main/examples/with-foundry) demonstrates this pattern. Here, the first transaction in the broadcast file deployed the `Counter.sol` contract. The location of the contract address and start block within the broadcast file depends on the order and number of transactions in your deployment script. | ||
|
||
```ts filename="ponder.config.ts" {4, 6-7, 21-22} | ||
import { createConfig } from "@ponder/core"; | ||
import { http, getAddress, hexToNumber } from "viem"; | ||
import { counterABI } from "../abis/CounterAbi"; | ||
import CounterDeploy from "../foundry/broadcast/Deploy.s.sol/31337/run-latest.json"; | ||
|
||
const address = getAddress(CounterDeploy.transactions[0]!.contractAddress); | ||
const startBlock = hexToNumber(CounterDeploy.receipts[0]!.blockNumber); | ||
|
||
export default createConfig({ | ||
networks: { | ||
anvil: { | ||
chainId: 31337, | ||
transport: http("http://127.0.0.1:8545"), | ||
disableCache: true, | ||
}, | ||
}, | ||
contracts: { | ||
Counter: { | ||
network: "anvil", | ||
abi: counterABI, | ||
address, | ||
startBlock, | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
### Enable hot reloading | ||
|
||
If you import a JSON broadcast file in `ponder.config.ts`, the dev server will reload each time that file changes. This is a simple way to ensure that Ponder reloads every time you run a Foundry deployment script. | ||
|
||
```ts filename="ponder.config.ts" {3-4} | ||
import { createConfig } from "@ponder/core"; | ||
import { http } from "viem"; | ||
import CounterDeploy from "../foundry/broadcast/Deploy.s.sol/31337/run-latest.json"; | ||
// ^ The development server detects changes to this file and triggers a hot reload. | ||
|
||
export default createConfig({ | ||
// ... | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,37 @@ | ||
# Foundry Example | ||
|
||
This example repo mimics a monorepo with ponder and a foundry dapp. It's intended to be used as a template for new ponder projects that want to integrate both. | ||
This is an example monorepo Ponder and Foundry dapp. It's intended to be used as a template for new ponder projects that want to integrate both. | ||
|
||
## Guide | ||
|
||
Follow the [Ponder docs](https://ponder.sh) to learn more on how to use Ponder with Foundry. | ||
|
||
Ensure you have Ponder installed as well as `foundry`. You will also need to install the example packages with: | ||
|
||
```shell | ||
pnpm install && cd ponder && pnpm install | ||
``` | ||
|
||
And then install the foundry packages in the `/contracts`: | ||
|
||
```shell | ||
# In the `/contracts` directory | ||
forge install | ||
``` | ||
For more information, read the Foundry [integration guide](https://ponder.sh/docs/advanced/foundry). | ||
|
||
## Usage | ||
|
||
There are some handy scripts in `package.json` to help you get started with this example. Open two terminal windows and run the following commands in each which starts an anvil server and ponder service respectively: | ||
|
||
```shell | ||
pnpm run start:anvil | ||
``` | ||
Start an Anvil local node: | ||
|
||
```shell | ||
pnpm run dev:ponder | ||
anvil --block-time 1 | ||
``` | ||
|
||
Next, you'll want to open a third terminal window and deploy the contracts: | ||
Compile contracts: | ||
|
||
```shell | ||
pnpm run deploy | ||
forge build | ||
``` | ||
|
||
After the contracts are deployed, you can run the following command to generate a single event: | ||
Run a Foundry script to deploy contracts and generate some logs: | ||
|
||
```shell | ||
pnpm run generate:event | ||
forge script script/Deploy.s.sol --broadcast --fork-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 | ||
``` | ||
|
||
## Developing | ||
|
||
If you'd like to develop the contracts further, make changes as required in `contracts/` and run the following command to recompile the contracts: | ||
Generate ABIs: | ||
|
||
```shell | ||
pnpmn run generate:abi | ||
pnpm wagmi generate | ||
``` | ||
|
||
This uses `wagmi-cli` to generate the ABI typescript files. Before deploying, you'll need to restart anvil and redeploy the contracts. After that, you can reload the ponder service using a dev only route: | ||
Start the Ponder development server: | ||
|
||
```shell | ||
curl -X POST http://localhost:42069/admin/reload?chainId=31337 | ||
``` | ||
|
||
This assumes you're using the default port and chainId. Replace the port and chainId if you're using different values. | ||
pnpm ponder dev | ||
``` |
Oops, something went wrong.