Skip to main content
This companion contract (OnChainBrewsRenderer) is responsible for composing SVG art on-chain and serving standard ERC‑721 metadata via tokenURI. Below is a section‑by‑section walkthrough of how images are generated, layered, and hosted entirely from contract storage.

Linking to the Core Contract

The renderer is linked to the main (core) contract via IOnChainBrews core and queries the core contract for:
  • tokenIdToAuction(tokenId) → which auction produced a token
  • getAuctionSeed(auctionId) → deterministic per‑auction seed for traits

Data Model

The metadata (description and traits) for On-Chain brews are stored in the core contract, which queries the renderer for the SVG image of each brew.
/// each trait contains a name, an svg snippet, and a weight
struct Trait { 
	string name;   /// human‑readable trait name (e.g., "amber", "frosted mug")
	string svg;    /// an SVG fragment (layer) stored directly on-chain 
	uint16 weight; /// relative rarity used in weighted random selection
}

/// traits are assigned to 1 of 4 categories
/// this defines both attributes order and  
/// layering order when composing the final SVG
string[4] public categories = ["Background", "Brew", "Mug", "Top"];

/// a registry of traits per category
mapping(string => Trait[]) public traitCategories;

Admin: Authoring & Maintaining the Art

Because the owner can add/update/remove traits, the art set is mutable until ownership is renounced. This is a conscious choice to allow live curation.
The SVG layers are managed by upsert and remove functions on the renderer contract. This is to allow for continued updates until the renderer contract is renounced. This allows the contract owner to:
  • Publish new traits over time (e.g., seasonal backgrounds).
  • Tweak rarity weight without changing deployed code.
  • Patch/iterate on SVG fragments (fix a pixel, adjust a color) by overwriting svg for that name.
    /// adds a new trait or updates an existing one by name within a category 
    function upsertTrait(
    	string memory category,
    	string memory name,
    	string memory svg,
    	uint16 weight
    ) external onlyOwner {};
    
    /// deletes a trait via swap‑and‑pop pattern
    /// reverts if the named trait is not found
    function removeTrait(
    	string memory category, 
    	string memory name
    ) external onlyOwner {};