Hartii developer docs

Gallery

Hartii Gallery

Hartii Gallery is the production NFT marketplace/creator platform at hartiigallery.com — collection creation, five separate marketplace venues (fixed-price, bundles, auctions, gasless orders, ERC-1155), and a public read API backing the frontend.

The collection wall consumes saved index previews instead of starting a separate tokenURI read for every tile. Artwork comes first in the default sort; explicit floor, listing and mint-price sorts remain available. Phone and laptop artwork grids keep the same four-column count and image widths, with responsive thumbnails and natural image heights. Names and item counts overlay the image on hover or keyboard focus; the first phone tap reveals details and a second opens the collection. Storage badges and the caption area beneath previews are removed.

An original floral-silk oil painting inspired by Somali dirac textiles fills the open page space. Its extended vertical composition opens into new folds and flowers as you scroll at a gentle, fixed rate; appending collections cannot rewind it. Translucent gallery and collection surfaces let the painting show through while keeping artwork and controls clear. Optional accelerated flow is capped at 24 frames per second and a viewport-sized two-million-pixel canvas; a matching CSS painting remains beneath it if acceleration is unavailable. The footer pause control freezes the current passage and is stored locally; system reduced-motion settings keep a still opening scene. Hidden tabs stop drawing, and decorative layers never receive pointer input.

The interface uses warm chiaroscuro, reflective controls and gilded frames inspired by classic painting. Those lighting treatments sit on the surrounding surfaces; the artwork itself is not tinted, blurred or recolored.

The owner-curated $ober room presents Hartii Biome's backed lead artist and selected IPFS works. Artist attribution is bound to canonical collection addresses, with a creator check when the index provides one; matching a collection name is insufficient. The work viewer supports keyboard and touch navigation and respects reduced motion. No price, ownership or availability is inferred from the editorial selection.

The existing discovery, media-resolution and sales jobs remain the data pipeline. Quai's IPFS gateway participates in media retrieval alongside existing fallbacks. A scheduler heartbeat proves a job reported success at a timestamp; it does not certify every individual image is reachable.

Since Gallery 2.26.0 the NFT indexer also has a media lane for idle cron minutes: between full runs it fetches the images that are due, a few per minute (at most 6 items and 45 external fetches per run). A failed item can no longer block the queue behind it, retries are spread fairly, and a gateway rate limit (429) counts as transient, not as a failure. The lane obeys the free-tier D1 budget: it skips a run once the day's reads or writes pass 85% of the indexer's own soft line, and past 70% of either daily cap the indexer writes only a heartbeat until 00:00 UTC. These limits exist so background work stays inside the account's shared free-tier D1 allowance. With about 22,000 images waiting, the expected pace is roughly 2,200 a day; that figure is the release estimate, not a measured guarantee.

The Hartii mark

The mark is a faceted camel whose hump is a cut watch case. The case has twelve bezel facets, one for each hour. It is drawn in black and the crimson scale only. The favicons and app icons are rendered from the same code-drawn geometry.

The dial keeps Quai time. The hand moves one tick for every Quai block: 6 degrees a block, 60 ticks a turn. The hand angle is (block mod 60) × 6 degrees. While the tab is visible, the mark reads the latest block number about every 11 seconds through the site's cached RPC endpoint and advances by the number of blocks since its last read. It never moves backward. A failed read keeps the last real block; it never invents one. Hover the navigation mark to read the block number.

The mark is live in the navigation bar, the footer, the welcome window and the coda at the end of the home page. Everywhere else it is static, and the hand rests nine ticks past the hour (54 degrees). When the system asks for reduced motion, the hand still moves to the new block but without the animated tick.

The exhibition walk

