<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BoRn SliPPy</title>
    <description>The latest articles on DEV Community by BoRn SliPPy (@brn_slp).</description>
    <link>https://dev.to/brn_slp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3961663%2F531c0a52-7b44-4500-b4a8-c866a50ed76c.jpg</url>
      <title>DEV Community: BoRn SliPPy</title>
      <link>https://dev.to/brn_slp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brn_slp"/>
    <language>en</language>
    <item>
      <title>My Landing Page Claimed $10,725 in Tips. The Real Number Was $11.66.</title>
      <dc:creator>BoRn SliPPy</dc:creator>
      <pubDate>Wed, 10 Jun 2026 06:21:53 +0000</pubDate>
      <link>https://dev.to/brn_slp/my-landing-page-claimed-10725-in-tips-the-real-number-was-1166-1g7k</link>
      <guid>https://dev.to/brn_slp/my-landing-page-claimed-10725-in-tips-the-real-number-was-1166-1g7k</guid>
      <description>&lt;p&gt;Three weeks after I shipped my weekend tipping protocol, I gave it a proper audit. The smart contract holding actual money: fine. The key derivation: fine. The landing page: proudly displaying &lt;strong&gt;$10,725 in tips, 12,381 transactions, "760+ supporters."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The real numbers, sitting on a public blockchain the entire time, where anyone including me could have checked them: &lt;strong&gt;$11.66. 3,733 tips.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nobody hacked me. There is no exploit writeup. During a late-night "design pass" I had typed aspirational numbers into the hero section as placeholders, shipped them, and then spent weeks looking at my own landing page thinking, huh, decent traction. I built a payment system where every cent is cryptographically verifiable, and then lied about the total by three orders of magnitude, to myself, by accident.&lt;/p&gt;

&lt;p&gt;The audit found 53 issues. The contract was not one of them. The most dangerous bug in my dApp was marketing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46faam7ehm5rnlg1lor2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46faam7ehm5rnlg1lor2.png" alt="What the landing page claimed vs what the chain says" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Exhibit A. The left card ran in production for weeks. The right card was one RPC call away the whole time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let me rewind and tell you what this thing actually is, because the product is genuinely good, which is somehow the most embarrassing part.&lt;/p&gt;
&lt;h2&gt;
  
  
  A parking meter for paragraphs
&lt;/h2&gt;

&lt;p&gt;Most tip jars live at the bottom of the post. You read 2,000 words, scroll past two newsletter popups, and arrive at a "buy me a coffee" button having completely forgotten which sentence earned the coffee. Mine did too.&lt;/p&gt;

&lt;p&gt;So I moved the tip jar. Every paragraph gets its own little heart. Tap it, and a fraction of a cent in stablecoin goes from your wallet to the author's. Tip the paragraph, not the post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr08vflp1dze3mps577h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr08vflp1dze3mps577h.png" alt="The reader view: a sticky tip bar and a heart under every paragraph" width="800" height="320"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The live reader view. Presets from $0.001 to $0.05, a heart per paragraph, and yes, the fee disclosed right in the bar. The hearts on this fresh article read zero, which after the audit is the most trustworthy thing on the page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A tip is between $0.001 and $0.05. Yes, a tenth of a cent is a valid tip. This is where most chains check their watch and leave, because moving one cent costs fifty cents in gas, which is not a payment, that is a donation to a validator with a rounding error attached. It currently runs on an L2 where gas is sub-cent and payable in the stablecoin itself, so the math survives. More on chains later, including the part where I expand to several and regret the sentence I just wrote.&lt;/p&gt;
&lt;h2&gt;
  
  
  Who this is for, besides my own dashboard
&lt;/h2&gt;

&lt;p&gt;Two people, and neither is served by the donate button at the bottom.&lt;/p&gt;

