diff --git a/.env.example b/.env.example index 2a8f937..42c459b 100644 --- a/.env.example +++ b/.env.example @@ -10,6 +10,7 @@ # is NOT production-ready — its rate limit stalls the indexer (see docs/deployment.md). MAINNET_RPC_URL=https://eth.api.pocket.network GNOSIS_RPC_URL=https://rpc.gnosischain.com # dev only — replace with a dedicated RPC in production +SEPOLIA_RPC_URL= ARBITRUM_RPC_URL= BASE_RPC_URL= BNB_RPC_URL= @@ -22,6 +23,7 @@ PLASMA_RPC_URL= # WS RPC URLs (optional; enables WS realtime subscriptions, more efficient than HTTP polling) # MAINNET_WS_RPC_URL=wss://... # GNOSIS_WS_RPC_URL=wss://... +# SEPOLIA_WS_RPC_URL=wss://... # ARBITRUM_WS_RPC_URL=wss://... # BASE_WS_RPC_URL=wss://... # BNB_WS_RPC_URL=wss://... diff --git a/docs/architecture.md b/docs/architecture.md index 1aa7744..bc6b94a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -22,7 +22,7 @@ Stub configs exist for all 12 chains in cow-sdk's `ALL_SUPPORTED_CHAIN_IDS`; con Three contracts are indexed: 1. **ComposableCow** -- the main contract. Emits `ConditionalOrderCreated` for new programmatic orders. -2. **CoWShedFactory** -- emits `COWShedBuilt` when a user deploys a CoWShed proxy wallet. On Gnosis there are two factory addresses (the current `CoWShedForComposableCoW` factory and a legacy `COWShed` factory), both indexed through a single Ponder contract entry using an address array. +2. **CoWShedFactory** -- emits `COWShedBuilt` when a user deploys a CoWShed proxy wallet. Each chain config can provide multiple factory addresses. A single Ponder contract entry indexes all addresses and preserves owner mappings across factory upgrades. 3. **GPv2Settlement** -- the CoW Protocol settlement contract. Filtered to only `Settlement` events where the solver is the FlashLoanRouter address, so the volume is very low. ## Data Flow diff --git a/docs/deployment.md b/docs/deployment.md index 4a6c358..01e5d7d 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -46,6 +46,7 @@ copy `.env.example` to `.env.local`. |----------|----------|-------------| | `MAINNET_RPC_URL` | Yes | Ethereum mainnet RPC endpoint | | `GNOSIS_RPC_URL` | Yes | Gnosis Chain RPC endpoint | +| `SEPOLIA_RPC_URL` | When active | Sepolia RPC endpoint | | `ARBITRUM_RPC_URL` | When active | Arbitrum One RPC endpoint | | `BASE_RPC_URL` | When active | Base RPC endpoint | | `BNB_RPC_URL` | When active | BNB Chain RPC endpoint | @@ -59,8 +60,8 @@ copy `.env.example` to `.env.local`. The indexer is RPC-heavy during initial sync. Rate-limited endpoints will work but sync takes considerably longer. Use an endpoint with generous throughput for production. The indexer currently processes Ethereum and Gnosis. Chain configuration and -RPC variables for Arbitrum, Base, BNB, Polygon, Avalanche, Linea, Ink, and -Plasma are ready for a later rollout. Sepolia is configured but not indexed. +RPC variables for Arbitrum, Base, BNB, Polygon, Avalanche, Linea, Ink, Plasma, +and Sepolia are ready for a later rollout. > **Adding a new chain:** when a chain is added to `ACTIVE_CHAINS` in `src/chains/index.ts`, its RPC URL env var (defined as `rpcEnvVar` in the chain config file) must be added here and to the infrastructure deployment. The RPC used must be a dedicated/paid one, since the public endpoint rate limits is insuficient for the app. The optional WS RPC URL env var (`wsRpcEnvVar`) may be added the same way to enable realtime WS subscriptions. diff --git a/src/chains/arbitrum.ts b/src/chains/arbitrum.ts index bb6d06d..34e5c85 100644 --- a/src/chains/arbitrum.ts +++ b/src/chains/arbitrum.ts @@ -16,8 +16,14 @@ export const arbitrum: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy + ] as const, startBlock: 358667546, // verified: tx 0x97b8fa7baf78bca1836e6a7cdce3bd0b983fa96352fc168ebf5f24ba63f23a91 }, gpv2Settlement: { diff --git a/src/chains/avalanche.ts b/src/chains/avalanche.ts index 20241ae..f9c0299 100644 --- a/src/chains/avalanche.ts +++ b/src/chains/avalanche.ts @@ -16,8 +16,14 @@ export const avalanche: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy + ] as const, startBlock: 65617025, // verified: tx 0xcf5f0c9a40d26d09e497a6ce871df31ca13d8e72b1724d8ba015368cf36068f1 }, gpv2Settlement: { diff --git a/src/chains/base.ts b/src/chains/base.ts index 3bb089c..4cf92a1 100644 --- a/src/chains/base.ts +++ b/src/chains/base.ts @@ -16,8 +16,14 @@ export const base: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy + ] as const, startBlock: 32986811, // verified: tx 0x29c63a32edbf7b29ae73e6a8e5293b65c65906943ad41092205a473e4bbf56d0 }, gpv2Settlement: { diff --git a/src/chains/bnb.ts b/src/chains/bnb.ts index fce9e25..3606b3f 100644 --- a/src/chains/bnb.ts +++ b/src/chains/bnb.ts @@ -16,8 +16,14 @@ export const bnb: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy + ] as const, startBlock: 61362362, // verified: tx 0x76d25671fd1c31044a6cf481df15649fc3503cf5a492de92be8601fee02e259f }, gpv2Settlement: { diff --git a/src/chains/gnosis.ts b/src/chains/gnosis.ts index 56aad48..0a4a5e7 100644 --- a/src/chains/gnosis.ts +++ b/src/chains/gnosis.ts @@ -16,12 +16,16 @@ export const gnosis: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { address: [ - "0x4f4350bf2c74aacd508d598a1ba94ef84378793d", // current (CoWShedForComposableCoW) + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // v2.1.0 factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // v2.1.0 factory for COWShed + "0x4f4350bf2c74aacd508d598a1ba94ef84378793d", // v2.0.0 (CoWShedForComposableCoW) "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy (COWShed); 2 historical events ] as const, - startBlock: 41469991, // earliest COWShedBuilt from either factory on Gnosis + startBlock: 41469991, // earliest COWShedBuilt from any configured factory on Gnosis }, gpv2Settlement: { address: "0x9008D19f58AAbD9eD0D60971565AA8510560ab41", diff --git a/src/chains/index.ts b/src/chains/index.ts index 178254a..3294162 100644 --- a/src/chains/index.ts +++ b/src/chains/index.ts @@ -53,6 +53,7 @@ export const ALL_DEFINED_CHAINS: ChainConfig[] = Object.values( * array. * * Inactive-but-defined chains (arbitrum, base, bnb, polygon, avalanche, linea, - * plasma) are fully verified — add one here once its RPC URL is provisioned. + * ink, plasma, sepolia) are fully verified — add one here once its RPC URL is + * provisioned. */ export const ACTIVE_CHAINS: ChainConfig[] = [mainnet, gnosis]; diff --git a/src/chains/ink.ts b/src/chains/ink.ts index 8ac6535..103053e 100644 --- a/src/chains/ink.ts +++ b/src/chains/ink.ts @@ -16,7 +16,15 @@ export const ink: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, - cowShedFactory: null, // TODO: confirm CoWShedFactory address on Ink + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json + cowShedFactory: { + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + ] as const, + startBlock: 51750825, // both current factories were deployed in this block + }, gpv2Settlement: null, // TODO: enable once flash-loan infra is confirmed on Ink flashLoan: null, // TODO: set { aaveV3: { router, adapterFactory } } once flash-loan infra is confirmed on Ink orderbookApiPath: "ink", // TODO: verify CoW Protocol orderbook URL for Ink diff --git a/src/chains/linea.ts b/src/chains/linea.ts index dfd5316..cc504d5 100644 --- a/src/chains/linea.ts +++ b/src/chains/linea.ts @@ -16,8 +16,14 @@ export const linea: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy + ] as const, startBlock: 25033271, // verified: tx 0xad527499a510773fed02f46787d8ed9190d52fe40997c661353805e2bc056a65 }, gpv2Settlement: { diff --git a/src/chains/mainnet.ts b/src/chains/mainnet.ts index 1c7e07a..b033927 100644 --- a/src/chains/mainnet.ts +++ b/src/chains/mainnet.ts @@ -16,9 +16,15 @@ export const mainnet: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", - startBlock: 22939254, + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // v2.1.0 factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // v2.1.0 factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy (COWShed) + ] as const, + startBlock: 22939254, // earliest COWShedBuilt from any configured factory on Mainnet }, gpv2Settlement: { address: "0x9008D19f58AAbD9eD0D60971565AA8510560ab41", diff --git a/src/chains/plasma.ts b/src/chains/plasma.ts index 96d87d4..0e97f46 100644 --- a/src/chains/plasma.ts +++ b/src/chains/plasma.ts @@ -16,8 +16,14 @@ export const plasma: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy + ] as const, startBlock: 4803028, // verified: tx 0x33d7ed32d433467d75373baf0bcbc99fec65df8a8fd6f67673efa8378f67ebcc }, gpv2Settlement: { diff --git a/src/chains/polygon.ts b/src/chains/polygon.ts index cd12428..24ec514 100644 --- a/src/chains/polygon.ts +++ b/src/chains/polygon.ts @@ -16,8 +16,14 @@ export const polygon: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy + ] as const, startBlock: 74072686, // verified: tx 0x9d877eaa06776c30a409fc31db365e8441f982598586345d53ffaee4f9d2da6d }, gpv2Settlement: { diff --git a/src/chains/sepolia.ts b/src/chains/sepolia.ts index ac79ab0..6aa4d2a 100644 --- a/src/chains/sepolia.ts +++ b/src/chains/sepolia.ts @@ -16,8 +16,14 @@ export const sepolia: ChainConfig = { composableCowLive: { address: "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", }, + // Official deployments: + // https://github.com/cowdao-grants/cow-shed/blob/main/networks.json cowShedFactory: { - address: "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // CREATE2 — same across chains + address: [ + "0x5e284e80f3bd6a7d80a8500d9c49878028110848", // v2.1.0 factory for COWShedForComposableCoW + "0xc94f7d71d022e773b0b516841ff867c06f39726b", // v2.1.0 factory for COWShed + "0x312f92fe5f1710408b20d52a374fa29e099cfa86", // legacy (COWShed) + ] as const, startBlock: 8784028, // verified: tx 0x4d42972f24fa0846523513e7733b1d2238d0a709c3e4a2cd415cc64885bd1762 }, gpv2Settlement: null, // TODO: enable once flash-loan infra is confirmed on Sepolia diff --git a/src/chains/types.ts b/src/chains/types.ts index 5511c01..5f61c2a 100644 --- a/src/chains/types.ts +++ b/src/chains/types.ts @@ -42,7 +42,7 @@ export interface ChainConfig { /** * CoWShedFactory deployment(s) on this chain. - * Gnosis has two factory addresses (current + legacy), so address may be an array. + * Address may be an array when a chain has multiple factory deployments. * Null when the factory address hasn't been confirmed for this chain yet. */ cowShedFactory: {