> ## Documentation Index
> Fetch the complete documentation index at: https://docs.windrose.market/llms.txt
> Use this file to discover all available pages before exploring further.

# Local development

> Run the whole stack against a local anvil, regenerate ABIs, and run the contract test suite.

The repository is a pnpm workspace (`apps/*`, `packages/*`) plus a Foundry project in `contracts/`. Everything runs locally against an anvil that mimics Arc testnet, with no faucet needed.

## Layout

| Path                | Contents                                                                                                                  |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `contracts/`        | Foundry: `CurrencyRegistry`, `FxVault`, `BondingCurve`, `LaunchFactory`, `Router`, oracle adapters, tests, deploy scripts |
| `packages/abis/`    | ABIs, the chain registry (`chains.json`), deployment JSONs and token lists consumed by everything off-chain               |
| `packages/keeper/`  | FX keeper bot that posts rates to `KeeperFxOracle`                                                                        |
| `packages/indexer/` | Ponder indexer and GraphQL API                                                                                            |
| `apps/web/`         | Next.js app                                                                                                               |
| `apps/docs/`        | This documentation (Mintlify)                                                                                             |
| `scripts/`          | `local-demo.sh`, `deploy-testnet.sh`, `deploy-mainnet.sh`, `seed-testnet.sh`, `verify.sh`, `vps-setup.sh`, `chain-env.sh` |
| `deploy/`           | pm2 process file, certbot helper, rsync excludes                                                                          |
| `docs/`             | Design notes: `ARCHITECTURE.md`, `INTEGRATION.md`, `RESEARCH.md`, `HOSTING.md`                                            |

## Quick start

Requires node 22, pnpm 9 and Foundry (`forge`, `cast`, `anvil`) on `PATH`.

```bash theme={"system"}
pnpm install
bash scripts/local-demo.sh              # anvil on :8545 with chain id 5042002, everything deployed and seeded
pnpm --filter @launchpad/indexer dev    # GraphQL on :42069 (PONDER_RPC_URL_5042002=http://127.0.0.1:8545)
pnpm --filter @launchpad/web dev        # NEXT_PUBLIC_RPC_URL=http://127.0.0.1:8545
```

What `scripts/local-demo.sh` does:

1. Starts anvil with chain id 5042002 (2 s block time) if nothing answers on `:8545`, writing the PID to `.anvil.pid` and the log to `.anvil.log`. `CHAIN_ID` overrides the mimicked id; it must be in the registry so the apps pick it up.
2. Uses `contracts/.env`'s `PRIVATE_KEY` if present, else anvil's first default account (`0xf39F…2266`, key `0xac09…f2ff80`), and sets its native balance to 10,000.
3. Deploys mock USDC and EURC with `LocalTokens.s.sol` (funding the deployer and anvil's default accounts with 10 M of each) and passes them to `Deploy.s.sol` as `USDC` and `EURC`, with `PYTH=0x0` so no Pyth oracle is deployed.
4. Runs `Seed.s.sol`: posts approximate rates through the keeper oracle, backs a few vaults and creates sample launches (`SEED_RATES`, `SEED_UNDERWRITE_USDC`, `SEED_UNDERWRITE_COUNT`, `SEED_LAUNCHES`, `SEED_INITIAL_BUY_USDC` tune it).
5. Copies `contracts/deployments/5042002.json` to `packages/abis/deployments/5042002.json`, where the indexer and the web app read it.

Because the chain id is Arc testnet's, the registry entry, gas parameters and file names of the real chain apply: point the indexer and the web app at `http://127.0.0.1:8545` with `PONDER_RPC_URL_5042002` and `NEXT_PUBLIC_RPC_URL` (or `NEXT_PUBLIC_RPC_URL_5042002`). Multicall3 is absent on a plain anvil; the web app probes for it and falls back to single reads, or set `NEXT_PUBLIC_MULTICALL3=none`. The indexer's `START_BLOCK` can stay at 0 locally.

<Tip>
  anvil's automine occasionally stops picking up pending transactions on Windows; the demo script forces a block every 0.5 s while it deploys and sends with `--slow`. If the factory ends up without code, restart anvil and rerun.
</Tip>

## Contract tests

```bash theme={"system"}
pnpm contracts:test          # cd contracts && forge test
```

The suite (54 tests at the time of writing, across `BondingCurve`, `FxVault`, `Oracles`, `Router` and `Invariants`) includes fuzz runs (256 by default, 2000 under `FOUNDRY_PROFILE=ci`) and invariant suites for curve solvency, token conservation and vault redemptions never exceeding assets. Unit tests use mock ERC-20s because a standard anvil lacks Arc's precompiles.

Compiler settings live in `contracts/foundry.toml`: solc 0.8.26, `evm_version = "cancun"`, the legacy pipeline for the protocol and tests, and via-IR compilation profiles (`v4core`, `posm`, `descriptor`) for the Uniswap v4 contracts, which only fit under the size limit that way.

## Regenerating ABIs

The off-chain packages consume the ABIs from `packages/abis/src/*.json`, exported from `contracts/out`:

```bash theme={"system"}
pnpm contracts:build                        # forge build
pnpm abis                                   # forge inspect <Name> abi for every protocol contract into packages/abis/src/
pnpm --filter @launchpad/indexer codegen    # abis/index.ts (as const) and ponder-env.d.ts; postinstall does this too
pnpm --filter @launchpad/web gen            # src/lib/abis.generated.ts and src/lib/chains.generated.ts; dev and build do this too
```

`@launchpad/abis` also exports `CHAINS`, `getChain(id)`, `findChain(id)`, `parseChainId`, `deploymentPath(id)` and the `Deployment` type, so no other package parses `chains.json` itself. See [ABIs and registry](/protocol/integrate/abis-and-registry).

## Checks per package

| Package            | Commands                                                                                                                                                                |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `contracts`        | `forge build`, `forge test`, `forge fmt`                                                                                                                                |
| `apps/web`         | `pnpm --filter @launchpad/web lint` (eslint), `pnpm --filter @launchpad/web typecheck` (gen-abis, `next typegen`, `tsc --noEmit`), `pnpm --filter @launchpad/web build` |
| `packages/indexer` | `pnpm --filter @launchpad/indexer typecheck`                                                                                                                            |
| `packages/keeper`  | `pnpm --filter @launchpad/keeper test` (vitest), `pnpm --filter @launchpad/keeper typecheck`                                                                            |
| `apps/docs`        | `mint dev` for a local preview, `mint validate` and `mint broken-links` before pushing                                                                                  |

## Root scripts

| Script                                        | Runs                                                           |
| --------------------------------------------- | -------------------------------------------------------------- |
| `pnpm contracts:build`, `pnpm contracts:test` | `forge build`, `forge test`                                    |
| `pnpm abis`                                   | the ABI export                                                 |
| `pnpm abis:logos`, `pnpm abis:tokenlist`      | coin logos and the token list for `CHAIN_ID` (default 5042002) |
| `pnpm keeper`, `pnpm indexer`, `pnpm web`     | `keeper start`, `ponder dev`, `next dev`                       |
