The Stellar-powered beat marketplace where producers get paid instantly.
Crate is a peer-to-peer marketplace for music producers to sell sample licenses on-chain. Upload a beat, set your price, and earn on every sale and resale — instantly, with no intermediary. Buyers get a tamper-proof on-chain license. Collaborators split royalties automatically at the contract layer.
Streaming platforms pay producers fractions of a cent per play, months after the fact. Beat marketplaces take cuts of 30–50% and hold payouts for 30–90 days. When a track gets sampled, the original producer rarely sees a royalty at all.
Soroban contracts change the economics. Revenue splits happen in the same transaction as the purchase — zero delay, zero platform cut beyond a transparent basis-points fee. Resale royalties are enforced by the contract, not by a platform's goodwill.
Producer uploads a beat → IPFS stores the audio → contract stores metadata + price
↓
Buyer selects a license tier (Basic / Premium / Exclusive)
↓
purchase_license: platform fee split, producer cut paid out, collaborator shares distributed
↓
On-chain license record created — buyer can prove ownership
↓
Buyer lists for resale → buy_resale: producer gets resale royalty, platform fee, seller gets remainder
↓
Producer calls withdraw_earnings → accumulated earnings transfer to wallet
Every payment is atomic. If a split fails, the entire purchase reverts. No partial pays, no accounting debt.
Single Rust/WASM contract deployed on Stellar Testnet. Handles the full marketplace lifecycle.
| Function | Description |
|---|---|
upload_sample |
Registers a beat: IPFS CID, title, genre, BPM, prices per tier, collaborator shares |
purchase_license |
Splits payment: platform fee + producer cut + collaborator shares in one tx |
get_sample |
Returns full SampleData for a sample ID |
get_earnings |
Accumulated unpaid balance for a producer address |
withdraw_earnings |
Transfers accumulated earnings to the producer's wallet |
get_license |
Returns the license tier held by a buyer for a given sample |
list_resale |
Owner lists a purchased license for resale at a chosen price |
buy_resale |
Secondary purchase: producer resale royalty + platform fee + seller remainder |
delist_sample |
Producer removes their upload from the marketplace |
get_collaborators |
Returns the collaborator list with share basis points for a sample |
get_stats |
Platform-wide: total samples, total volume, total resales |
bump_sample |
Extends ledger TTL for a sample's storage entry |
License tiers: Basic · Premium · Exclusive — each with independent pricing set by the producer at upload time.
Collaborator splits: up to a configurable maximum collaborators per sample, shares expressed in basis points. The contract validates that shares sum correctly and distributes them atomically on every purchase.
Resale royalties: producers specify a resale royalty percentage at upload. Every secondary sale enforces it at the contract layer — no off-chain trust required.
| Repo | Stack | Description |
|---|---|---|
| crate-contracts | Rust · Soroban SDK | crate_marketplace contract — licensing, royalty splits, resale, collaborator revenue distribution |
| crate-backend | TypeScript · Express · PostgreSQL · Redis | REST API, IPFS proxy, Soroban event indexer, WebSocket broadcast, analytics, Redis caching, moderation, reconciliation |
| crate-frontend | React 18 · TypeScript · Tailwind · Freighter | Marketplace with search/filter/pagination, producer earnings dashboard, multi-wallet support, cross-chain payment via CCTP, upload flow |
| crate-mobile | React Native · Expo | Mobile app for producers — discover feed, earnings screen, upload, beat preview |
┌─────────────────────────────────────────────────────────────────┐
│ crate-frontend │
│ React 18 + Tailwind + Freighter / EVM wallet │
│ │
│ Marketplace Producer Dashboard Upload │
│ ├ SearchBar ├ RevenueChart ├ IPFS upload │
│ ├ FilterPanel ├ WithdrawalHistory ├ Collaborator config │
│ ├ SampleCard ├ BeatPerformance └ Price per tier │
│ ├ SalesFeed └ StatsCard │
│ └ CrossChainPaymentModal (CCTP) │
└───────────────────────────┬─────────────────────────────────────┘
│ REST + WebSocket
▼
┌─────────────────────────────────────────────────────────────────┐
│ crate-backend │
│ Express · TypeScript · PostgreSQL · Redis │
│ │
│ /samples CRUD + IPFS proxy │
│ /royalties split calculations + payout records │
│ /analytics per-sample stats and platform aggregates │
│ /moderation content review queue │
│ /webhooks outbound event dispatch │
│ /ws WebSocket server — real-time sales feed │
│ │
│ Soroban event indexer → decodes contract events → Postgres │
│ Reconciliation worker → aligns on-chain state with DB │
│ Redis cache layer → cache-aside on samples + analytics │
└───────────────────────────┬─────────────────────────────────────┘
│ Soroban RPC
▼
┌─────────────────────────────────────────────────────────────────┐
│ Stellar Testnet / Soroban │
│ │
│ crate_marketplace contract │
│ upload · purchase · resale · withdraw · collaborator splits │
└─────────────────────────────────────────────────────────────────┘
The backend is built for production: a PostgreSQL database for off-chain state, a Soroban event indexer that decodes contract events and writes them to relational tables, a reconciliation worker that periodically checks on-chain state against the database and flags drift, and a Redis cache layer with cache-aside reads and targeted invalidation on writes.
WebSocket support streams real-time sale events to connected frontends — the SalesFeed component on the marketplace page receives them without polling.
The IPFS proxy avoids exposing the pinning service credentials to the client. Audio uploads go client → backend → IPFS; the CID returned is what gets written to the contract.
The marketplace supports full-text search with keyboard shortcut activation and autocomplete, a filter panel (genre, BPM range, license tier, price) with URL-serialised state for shareable links, and pagination. Sample cards show a 30-second preview player.
The producer dashboard shows accumulated on-chain earnings from get_earnings, a revenue chart over time from the backend analytics endpoint, per-beat performance stats, and a withdrawal history. Withdrawal calls withdraw_earnings directly on the contract via Freighter.
Multi-wallet support handles both Freighter (Stellar native) and EVM wallets. Cross-chain payment via Circle's CCTP lets buyers on EVM chains pay in USDC without bridging manually.
The Expo app covers the producer workflow on mobile: a Discover feed of recent uploads, an Earnings screen with live balance from the contract, an Upload tab for submitting beats from the device, and a beat preview player using expo-av. Haptic feedback on purchase confirmation. Safe area insets handled correctly on notch devices.
- Freighter browser extension
- Stellar Testnet account funded via Friendbot
- Node.js 20+, Rust +
cargo, PostgreSQL, Redis (optional — gracefully disabled)
# Contracts
cd crate-contracts
cargo test
stellar contract build
# Backend
cd crate-backend
cp .env.example .env # fill in RPC URL, contract ID, Postgres, IPFS creds
npm install && npm run dev
# Frontend
cd crate-frontend
cp .env.example .env
npm install && npm run dev
# Mobile
cd crate-mobile
cp .env.example .env
npx expo startContracts: upload with collaborators, purchase across all three license tiers, revenue split arithmetic, resale flow with royalty enforcement, collaborator empty check, zero-share validation, comprehensive collaborator revenue-split matrix.
Backend: sample repository CRUD, royalty split calculations, payout records, reconciliation worker logic, moderation queue, Soroban event decoder, IPFS service, auth middleware, route-level timeout handling — across 10 test files.