Retrospective: Mosaics

This week I released Mosaics, a fully on-chain canvas editor that allows users to publish artwork with unique backgrounds, stickers, borders, and text. Users can also create custom backgrounds and stickers in a pixel art editor and list them as assets for other people to use, receiving portions of all mints that use that asset.

I didn’t have any specific goals for this project. These days my priority is practicing the muscle of taking a project from idea to reality, learning and growing from that process, and listening to what reality tells me in return. I mostly wanted to make something that leveraged programmable money and the creative capacities of on-chain SVG in a novel way, and I feel happy about the outcome on that front. The project is probably entering a maintenance mode now, will run/exist on-chain forever as long as Base exists, and I’ll implement new features if I think of any that feel worthwhile.

Anyway, here are some scattered learnings and reflections:

  1. This was the first project I’ve done that turned out meaningfully different from the idea I had for it going in. Initially, the project was called String Theory and it was essentially “NFTs for unique strings”. You would type in a string and if it hadn’t been claimed you could mint a 1/1 onchain SVG ERC-1155 of that string, and it could be collected as an infinite edition forever where you get paid on any future collects.

    But then I started looking at the NFTs and they looked so bland with just text on a background, so I thought it would be fun if maybe the user could edit the background color or font of the string to add some variety and personality. It kept looking boring until I thought about adding stickers and some more detailed background types, and then after that I realized it’s not even really about the string anymore it’s more about the artwork, so then I said fuck it just let people put multiple text boxes. At this point we now had a legitimate onchain canvas which to me felt more expressive and generative than just claiming a unique string (which has also been done before indirectly by e.g. ENS).

    Ironically, the original String Theory concept may have “done better” in the traditional sense. The assets would feel more like rare collectibles, the scarcity might induce people to be more active about claiming the NFTs or even willing to pay money for them, etc. But I don’t know if I would have been as proud of that iteration of the project; I’m happy that I can comfortably say I’m proud of Mosaics.

    The main learning here upon reflection is that I would not have arrived at the Mosaics idea had I not gotten started taking action on the String Theory idea. This is what people mean when they say “action produces information”.

  2. This was also the first project where I shared it on X. I used to post on X a lot, basically as often as I post on Farcaster. Over the last year I stopped posting as much and lost the muscle for it and I’ve felt very self-conscious of sharing my projects on X. I made 5 other projects over the last month that I only shared on Farcaster. Sharing on Farcaster feels more like an easy mode cop out, since I already post very liberally. I wish I could say the same for X but it’s not the case.

    Anyways, I’m glad I shared it because it ended up flopping and did not drive a single new creation. After this I realized I did not really have anything to be self-conscious about in the first place.

    The subconscious fear of people dunking on your thing or judging your thing or not liking it for whatever reason is extremely unfounded. X can be unreasonably toxic at times but it’s a far more likely scenario that people just don’t care about it to begin with, and this is in most cases a worse outcome than the one you feared.

  3. Any “consumer crypto” product only works if users can make money from it, either by earning or by speculating. My hypothesis was that creating a Mosaic is a form of both: the trade is paying to launch a paid edition and the speculation is that n>1 people will mint it, thus yielding your creation to be profitable.

    I’m not sure if people are convinced that the latter will work out for them. Paying to collect a low-supply open edition NFT is entirely an act of patronage, and especially in a crypto bear market everyone knows they’re not going to make money from minting. I don’t believe patronage-based onchain products work in a bear market because people don’t feel rich enough to be patrons. NFTs as an object format also have less energy around them, but I don’t subscribe to the idea that the format is “dead”. Many reasonable use cases still exist.

  4. I probably paywalled too much stuff (e.g, charging the user to list stickers/backgrounds, charging them to launch any paid mint). I had two main goals here: one was just to try a new financial mechanism for the sake of it, and the second was spam reduction since it was a UGC product. I wouldn’t change anything about my intention with the former, mechanism experimentation for the sake of it is a good thing. But realistically for spam mitigation, the better practice is to have things be free and frictionless to create and only try to charge on economically valuable transactions (e.g. take cuts of paid mints). Anything that’s spam, you should just figure out how to filter client-side instead of trying to mitigate it onchain. Even if the fees are tiny, the mental friction will probably limit people from wanting to participate, who otherwise might have done so.

    It’s also worth noting that in 2026, people are used to having things like gas and such be abstracted for them from onchain products.

  5. I didn’t go that hard on marketing this. I didn’t DM anyone to try it out, I posted a few times on Farcaster and once on X. Part of me is just not used to trying to market something, and the other part of me was not as high conviction on this to begin with to want to go hard on marketing it. So tbh I’m not sure if I would even change that, but it is worth building the muscle of shamelessly shilling your thing constantly. Half-assing anything does not yield desirable outcomes. Something to think about further.

  6. I went down a rabbithole where I discovered neocities in the process of figuring out what I wanted the UI to look like. It made me realize a lot of design is also about having diverse references and inputs to inform your creative process. Sending references and screenshots to the model for figuring out UI is also a huge boost to its output quality vs. trying to just describe your desired vibe with English. Claude models are the best for this.

  7. There were some issues with the UI being weird on different devices, something I need to figure out how to test/account for better.

  8. When you publish a project that touches user funds it’s important to take it seriously. For simple and straightforward contracts I don’t really think you need to get formal audits, but you do need to have your own clear plan and intention for maximally approaching security to the best of your ability. For me that meant a few things:

    1. Every update to the protocol had adversarial review from 5.5 and 4.8 (ideally Fable but I always ran into safeguard issues when trying to do security review), using specific security skills from Pashov and Trail of Bits. As the models get better you can trust them more to be good at this, e.g. now we have 5.6.
    2. In this specific case, I made sure that we never stored money in the contract so there was no path to losing user funds. All payments are pushed to recipients at time of transaction. There are many contracts though that do need to store user funds (e.g. Mutual does this) so this can’t always apply.
    3. Define clear invariants for writing and running tests - e.g. no user should ever lose funds unexpectedly, nobody should be able to mint any NFT without funds going to the intended recipients, etc.
    4. Obviously do your own end-to-end testing on testnet, try to define all the scenarios and flows and test them as a user end-to-end, not just via programmatic testing.
    5. When you do catch bugs or errors in testing, update your process/system to understand how it happened. In theory there’s no reason for the same mistake to be made twice.
    6. Testing with mainnet fork, not just testnet, is also good.

    If you’ve read this far and have thoughts to add on security in building onchain applications with AI, please add in the comments. I have a lot more to learn here.

This has mostly been a stream of consciousness but thank you for reading if you made it this far. I will update it if there is more stuff I think of. You can try Mosaics here.

No comments yet.