Building Bags.fm Embeds: A Free Tool to Make Crypto Community Support Visible
Building Bags.fm Embeds: A Free Tool to Make Crypto Community Support Visible
TL;DR: Token addresses are forgettable. Community support shouldn’t be. I built Bags.fm Embeds — a free tool that turns wallet addresses into real-time badges showing lifetime earnings. It took a weekend, taught me a lot about Go concurrency, and might actually help grow an entire ecosystem.
The Problem Nobody Talks About
If you’ve ever shared a Solana token address, you know the drill:
9XzKDJ9wP9yqi9G5okp9UFNxFuhqyk5GNyUnnBaRBAGS
That’s it. That’s the tweet. A 44-character string that tells you absolutely nothing.
No story. No context. No indication that this token has generated thousands of dollars in fees for creators. No signal that hundreds of community members are actively supporting this project.
The address is static, but the community is alive.
I kept seeing this disconnect in the Bags.fm ecosystem — a platform where token trading generates fee revenue that flows back to creators. Projects were sharing contract addresses, but the impact of community support was invisible.
What if you could see it?
The “Aha” Moment
I was browsing GitHub one day and noticed those little badges everyone uses:
They’re everywhere because they work. They take boring metadata (version numbers, build status) and make it visual and shareable.
What if Bags.fm had something like this? A badge that shows:
- Total lifetime fees earned
- Who’s receiving those fees
- Real-time updates as the community grows
Not a screenshot. Not a manual update. A live, embeddable badge that grows with the community.
What I Built
Bags.fm Embed Generator — five different embed types for different use cases:
1. Stats Card Widget
The full experience. Token name, logo, lifetime fees in USD and SOL, all fee recipients with their profiles, plus live market data (price, volume, market cap).
Perfect for websites and landing pages.

2. Fee Badge (Recipient)
Shows a creator’s total earnings from a token. “I’ve earned $2,221 from this project.”

3. Fee Badge (Project)
Shows total fees generated by a token. “This project has generated $5,000 for its creators.”

4. Mini Badge (Recipient)
Compact version for GitHub READMEs, Twitter bios, or anywhere space is tight.

5. Mini Badge (Project)
Compact token badge for project pages.

