⚠️ Alpha · testnets only. ChainRender is in active alpha and deployed on testnets only — Ethereum Sepolia, the Robinhood Chain Testnet, and the Circle Arc Testnet — not on any mainnet. Contracts, addresses, and APIs may change. Do not use with real funds or production assets.
Concepts

Intent DeFi & CoW Protocol

Most DeFi is transactional: you sign a specific swap at a specific block. Intent-based DeFi is different — you express what you want ("sell 10 WETH for USDC over the next day, never below this limit") and a network of solvers competes to fill it. CoW Protocol is the canonical intent layer: its ComposableCoW framework lets a single signed order describe a programmatic or conditional order — a TWAP, a stop-loss, a good-till-cancelled limit — that becomes tradeable only when its on-chain conditions hold.

Intent orders are exactly the kind of thing users sign without being able to read. ChainRender's job here is the one it always has: render the on-chain truth of the intent, and verify what the user is about to sign — trustlessly, as a free view — and never pretend to be the solver, the settlement layer, or CoW's order book. Three resolvers cover the lifecycle, each ownerless, immutable, view-only, and fail-closed.

The mental model: render + verify the intent, never become the auction

CoW settlement happens in an off-chain batch auction: solvers find coincidences of wants, and the winning settlement is submitted to CoW's settlement contract. That auction is not something any eth_call can see, and ChainRender does not fake it. What is on-chain and readable:

  1. The order definition — a TWAP/conditional order's parameters (schedule, limits) are deterministic data. Rendering the schedule is pure arithmetic over that data + block.timestamp.
  2. Tradeability this block — ComposableCoW itself exposes a view that returns the discrete order a conditional order would emit right now (or reverts if none is valid yet). That is a trustless read of "is this live?".
  3. App-data integrity — a CoW order commits to a keccak256 of its full app-data document (metadata + pre/post hooks). Recomputing that hash on-chain proves the human-readable document you are shown is the exact one the order bound.

What is not a floor fact, and is never rendered as one: whether a batch will actually settle, at what price, and when — that depends on solver competition in the off-chain auction. A "ready/settled" badge would be a labelled client enhancement over CoW's Order Book API, not part of this on-chain floor.

cowOrder — live tradeability (the real ComposableCoW)

CowConditionalOrderResolver STATICCALLs the real ComposableCoW — getTradeableOrderWithSignature(owner, (handler, salt, staticInput), offchainInput, proof) — and renders the discrete GPv2Order the conditional order would emit this block. When no order is valid yet (the normal "not yet executable" state), the call reverts and the resolver fails closed to "not active" — never a fabricated order.

kind renders
cowOrder a field of the tradeable GPv2Order this block — sell amount, buy amount, validTo, or partially-fillable — or "not active"

Args are caller-supplied: abi.encode(composableCow, owner, receiver, salt, staticInput, offchainInput, proof[], sellDecimals, buyDecimals, field). Because the result is a view recomputable by anyone against the real ComposableCoW, an honest tradeability read grades A (Trustless). The resolver renders what ComposableCoW returns — it does not assert the order is registered, nor that a batch will settle it; it answers exactly one question: would this order be tradeable right now?

ComposableCoW is deployed deterministically at the same address on every supported chain: 0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74. The resolver takes it as an argument — ChainRender hardcodes nothing.

cowTwap — the schedule (pure, trustless arithmetic)

CowTwapResolver decodes a TWAP order definition (TWAP.Data: part sell amount, minimum part limit, start t0, number of parts n, interval t, and span) and projects it against block.timestamp to render the human schedule: which part is active, the countdown to the next slice, the per-part sell size, and the per-part limit.

kind renders
cowTwap part X / N, next-slice countdown, per-part sell amount, per-part minimum limit, or a status label

Args: abi.encode(twapData, sellDecimals, buyDecimals, field). This is pure arithmetic over the definition plus the block clock — nothing but block.timestamp is read, so it is fully recomputable via eth_call and grades A. The honest caveat is stated on every card: cowTwap renders the schedule the definition encodes; it is not proof the order was registered with ComposableCoW. Pair it with cowOrder (which does read the real ComposableCoW) for the full picture — the schedule story next to live tradeability.

cowIntent — "verify what you sign" (on-chain integrity + a client decoder)