&lt;p&gt;The first is the writer who publishes a genuinely good idea and gets twelve likes for it. Likes do not pay rent. A $5-a-month membership is a big ask from someone who liked one paragraph of one post, so readers who would have paid a little end up paying nothing, because "a little" was never on the menu.&lt;/p&gt;

&lt;p&gt;The second is the reader who would happily pay that little. Often a reader on a phone in a market where card subscriptions barely work but a stablecoin wallet is already in their pocket. They do not want a relationship with your content. They want to drop a cent on the line that made them stop scrolling and get on with their day.&lt;/p&gt;

&lt;p&gt;The button at the bottom asks the wrong question at the wrong time: a verdict on the whole post, at the end, once the feeling has faded. A heart under the paragraph asks a smaller question at the exact moment the sentence lands. Smaller questions get answered. 3,733 times so far, by 762 wallets, for a grand total of $11.66. I told you the numbers were honest now.&lt;/p&gt;
&lt;h2&gt;
  
  
  The one clever line
&lt;/h2&gt;

&lt;p&gt;On-chain, a &lt;code&gt;TipJar&lt;/code&gt; contract (UUPS proxy, verified, holding real if modest money) tracks balances per author. The line I am unreasonably proud of is how a paragraph gets an identity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bytes32 paragraphKey = keccak256(
    abi.encodePacked(articleId, uint32(index), keccak256(bytes(text)))
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The text is baked into the key. Fix a typo in paragraph 3 and it becomes a new paragraph with a clean slate, while tips already sitting on paragraphs 1, 2 and 4 do not move. Tips attach to what was said, not to a line number that slides the moment you add a sentence. This took twenty minutes. The landing page that lied about $10,000 took considerably longer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfbghntusno3rbhgfulp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfbghntusno3rbhgfulp.png" alt="How a paragraph gets an identity: articleId + index + keccak of the text" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Edit paragraph 3 and only paragraph 3 starts over. The neighbors keep their earnings, like colleagues pretending not to watch a reorg.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The bug museum
&lt;/h2&gt;

&lt;p&gt;The audit deserves its own section, because I think build-in-public posts that only show the wins are a genre of fiction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exhibit A: the imaginary $10,713.&lt;/strong&gt; Covered above. The fix wired the hero stats to the same on-chain scan that feeds the leaderboard, and if the RPC hiccups, the section now hides instead of inventing. Numbers that cannot be fetched are now displayed as nothing, which it turns out is the correct amount of lying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exhibit B: "lifetime earnings," for very short lifetimes.&lt;/strong&gt; The writer dashboard had a "lifetime claimed" counter. A writer with $11.59 claimed showed $0.40. The scan behind it only looked back ~500,000 blocks, which on a chain with one-second blocks is less than a week. I had labeled a six-day window "lifetime," like a mayfly's biographer. It now scans from the deploy block, like the word lifetime implies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exhibit C: the social platform that rejected my chain.&lt;/strong&gt; I packaged the app as a social Mini App. The manifest validator rejected it for two reasons: my splash image was 512 pixels instead of exactly 200, and I had honestly declared which chain the app needs, a chain that works perfectly inside the client but is not on the validator's list of chains that exist. The fix for the second problem was to delete the honesty. The field was optional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exhibit D: the optimistic paycheck.&lt;/strong&gt; I shipped a 2.5% protocol fee (we will get to it, put the pitchfork down). The contract dutifully paid writers 97.5% of every tip. The dashboard, meanwhile, kept showing writers the gross amount, the one number a writer actually checks, inflated by exactly my own cut. So for a while the product simultaneously took a fee and displayed a world in which it did not. Schroedinger's commission. Fixed by labeling everything gross or net like an adult.&lt;/p&gt;

&lt;p&gt;Eighteen pull requests later the audit list was empty. The product looked exactly the same. That is the joke about audits: their best outcome is that nobody can tell you did anything.&lt;/p&gt;
&lt;h2&gt;
  
  
  The analytics accident
&lt;/h2&gt;

&lt;p&gt;Here is what I did not see coming when I sketched this.&lt;/p&gt;

&lt;p&gt;A like is free, which makes it cheap, which makes it noise. A tip costs something, even a tenth of a cent, which makes it signal. When money attaches to a specific paragraph, you get a map a like button cannot draw: not "this post did well," but "this exact line, third paragraph of the fourth section, is the one that landed."&lt;/p&gt;

&lt;p&gt;I have shipped paragraphs I was certain were the point and watched a throwaway line three down quietly out-earn all of them. Paid attention is just a better metric than attention. The money is nice. The map of which sentences were worth actual money is the part I did not know I was building.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyw7somhn7ndyz6f221n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyw7somhn7ndyz6f221n.png" alt="Paragraphs ranked by what readers actually paid" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A dramatization with made-up numbers, which, given this article's history, I am now contractually obligated to disclose.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  I became the platform I warned you about
&lt;/h2&gt;

&lt;p&gt;The first version of this post bragged that the protocol takes 0% and every cent goes to the writer. I then sat down with a calculator and the concept of "servers" and shipped a 2.5% protocol fee. The author keeps 97.5% of every tip, the fee accrues to a treasury, and the cap is hard-coded at 10% so future me cannot get creative without an upgrade everyone can see coming on-chain.&lt;/p&gt;

&lt;p&gt;Why admit this in public? Because the alternative is the classic arc where the fee appears silently in a terms-of-service update, and I would rather be the person who tells you to your face that the parking meter now keeps a coin out of every forty. It funds development now and, if volume ever justifies it, a prize pool for writers beyond their own tips. If 2.5% is the number where you feel taxed, the comment box is right there, and unlike my hero section, it accepts honest input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fal57ob7tcuamma1usrta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fal57ob7tcuamma1usrta.png" alt="One cent tip split: 97.5% to the writer, 2.5% to the protocol" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The whole business model, to scale. The rose sliver is the empire.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The contract has more versions than my resume
&lt;/h2&gt;

&lt;p&gt;The TipJar is a UUPS proxy and has now survived three upgrades on mainnet without moving a single balance: V1 shipped the core, V2 added the fee, V3 added something I find funnier than it should be, a &lt;code&gt;support()&lt;/code&gt; function. Anyone can sign a transaction that moves zero money and permanently records "I back this project" on-chain, optionally with a message. A guestbook with gas costs.&lt;/p&gt;

&lt;p&gt;We then built a beautiful landing section for it, shipped it, looked at it for a day, and moved the whole thing behind a small link in the footer, because a project whose landing page once lied about $10,000 should probably not lead with a "wall of believers." Growth is also knowing where to hide your own features.&lt;/p&gt;
&lt;h2&gt;
  
  
  Two lines to put it on your blog
&lt;/h2&gt;

&lt;p&gt;The tipping layer is an npm package, because none of this is useful trapped on my domain.&lt;/p&gt;

&lt;p&gt;React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TipParagraphs&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tipitip/embed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TipParagraphs&lt;/span&gt; &lt;span class="na"&gt;articleId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0x7ff6..."&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Allergic to React? Framework-free web component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://esm.sh/@tipitip/embed/vanilla"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;tipitip-paragraphs&lt;/span&gt; &lt;span class="na"&gt;article-id=&lt;/span&gt;&lt;span class="s"&gt;"0x7ff6..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/tipitip-paragraphs&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop either into a blog or a docs page and your paragraphs grow hearts. It ships with npm provenance, a signed attestation linking the tarball to the exact commit and CI run, because I wanted at least one part of this project to look like an adult made it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every place a paragraph can grow a heart
&lt;/h2&gt;

&lt;p&gt;Since "so where does this actually run" is the first question everyone asks, the full inventory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The platform itself.&lt;/strong&gt; Paste markdown, hit publish, share the link. One on-chain transaction registers the article to your wallet, so tips route to you and not to whoever hosts the page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your blog.&lt;/strong&gt; The React embed above. Two lines, your paragraphs become tippable on your own domain, the money still goes straight to your address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Any site that has ever heard of HTML.&lt;/strong&gt; The web component needs no framework, no build step, no opinion. It has been dropped into WordPress without asking PHP for permission.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The social feed.&lt;/strong&gt; Cast an article link on Farcaster and it unfurls into a card with a Read &amp;amp; Tip button. The full Mini App opens inside the feed, so a reader can read, tap a heart, and pay an author without ever technically leaving their doomscroll. I consider this my contribution to ethical attention capture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A phone in a market where cards do not work.&lt;/strong&gt; Inside the MiniPay wallet the app auto-connects and gas is paid in the same stablecoin as the tip, so the entire onboarding is "open link, tap heart." No seed-phrase liturgy, no "first acquire our token."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The writer's side.&lt;/strong&gt; A dashboard that ranks your paragraphs by what readers actually paid for, shows pending earnings, and claims them in one transaction. Plus a public profile per wallet and a leaderboard, so good writing gets discovered by the only metric that cannot be botted for free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The guestbook in the footer.&lt;/strong&gt; The on-chain &lt;code&gt;support()&lt;/code&gt; endorsement from earlier. It is there. It is humble. It knows what the landing page did.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same contract, same hearts, same sub-cent math everywhere. The surface changes, the paragraph still gets paid.&lt;/p&gt;

&lt;h2&gt;
  
  
  The multichain confession
&lt;/h2&gt;

&lt;p&gt;The current deployment lives on one L2. The next ones, if the plan survives contact with reality, are Base, Optimism, and probably a couple more Superchain networks, because that is where the readers and the writers actually are.&lt;/p&gt;

&lt;p&gt;Here is the honest catch I keep circling: today the whole reader experience is "tap heart, cent moves," partly because the current chain lets you pay gas in the same stablecoin you are tipping with. The moment I deploy to a chain where gas wants a different token, I have to explain to a reader who came to spend one cent why they first need to acquire a second asset, which deletes the magic. The grown-up answer is a paymaster and account abstraction, ERC-4337 sponsorship so the reader never learns what gas is. That is the plan for the Superchain expansion. It is also more work than this paragraph makes it sound, which is why I am writing the paragraph first.&lt;/p&gt;

&lt;p&gt;If you run a blog or a community on Base or OP and would actually use per-paragraph tipping there, say so in the comments. Deployment order will be decided by people who show up, not by my gut, which as established once believed its own fake numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest scoreboard, as of the audit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;$11.66 tipped, 3,733 tips, 762 tipping wallets, 6 articles&lt;/li&gt;
&lt;li&gt;29 contract tests, 3 mainnet upgrades, 0 balances lost&lt;/li&gt;
&lt;li&gt;~150 pull requests, 53 audit findings, 18 PRs to clear them&lt;/li&gt;
&lt;li&gt;1 landing page, no longer creative with numbers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your turn
&lt;/h2&gt;

&lt;p&gt;Three questions, and they decide real things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the largest tip that still feels like nothing to you? The presets are $0.001 to $0.05 and the default is a guess.&lt;/li&gt;
&lt;li&gt;Is 2.5% a fair protocol cut, and at what number would you start feeling taxed?&lt;/li&gt;
&lt;li&gt;Base, OP, or which Superchain network first, and do you actually have readers there, or does it just sound nice?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Poke it directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live: &lt;a href="https://tipitip-sable.vercel.app" rel="noopener noreferrer"&gt;https://tipitip-sable.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SDK: &lt;code&gt;npm i @tipitip/embed&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/BRN-SLP/tipitip" rel="noopener noreferrer"&gt;https://github.com/BRN-SLP/tipitip&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put it on your own blog and send me the link. I will tip your best paragraph. The amount will be honest. We have a whole audit about it.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>solidity</category>
      <category>typescript</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