The home page is a walk through rooms. Scrolling takes you from one to the next.

  • Hero. Real collection artwork hangs in frames at three depths, directly on the silk with no panel behind it. Moving the pointer, or dragging sideways on a touch screen, looks around. Scrolling drives the parallax. Hover, keyboard focus or a first tap brings one frame forward and dims the rest. Enter, a click or a second tap opens the collection. Escape, moving away or tapping outside puts the frame back. Arrow keys move between frames. The hero uses real artwork only.
  • Room I, In residence. The $ober room with a light sweep as it enters, then the heads: a slow, endless procession of real tokens from $OBER PIXEL$ and $OBER FINGER$. Only those two canonical collections supply heads, under the same contract-address and creator checks as the artist room. The two collections alternate. A head whose image fails to load is skipped, never replaced by a stand-in. Pixels stay sharp. Hovering a head slows the procession to a stop and lifts the head with its name and token number. Enter or a second tap opens its item page.
  • Room II, Live on Quai. Real mints, sales, transfers and burns from the NFT index, newest first. The room shows the latest eight. Each row names the collection and token, shows sender and recipient (and the price in QUAI for a sale) and links to its transaction on the explorer. It refreshes every 15 seconds while the room is on screen and the tab is visible. The line above the list reads "Live" and the block it is as of.
  • Room III, Spotlights. Featured collections from the index with items, owners, floor, 24 h volume and all-time volume. Unknown values are a dash. Floor is a dash for now, because the index has no floor source. The spotlight changes about every 8 seconds with a crossfade. It pauses while off screen, while hovered or focused, and whenever motion is off; numbered controls step through the spotlights.
  • The wall. The four-column collection wall described above, unchanged. Tiles rise into place as they enter the view.
  • Room IV, The numbers. NFTs on Quai, collections, owners, sales in the last 24 hours, 24 h volume, 24 h mints, 24 h transfers, all transfers, and the top collectors. The room is dated "As of block N". A number counts up once when the room first appears.
  • Coda, "Mining is the movement". A short text about block time beside the live mark, which grows as you scroll to it.

