Why I Built a Separate NFT Template for MyZubster (and How It Integrates)
The Problem: Monero Doesn't Have Native NFTs
Monero is the gold standard for private, fungible cryptocurrency. Its blockchain is designed to be untraceable and confidential – which is exactly what makes it great for payments, but also what makes it incompatible with traditional NFTs.
When I started building MyZubster, I wanted to add NFT functionality to the platform. But I faced a fundamental challenge: Monero doesn't support NFTs natively.
Enter Tari – Monero's official sidechain designed specifically for digital assets like NFTs, tickets, and loyalty points.
The Solution: Tari, Monero's Official Sidechain
Tari is a merge-mined sidechain to Monero, built by ex-Monero maintainers. It offers:
- Privacy by default (MimbleWimble protocol)
- Smart contract support (via templates in Rust)
- Security inherited from Monero's mining network
- Scalability with a two-token model (XTM for mining, XTR for dApps)
This made Tari the obvious choice for MyZubster's NFT functionality.
The Decision: Why a Separate Template?
I could have embedded the NFT logic directly into MyZubster's backend. Instead, I chose to build a separate, standalone NFT template called tari-nft-template. Here's why:
1. Reusability Across Projects
The template is not tied to MyZubster. Any developer or project can use it to create NFT collections on Tari, without having to adopt the entire MyZubster ecosystem.
bash
docker pull myzubster/tari-nft-template:latest
2. Easier Testing and Maintenance
A focused codebase is easier to test, debug, and maintain. The template is written in Rust with tari_template_lib, and follows a clean, minimal API:
rust
pub fn new(name: String, symbol: String) -> Component<Self> {
let nft_resource = ResourceBuilder::non_fungible()
.metadata("name", name.clone())
.metadata("symbol", symbol.clone())
.metadata("description", "A Tari NFT Collection")
.build();
// ...
}
pub fn mint(&mut self, id: NonFungibleId, immutable_data: String, mutable_data: String) -> Bucket {
let manager = self.nft_vault.get_resource_manager();
// ...
}
3. Open Source for the Community
By keeping the template public and open-source (BSD-3-Clause), I'm contributing back to the Tari and Monero ecosystem. Other developers can:
Fork it for their own projects
Contribute improvements and bug fixes
Learn from the implementation
4. Separation of Concerns
MyZubster is a complex ecosystem with:
A skills marketplace
A payment gateway
An Android app
An admin panel
A React dashboard
Adding NFT logic directly into the monolith would have made the codebase harder to manage. By keeping the NFT logic separate, I can:
Update the NFT template independently
Roll back changes without affecting the rest of MyZubster
Reuse the same template in future projects
5. Dockerized for Easy Deployment
The template is containerized and published on Docker Hub:
yaml
services:
backend:
image: myzubster/tari-nft-template:latest
ports:
- "8080:8080"
This makes it plug-and-play for any developer.
How It Integrates with MyZubster
The integration is designed to be seamless, following a microservices-inspired approach:
Architecture Overview
text
[React Frontend] → [Gateway API] → [Rust NFT Template (Docker)]
↓
[Marketplace API]
↓
[SQLite Database]
1. The Template Exposes a REST API
The Rust backend (tari-nft-template) runs as a standalone service, exposing HTTP endpoints:
rust
// src/api.rs
async fn get_orders(State(state): State<AppState>) -> Json<serde_json::Value> {
// Fetch orders from SQLite
Json(json!({ "orders": orders }))
}
2. The Gateway Routes NFT Requests
MyZubster's Node.js gateway (gateway/) acts as a reverse proxy:
javascript
app.use('/api/nft', require('./routes/nft'));
3. The Frontend Calls the Gateway
The React dashboard (myzubster-frontend/) calls the gateway's /api/nft endpoints:
typescript
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000';
const response = await fetch(`${API_URL}/api/nft/mint`, {
method: 'POST',
body: JSON.stringify({ id, immutableData, mutableData }),
});
4. The Mobile App (Android) Uses the Same APIs
The Kotlin app (myzubster/) also calls the gateway, ensuring consistency across platforms:
kotlin
// Android (Kotlin)
val response = client.get("http://localhost:4000/api/nft/collections")
Benefits for the Community
By separating the NFT template, I've created a public good that benefits the entire Tari ecosystem:
1. A Ready-to-Use NFT Template
Developers can launch their own NFT collections on Tari in minutes:
bash
git clone https://github.com/DanielIoni-creator/tari-nft-template.git
cd tari-nft-template
cargo build
docker build -t my-nft .
docker run -p 8080:8080 my-nft
2. A Reference Implementation
The template serves as a learning resource for developers new to Tari and Rust smart contracts.
3. A Testbed for Innovation
The template is a sandbox where developers can experiment with new NFT features (royalties, whitelist, limited editions) without affecting their main projects.
4. Cross-Project Compatibility
Because the template is decoupled, it can be integrated into any project – not just MyZubster.
Repository Structure
The MyZubster ecosystem is organized as follows:
Repository Purpose Visibility
MyZubster Main ecosystem (private) 🔒 Private
tari-nft-template NFT template for Tari 🌍 Public
myzubster-assets Images and resources 🌍 Public
myzubster Android app (Kotlin) 🌍 Public (fork)
Future Development
Feature Status Timeline
NFT Royalties 📝 Planned Q3 2026
Whitelist Minting 📝 Planned Q3 2026
Batch Minting 🔬 Research Q4 2026
IPFS Metadata 🔬 Research Q4 2026
Conclusion
Building a separate NFT template for MyZubster wasn't just a technical decision – it was a strategic one. It allowed me to:
Keep the codebase maintainable
Contribute back to the Tari community
Enable reusability across projects
Create a public good that outlasts MyZubster itself
If you're building on Tari or Monero, I hope this template serves as a useful starting point. And if you're curious about the integration, feel free to explore the code, open an issue, or reach out.
📬 Connect with Me
📖 Dev.to: https://dev.to/danielioni
🐦 Twitter: https://x.com/myzubster
💼 LinkedIn: https://linkedin.com/in/daniel-ioni-62b2b9423/
🐙 GitHub: https://github.com/DanielIoni-creator
Built with ❤️ for the Monero and Tari community.
Top comments (0)