The key insight: SVG badges work everywhere — GitHub, Notion, Twitter cards, Discord, personal websites. No JavaScript required. Just an image URL.
Check out live examples to see them in action.
See It In Action
The Technical Journey
I’ll be honest: this could have been a simple weekend project. Fetch data, render HTML, done.
But I wanted it to be fast and reliable. And that led me down some interesting rabbit holes.
Why Go Instead of Node/Python?
My first instinct was Next.js on Vercel. I’ve built a dozen projects that way. But the requirements didn’t fit:
| Aspect | Next.js + Vercel | Go + Railway |
|---|---|---|
| Cold starts | Yes (serverless) | No (always running) |
| Memory usage | ~100MB | ~5-10MB |
| Response time | Good | Excellent |
| Concurrency | Good | Excellent (goroutines) |
| Monthly cost | $20+ | $5-20 |
For a service that needs to serve SVG badges in under 50ms with thousands of concurrent requests, Go was the obvious choice. A single binary, minimal memory footprint, and goroutines for concurrency.
The Background Worker Pattern
Here’s where it got interesting. The badges need to show USD values, which means I need the current SOL price. But I can’t fetch it on every request — that would be slow and hit rate limits.
Solution: a background goroutine that fetches the SOL price every 15 seconds and writes it to Redis.
┌─────────────────────────────────────────────────┐
│ Main Goroutine (HTTP Server) │
│ - Serves requests instantly │
│ - Reads from Redis (non-blocking) │
│ - Never waits for external APIs │
└─────────────────────────────────────────────────┘
│
│ Reads from
▼
┌─────────────────────────────────────────────────┐
│ Redis (Shared State) │
│ - SOL price (updated every 15s) │
│ - Token metadata (10min TTL) │
│ - Fee data (2min TTL) │
└─────────────────────────────────────────────────┘
▲
│ Writes to
┌─────────────────────────────────────────────────┐
│ Background Worker Goroutine │
│ - Runs every 15 seconds │
│ - Fetches from Jupiter → Binance → CoinGecko │
│ - Never blocks HTTP requests │
└─────────────────────────────────────────────────┘
The beauty: if Jupiter’s API goes down, HTTP requests keep serving cached data. The background worker will try Binance, then CoinGecko. Users never notice.
The Caching Strategy
Five layers of caching:
- Browser cache (60s) — Repeat visitors don’t hit the server
- Cloudflare CDN (60s) — Global edge caching
- Redis — Different TTLs for different data:
- SOL price: 15s
- Token metadata: 10min
- Fee data: 2min
- Market data: 1min
- Fallback cache — Last known values when APIs fail
- Hardcoded fallback — Reasonable defaults when everything is down
The result? 99% of requests are served from cache in under 50ms.
SVG Generation in Go
Generating SVGs server-side was surprisingly fun. No templating library, just string building with proper escaping:
func generateBadge(data TokenData, theme string) string {
bgColor := "#1a1a1a"
textColor := "#ffffff"
if theme == "light" {
bgColor = "#ffffff"
textColor = "#1a1a1a"
}
return fmt.Sprintf(`<svg xmlns="http://www.w3.org/2000/svg" width="320" height="52">
<rect fill="%s" rx="8" width="320" height="52"/>
<text fill="%s" x="16" y="32" font-size="14">
Lifetime Fees: $%s
</text>
</svg>`, bgColor, textColor, formatCurrency(data.FeesUSD))
}
The output is a valid SVG that works as an <img> tag anywhere on the web.
The Community Flywheel
Here’s what I find most exciting about this project: it creates a growth flywheel.
Projects share embeds
→ Visibility for Bags.fm
→ New users discover the platform
→ More trades, more fees
→ Recipients earn more
→ More projects join
→ More embeds shared
Every badge is passive marketing. Every embed is a data point showing that Bags.fm actually delivers value to creators. The more successful a token becomes, the more impressive its badge, the more likely it is to attract new community members.
The best part: I built the tool, but the community creates the growth.
Lessons Learned
1. Solve the Visibility Problem
The biggest issue wasn’t technical — it was that impact was invisible. Community members were contributing, but there was no tangible proof. Badges make the intangible tangible.
2. Meet People Where They Are
SVG badges work in GitHub READMEs, Twitter, Notion, Discord, and websites. I didn’t build five different integrations; I built one format that works everywhere.
3. Design for Failure
External APIs will go down. The Jupiter price API rate-limited me during development. DexScreener had a brief outage. Because I planned for failure (fallback sources, cached data, graceful degradation), users never noticed.
4. Concurrency Simplifies Architecture
The background worker pattern eliminated an entire class of problems. No race conditions on price fetches. No request timeouts waiting for external APIs. Clean separation of concerns.
5. Free Tools Win
I could have built this as a SaaS with pricing tiers. But the goal isn’t revenue — it’s ecosystem growth. Free tools get adopted. And if Bags.fm grows, everyone benefits.
Try It Yourself
Live Demo: bags.sivaramp.com
Examples: bags.sivaramp.com/examples
How it works:
- Paste your token address (must end in BAGS)
- Pick your embed type
- Copy the code
- Paste it anywhere
What’s Next
I’m considering a few enhancements based on early feedback:
- Custom colors — Let projects match their brand
- Animated badges — Show price changes in real-time
- Embed analytics — Track impressions and clicks
- Multi-token portfolios — Show total earnings across multiple tokens
But honestly? The MVP is working. Projects are starting to use it. The flywheel is starting to turn.
Sometimes the best next step is to get out of the way and let the community take over.
Final Thoughts
Building developer tools for crypto is an interesting space. The ecosystem is young, the tooling is sparse, and there’s real opportunity to make an impact.
This project took about two weekends. The hardest part wasn’t the code — it was identifying the right problem to solve. Once I realized that visibility was the gap, everything else fell into place.
If you’re building in this space, my advice: look for the invisible things. The data that exists but isn’t surfaced. The impact that’s real but not measurable. Make it visible.
That’s where the leverage is.
If you found this useful, consider sharing it with someone building in the Solana ecosystem. And if you try out the embed generator, I’d love to see how you use it!
Tech Stack:
- Backend: Go 1.21+ with Gin
- Frontend: React + Vite + TypeScript
- Cache: Redis
- CDN: Cloudflare
- Hosting: Railway
- Data: Bags SDK, DexScreener, Jupiter, Binance, CoinGecko