# Foundry \[Use Ponder with Foundry]

Ponder works with Anvil, the local development chain included with Foundry.

Foundry projects follow various development workflows (test-driven, deploy to a fresh chain, deploy to a fork, etc). This guide offers patterns that you can adapt to your specific requirements.

## Configure the `anvil` chain

### Disable caching

Ponder's RPC request cache works well for live chains 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 chain. With this option set to true, Ponder will clear the cache on start up and between hot reloads.

```ts [ponder.config.ts]
import { createConfig } from "ponder";

export default createConfig({
  chains: {
    anvil: {
      id: 31337,
      rpc: "http://127.0.0.1:8545",
      disableCache: true,  // [!code hl]
    },
  },
  // ...
});
```

### 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 chains.

### 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 chain.

:::warning
Known issue: When indexing Anvil with auto mining enabled in an app with
multiple chains, indexing progress will get "stuck" at the timestamp of the
latest Anvil block.
:::

## 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/get-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 [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.

:::info
Remember to enable
[broadcast](https://book.getfoundry.sh/guides/scripting-with-solidity#deploying-to-a-local-anvil-instance)
so that `forge script` submits transactions to Anvil.
:::

### 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 [ponder.config.ts]
import { createConfig } from "ponder";
import { http, getAddress, hexToNumber } from "viem";
import { counterABI } from "../abis/CounterAbi";
import CounterDeploy from "../foundry/broadcast/Deploy.s.sol/31337/run-latest.json"; // [!code focus]

const address = getAddress(CounterDeploy.transactions[0]!.contractAddress); // [!code focus]
const startBlock = hexToNumber(CounterDeploy.receipts[0]!.blockNumber); // [!code focus]

export default createConfig({
  chains: {
    anvil: {
      id: 31337,
      rpc: "http://127.0.0.1:8545",
      disableCache: true,
    },
  },
  contracts: {
    Counter: {
      chain: "anvil",
      abi: counterABI,
      address, // [!code focus]
      startBlock, // [!code focus]
    },
  },
});
```

### 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 [ponder.config.ts]
import { createConfig } from "ponder";
import CounterDeploy from "../foundry/broadcast/Deploy.s.sol/31337/run-latest.json"; // [!code focus]
 // [!code focus] // ^ The development server detects changes to this file and triggers a hot reload.

export default createConfig({
  // ...
});
```