While the index has nothing to show yet (it is warming up, cannot be reached, has seen no activity, or is still reading Quai's NFT history), the rooms hang real art from the collection index instead (since Gallery 2.9.2):

  • Room II lists pieces On the wall: real tokens from the collections on the wall, one collection before any repeats, with a new piece every 5 seconds while motion is on. Each row links to the piece's item page and carries one figure of its collection: the listing floor, the mint price, the minted count or the item count. A row has no transaction, block, sender or recipient, because it is not an event. While history is being read and the index already has transfers, Room II shows those instead, labelled "Reading history" with the percentage read.
  • Room III rotates collections from the wall with the figures they carry: floor, listed, minted, mint price, royalty and creator.
  • Room IV counts the collection index: collections, pieces minted, creators, listed for sale, earned by creators, lowest floor, made on Hartii and discovered on Quai, then hangs eight pieces On the wall.

The index's activity, spotlights and totals take the space back on their own as soon as it has them. Nothing is half-counted. If the collection index has no art either, a room says what is missing and offers Check again; it shows no guess.

One switch turns all motion off: the system reduced-motion setting, or Pause background in the footer. It governs the hero, the scroll rooms, the heads, the spotlight rotation, the count-ups, the tile rise and the silk. With motion off, the heads become a still row you can scroll sideways. The footer choice is stored in your browser.

Market rail

The market rail lists recent Hartii marketplace buys and sells, and nothing else. Each row shows the collection and token, the price in QUAI, seller to buyer, how long ago it sold and the block, and links to the transaction on the explorer. It reads the sales feed of the NFT index (/api/nft/activity?kind=sale, the latest 20 sales) and refreshes every 30 seconds while the tab is visible.

  • 1100 px and wider. A slim rail on the right, titled "Market · buys & sells", with a button to collapse it. Below 1360 px it starts collapsed. Your choice is remembered in your browser and wins over that default.
  • Narrower than 1100 px (phones and tablets). A ticker pill above the bottom edge shows the latest sale. Tapping it opens a bottom sheet with the list. Drag the sheet down, press Escape or press Close to dismiss it. Focus stays inside the sheet while it is open.
  • Pieces while there is no sale to list (since 2.9.2). If the sales feed has no sale yet, or is warming up or unreachable, the rail, the pill and the sheet show pieces On the wall from the collection index, a new one every 5 seconds, each linking to its item page with its collection's floor or mint price. Real sales replace them as soon as there are any.
  • Honest states. "No sales recorded yet" when the index is current and has seen none and there is no art to hang. While history is still being read the empty state reads "No sales recorded so far" with the percentage read, and a list is labelled "Sales recorded so far". If the feed is warming up, unreachable, unreadable or not switched on, the rail says which and shows no guess. An unknown price is a dash. A failed refresh keeps the last list, and the desktop rail says so.

Architecture

  • Frontend: Vite + React, deployed as static assets to Cloudflare Pages.
  • Chain library: quais — this repo does not use ethers.
  • Contracts: Hardhat project in contracts/; deployed to Quai mainnet (Cyprus-1, chain 9).
  • Edge/API: Cloudflare Pages Functions under functions/api/** — see api.
  • Data stores: Cloudflare KV (hot cache, floor prices, sales index) and D1 (durable collection index, sales history) behind the API — the browser never talks to KV/D1 directly.
  • NFT index: a dedicated indexer reads every ERC-721 and ERC-1155 transfer on Cyprus-1 into its own D1 database; /api/nft/* is the public read API over it — see NFT index API.

There is also a testnet mirror, Orchard (hartiigallery.com/orchard, chain 15000), built from the same app and used for rehearsal before mainnet contract changes. It shares the same image/metadata proxy endpoints as production but has its own contract addresses and its own KV/D1 — it is not documented further here since it carries no real value.

Live URLs

Apphartiigallery.com
Public API basehttps://hartiigallery.com/api/
Orchard testnet mirrorhttps://hartiigallery.com/orchard (chain 15000 — rehearsal only)

Data flow

  1. Collection creation. A creator calls deployCollection(...) on the current factory (HartiiFactoryV7Clone), which deploys an EIP-1167 minimal-proxy clone of HartiiCollectionV7Clone, initialized atomically in the same transaction.
  2. Discovery. A scheduled worker scans the chain for CollectionDeployed events and known marketplace activity and writes a durable index into D1 (functions/api/collections.js reads from that index, merging in live on-chain floor-price/listing reads rather than trusting a stale cache for money-relevant fields).
  3. Browsing. GET /api/collections returns the whole catalogue in one response — factory collections plus externally-listed ones — for the Explore page. GET /api/floor-prices recomputes floors from live marketplace state.
  4. Trading. The frontend calls the marketplace contracts directly from the connected wallet (list, buy, offer, bundle, auction, gasless order fulfillment) — the API never custodies a trade; it only indexes what already happened on-chain (/api/sales) for fast history browsing.
  5. Media. NFT images/metadata live on IPFS. /api/img and /api/meta are caching proxies that hedge across several public IPFS gateways and cache the result at Cloudflare's edge (content-addressed, so the cache is effectively permanent). Since 2.13.0 the media job also keeps the Gallery's own copy of every displayed cover and sample image, so covers load even when public gateways refuse Cloudflare. It also covers Hartii-made collections and on-chain SVG art.
  6. NFT index. Separately from the collection catalogue, the NFT index follows the chain tip and reads Quai's earlier NFT history in the background. It also records Hartii marketplace sales itself, from block 7,640,402. The home page's Live, Spotlights and Numbers rooms and the market rail read /api/nft/*. Name-service contracts are never indexed.

Live contracts (Quai mainnet, Cyprus-1)

All addresses below were read from src/utils/appConfig.js NETWORK_CONFIGS.mainnet and independently confirmed live with quai_getCode against https://rpc.quai.network/cyprus1 (each returned non-empty deployed bytecode).

ContractAddressRole
HartiiFactoryV7Clone (current factory)0x007d00B9752d852658A03167b825d62b68c375FcDeploys new collections as EIP-1167 clones
HartiiFactory (legacy factory)0x00265a93d7Bf94147d88e27EA28A2AC9dAd9eF04Older full-bytecode factory; existing collections still resolve their provenance to it
HartiiMarketplaceV8 (current marketplace)0x006792f8913d99e2D9E72087D4C3CBAf2e77E867Fixed-price listings + offers — write target for all new activity
Legacy marketplace (v7)0x003fEB578c595563e8790Ef0240B248e4D2C1Ae5Old listings/offers stay readable, buyable and cancellable here — no new listings
HartiiBundleMarketplace0x0028E7a353cA07Ad754E8b1F144305e2E17b2eDAMulti-NFT bundle listings, one flat price
HartiiAuctionHouse0x0068d66A3FC1E65e89D00D801cADB095e6e4019cEnglish auctions with anti-snipe extension
HartiiGaslessMarketplace0x005f633a448B10e0aF8E170394F92A83955a410fEIP-712 signed orders, fulfilled by the buyer's tx
HartiiMarketplace11550x00137c1eD65B084319ee1420a243aa1dD35BfA04Quantity-aware ERC-1155 trading venue
HartiiCurationRegistry0x000404Cd0833465bCe3E345454B901b69B5ff51CEditorial allow-list for a specific launch surface (see contracts)
Launchpad demo collection0x004Ff0147ca6AB274E171D2A47d0aD34762bE154Seed collection so Explore isn't empty before real factory deploys land

Every collection a creator deploys through either factory is its own HartiiCollectionV7Clone (or legacy HartiiCollection/HartiiCollectionV2) instance — there is no single "the collection contract" address; see contracts for the template's interface.

See contracts for the full interface and trust model of each contract above, and api / integrate for the HTTP surface and code examples.

Quai Network mainnet · chain 9 · Cyprus-1. Figures marked "read on" a date were read from the chain that day; re-read before relying on them.