Why I built it
Existing NFT marketplaces force a tradeoff: on-chain orderbooks bleed gas, off-chain ones lose composability. This project lands in the middle — orders live in Postgres, signatures get verified on-chain at fill time.
Architecture
- Contracts — minimal
Exchange.solverifies EIP-712 typed-data signatures and pulls assets viatransferFrom. - Indexer — Foundry test harness + a viem-based ingest worker subscribed to
OrderFilledevents. - Frontend — Next.js App Router, wagmi connectors, optimistic UI for listing/canceling.
- Royalty enforcement — reads ERC-2981 on the asset contract, falls back to a registry.
function fillOrder(Order calldata o, bytes calldata sig) external {
bytes32 digest = _hashOrder(o);
require(SignatureChecker.isValidSignatureNow(o.maker, digest, sig), "BAD_SIG");
// ...
}Lessons
The hardest bug was a signature replay across chains — fixed by including block.chainid in the EIP-712 domain. Type-safe ABIs from viem catch most issues at the seam between contract and app.