This is the user-protection piece. A CoW order commits to order.appData == keccak256(fullAppData) (per CoW's app-data SDK). CowIntentVerifyResolver recomputes that hash on chain and compares it to the hash the order bound:

kind renders
cowIntent (field 0) "verified" if keccak256(fullAppData) == expected, else "app-data mismatch"
cowIntent (field 1) the computed keccak256 of the presented document, as hex

Args: abi.encode(fullAppData, expected, field). Flip one byte of the document and "verified" becomes "app-data mismatch". Crucially, the verdict is an integrity statement, never a safety one — it proves the document you are shown is byte-identical to the one the order committed to; it never says "safe to sign." Grade A, fail closed.

The ⚙ client decoder (cr-cow-intent.js)

A CoW app-data document carries the atomic plan — pre/post CoW Hooks, each {target, callData, gasLimit} — that will run around the swap. On-chain JSON parsing is impractical, so decoding the plan into plain English is a client enhancement (Grade ⚙), not a floor read. cr-cow-intent.js does exactly that, under strict rules that keep it honest:

  • It only runs after the on-chain cowIntent slot returned "verified". If the hash did not match, it refuses to decode — the document is not the one the order committed to.
  • It decodes known selectors (approve, transfer, transferFrom, permit, withdraw, stake, …) into a readable step; any unknown selector is marked OPAQUE and surfaced, never guessed.
  • It fails closed and never emits "safe to sign." The worst case is an honest "this step could not be decoded — verify it manually."

This is the msg-712 / sig-1271 split in miniature: the trustless floor proves integrity (the bytes are the committed bytes), and a clearly-labelled client layer adds legibility (what those bytes do) over the already-verified document. The enhancement can only ever make a verified document more readable — it can never upgrade an unverified one.

Putting it together — the trustless order monitor

The Explorer ships two CoW example cards built entirely from these reads:

  • Trustless CoW order monitor — cowTwap renders the schedule (live via block.timestamp) beside cowOrder, which STATICCALLs the real ComposableCoW for live tradeability, failing closed to "not active". The schedule story next to the live-tradeability truth, with zero client trust.
  • Verify what you sign — cowIntent shows a matching document rendering "verified" and a tampered hash rendering "app-data mismatch" side by side; the hook plan is decoded client-side (cr-cow-intent.js) only after the on-chain verdict.

Both are free eth_call renders — no server, no CoW API key, no indexer.

The honest boundaries (read these)

  • Settlement is off-chain and is not rendered as a floor fact. CoW fills orders in an off-chain batch auction; whether/when/at-what-price a batch settles depends on solver competition. ChainRender renders tradeability and the schedule (both on-chain), not a settlement guarantee. A "settled/ready" badge would be a labelled client layer over CoW's Order Book API.
  • cowTwap renders the definition, not proof of registration. It is the schedule the parameters encode; use cowOrder against the real ComposableCoW to confirm the order is actually live.
  • cowIntent proves integrity, not safety. A "verified" document is the one the order bound — it is not a judgment that signing is wise. The decoder reinforces this: unknown calls are OPAQUE, and it never says "safe."
  • ChainRender blesses no order or handler. Every ComposableCoW address, owner, handler, and app-data document is a caller argument; nothing is hardcoded or endorsed.

What this is not

ChainRender is not a CoW solver, does not run or replace CoW's off-chain batch auction or Order Book API, does not custody funds, and does not settle trades. It renders the on-chain truth of an intent order and verifies the document behind it — the trustless half — and is deliberately silent on the off-chain auction it cannot see.

Deployed (Sepolia)

CoW intent-DeFi resolvers are deployed on Ethereum Sepolia (where ComposableCoW lives); they are portable to any chain where ComposableCoW is deployed, since the ComposableCoW address is a caller argument. Verify against deployment/additive/addresses.json before integrating.

Resolver Kind(s) Sepolia address Grade
CowConditionalOrderResolver cowOrder 0x752AcEd4a7D7bD9Bd604c3d7adD38373Eed3b6c1 A
CowTwapResolver cowTwap 0xF949E6fB52Df34Dcc86F674E51327567cD964395 A
CowIntentVerifyResolver cowIntent 0xCaa6E85510f6FDDA54Be92AaEb95e6779bdc1AB2 A
ComposableCoW (CoW Protocol, external) — 0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74 —

Where to go next