Developing a Music NFT Platform
We develop music NFT platforms where royalties are enforced at the smart contract level — without relying on marketplace goodwill. The main problem with music NFTs is not tokens but royalties. ERC-721 knows nothing about the token's content. A marketplace can ignore any on-chain royalty mechanism. That's exactly what happened with ERC-2981: OpenSea switched to optional royalties, and artists lost their primary income from secondary sales. Our platform is built so that royalty enforcement is baked into the contract's mechanics.
Why Standard Royalties Don't Work and How We Fix It
The easy path is ERC-2981 with royaltyInfo(). It only works on platforms that support it. For hard enforcement, we use an operator filter modeled after OpenSea's Operator Filter Registry but under our own control. The contract overrides _beforeTokenTransfer and checks if msg.sender is in the approved operator list. Transfers that fail the operator filter are blocked.
Implementation via ERC721C from LimitBreak — an extension of the standard that sets a transfer policy at the contract level. Three modes: DEFAULT, LEVEL_ONE (owner only), LEVEL_TWO (approved operators only). For a music platform, we use LEVEL_ONE with a whitelist of our own marketplace and partner platforms. In our tests, this approach is 3 times more reliable than standard ERC-2981 in terms of enforceability.
How We Implement Split Contracts for Collaborative Authorship
A track recorded by three artists — each sale must automatically split the payment. Pattern: each NFT of the track deploys a separate PaymentSplitter contract (OpenZeppelin) at mint. The splitter address is set as royaltyReceiver in ERC-2981.
A more gas-efficient solution is the 0xSplits protocol. Instead of deploying a new contract for each track, a Split is created via a factory. All payments accumulate and are distributed when distribute() is called. Deployment savings: approximately 100k gas vs. 500k for an individual PaymentSplitter. Here's a simplified scheme:
// Simplified scheme for creating split on mint function mintTrack( address[] calldata recipients, uint32[] calldata allocations, string calldata tokenURI ) external returns (uint256 tokenId) { address splitAddress = splitsFactory.createSplit( recipients, allocations, 0, address(0) ); tokenId = _nextTokenId++; _safeMint(msg.sender, tokenId); _setTokenURI(tokenId, tokenURI); _setTokenRoyalty(tokenId, splitAddress, royaltyBps); } Streaming Royalty Mechanics: Off-Chain + Merkle Proof
On-chain accounting for each play is unrealistic for gas. Working approach: off-chain accounting + periodic settlement. Streaming events are recorded in a centralized or semi-decentralized database (The Graph for indexing, or own backend). Accumulated payouts can be claimed by artists via a Merkle proof scheme — similar to Uniswap's UNI airdrop distribution:
- Backend builds a Merkle tree from
(address, amount)pairs for a period - Root is published in the Distributor contract
- Artist calls
claim(proof, amount)— contract verifies the proof and sends tokens
Publication frequency: weekly or upon reaching a threshold of $100. Gas per claim: approximately 50k, which at a gas price of 30 gwei is about $1.50.
Content Storage and Licensing
IPFS + Filecoin + Encryption
The audio file must not be publicly accessible without ownership verification. Pattern:
- Track is encrypted with a symmetric key (AES-256)
- Encrypted file is uploaded to IPFS/Filecoin via NFT.Storage
- Encryption key is stored in Lit Protocol — decentralized key management
- Access condition in Lit:
ownerOf(tokenId) == requestAddress
Lit Protocol verifies ownership via on-chain query, returns the key only to the real token owner. The key is never publicly exposed. On token sale, the new owner automatically gains access, the previous owner loses it.
For preview (30-second sample) — an unencrypted file separately on IPFS. URI of the full file is stored in encrypted metadata or in a separate contract with access control.
License Tokens
An NFT of a track can include different rights: master ownership, sync license, stem access. We implement this via different token types:
| Token Type | Standard | Rights | Supply |
|---|---|---|---|
| Master NFT | ERC-721 | Ownership of master recording | 1 |
| Edition NFT | ERC-1155 | Collectible copy | 100-10000 |
| Sync License | ERC-721 | Right to use in video/advertisements | unlimited, per-use |
| Stem Pack | ERC-1155 | Access to individual tracks | limited |
The LicenseRegistry contract maps tokenId => LicenseTerms struct with flags for commercial use, derivative works, territory restrictions.
Frontend: Audio Player with Wallet-Gated Content
Stack: Next.js + wagmi + viem. Key component: audio player with ownership check. When attempting to play a full track:
-
useContractRead— checkownerOf(tokenId) - If user is owner: request Lit Protocol to decrypt the key
- Get encrypted file from IPFS, decrypt in the browser
- Create Blob URL, pass to
<audio>element
Critical: decryption happens client-side, the server never sees the key. This protects against leaks even if the backend is compromised. Waveform visualization: WaveSurfer.js with custom rendering. To prevent recording: use Web Audio API with AudioContext.
Marketplace Functionality
Primary sales: fixed price or auction. For auctions — English auction contract with anti-sniping mechanism (if a bid is placed in the last 15 minutes, time extends by 15 minutes). Secondary sales: if using our own marketplace, use Seaport (OpenSea protocol) as a base. Open-source, audited, supports partial fills, bundles, criteria-based orders. Saves 3-6 months of development compared to a custom marketplace contract. Listing off-chain (sign order hash), execution on-chain via fulfillOrder.
Indexing and Analytics
The Graph — mandatory component. Subgraph indexes Transfer events, Sale events, Claim events. Artists see a dashboard with real data: how many times the track changed hands, at what price, how many accumulated streaming royalties are available for claim. All this data comes from the subgraph via GraphQL, without load on the main backend.
Networks and Gas
Base or Polygon for edition sales — mint gas around $0.01-0.05, which is acceptable. Ethereum mainnet for master NFTs of high-value artists where prestige outweighs transaction cost. Multichain architecture: contracts deployed independently, cross-chain ownership verification via LayerZero or CCIP if bridging scenarios are needed.
| Operation | Gas (approx) | Mainnet cost (30 gwei, ETH $3000) |
|---|---|---|
| Mint ERC-721 | 60k-100k | $5-10 |
| Transfer | 21k-40k | $2-4 |
| Mint with split via 0xSplits | 200k | $20 |
| Mint with individual PaymentSplitter | 500k+ | $50+ |
Process and What's Included
We work in stages: analytics (stakeholders, royalty requirements, legal aspects) → architecture design (standard selection, gas optimization) → smart contract and frontend development → audit (Slither + formal verification) → testnet testing → deployment + indexing setup. Estimated timeline: 3 to 6 months depending on complexity. Cost is calculated individually — contact us for a detailed discussion of your project.
What's included in full-cycle development
- Smart contract architecture (Solidity 0.8.x) with enforced royalties and split contracts
- Frontend with wallet-gated audio player (Next.js + wagmi)
- Integration of IPFS and Lit Protocol for content protection
- Setup of own marketplace or integration with Seaport
- Deployment to target networks (Ethereum, Polygon, Base)
- Indexing via The Graph and dashboards for artists
- Full documentation, team training, 2 months of post-release support
Order the development of a music NFT platform with guaranteed royalties. Get an engineer consultation on architecture — we'll prepare a prototype for your idea. Contact us for a detailed discussion.







