Decentralized, Cartesi-powered music streaming. Melodious combines Cartesi Rollups for verifiable on-chain logic, smart contracts for NFTs and tokens, a Node/Express API with Postgres/Redis, and a Next.js frontend.
cartesi-backend: Cartesi Rollups dApp backend (routes for users, genres, tracks, playlists, rewards, subscriptions, withdrawals, config).smart-contract: Hardhat project deployingCartesiToken,MelodiousVault,TrackNFT, andArtistTokento the local Cannon network.server: Node/Express API with Prisma, Postgres, Redis, and job processing.frontend: Next.js app (GraphQL + sockets) for artists and listeners.
- Cartesi Rollups (CLI) and Cannon local chain (
anvil) for development - Hardhat + Ethers
- Node.js (Express), Prisma, Postgres, Redis
- Next.js (App Router), GraphQL (Apollo/URQL), React Query
- Node
>=20(recommended) and Yarn - Docker Desktop (Postgres + Redis)
- Cartesi CLI
@cartesi/cli@2.0.0-alpha.20 - Foundry (for
cast) — required to run the genre seeding script - Browser wallet: Rabby Wallet (recommended) or MetaMask
- Git and a terminal
- Open a terminal and go to
cartesi-backend. Commands:yarn install yarn build # optional but recommended - Build and run the Cartesi machine:
cartesi build cartesi run --services explorer,graphql --epoch-length 1
- Copy the printed dApp contract address. You’ll use it as
DAPP_ADDRESSin the steps below.
Notes:
- The Cannon chain (
anvil) runs under Cartesi athttp://127.0.0.1:6751/anvil(chainId 13370). - GraphQL endpoint typically runs at
http://127.0.0.1:6751/graphql.
- Open a new terminal, go to
smart-contract. Commands:cd smart-contract yarn install cp .env.example .env # in .env DAPP_ADDRESS=<your_dapp_address_from_step_1>
- Deploy everything to Cannon:
yarn deploy:cannon
- After deployment, capture addresses from the logs:
CartesiTokenMelodiousVaultTrackNFTArtistToken
- Update
.envwith yourCTSI_TOKEN_ADDRESS(CartesiToken). This helps with minting and verification scripts.
Mandatory (but useful):
- Mint CTSI to your wallet for testing:
MINT_TO=<your_wallet> MINT_AMOUNT=10000 yarn mint:ctsi-to
With the contract addresses from step 2, send a configuration payload so the Cartesi backend knows where to find each component.
- In a terminal, run:
cartesi send
cartesi send- Accept the default RPC URL.
- Paste your application address (
DAPP_ADDRESS). - Choose “string” encoding.
- Paste a JSON payload like this (replace placeholders with your addresses):
{"method":"create_config","args":{
"adminWalletAddresses":["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"],
"cartesiTokenContractAddress":"<CartesiToken>",
"vaultContractAddress":"<MelodiousVault>",
"artistPercentage":70,
"platformFeePercentage":5,
"poolPercentage":30,
"feePercentage":2,
"serverAddress":"0x0000000000000000000000000000000000000000",
"relayerAddress":"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"dappContractAddress":"<DAPP_ADDRESS>",
"melodiousNftAddress":"0x0000000000000000000000000000000000000000",
"referralPoints":100,
"trackNftContractAddress":"<TrackNFT>",
"artistTokenContractAddress":"<ArtistToken>",
"conversionRate":1000,
"minConversion":5,
"maxDailyConversion":10000
}}
This persists configuration inside the Cartesi application state. You can later update via {"method":"update_config",...}.
The dApp expects base genres to exist. Seed them via the provided script.
- Requirements: Foundry’s
castis installed.- macOS:
curl -L https://foundry.paradigm.xyz | bash && foundryup
- Linux (Debian/Ubuntu):
sudo apt update && sudo apt install -y curl git curl -L https://foundry.paradigm.xyz | bash && foundryup
- Windows (WSL2 + Ubuntu): enable WSL2, install Ubuntu from Microsoft Store, then run the Linux command above inside WSL. Ensure Docker Desktop uses the WSL2 backend.
- Verify:
cast --version
- macOS:
Steps:
- Open
cartesi-backend/src/scripts/genre.script.shand set:APPLICATION_ADDRESS="<your DAPP_ADDRESS>"- Confirm
INPUT_BOX_ADDRESSandRPC_URLmatch your local setup (http://127.0.0.1:6751/anvil). But no need to change it since it's already there. Just change yourAPPLICATION_ADDRESSto yourDAPP_ADDRESS
- From in
cartesi-backend/, run:bash src/scripts/genre.script.sh
What it does:
- Sends Cartesi inputs to create multiple genres via the InputBox (
addInput). - You can verify in the frontend or by querying GraphQL notices that genres are present.
-
Open a terminal and go to
server.cd server yarn install cp .env.example .env # in .env (minimum) DAPP_ADDRESS=<your_dapp_address> RPC_URL=http://127.0.0.1:6751/anvil INPUTBOX_ADDRESS=0xc70074BDD26d8cF983Ca6A5b89b8db52D5850051 yarn infra:up yarn start:dev # choose “yes” when prompted to reset Open a new terminal and go to server directory and run the command to seed ads.
yarn seed:ads
Subsequent runs for development:
yarn start:test- Install Rabby Wallet: https://rabby.io (Chrome/Brave/Arc supported).
- Import the local test mnemonic (Anvil default):
test test test test test test test test test test test junk- Only for local dev; never use on mainnet.
- Add the local Cannon chain in your wallet:
- RPC URL:
http://127.0.0.1:6751/anvil - Chain ID:
13370 - Currency symbol:
ETH
- RPC URL:
- MetaMask note: users sometimes hit RPC/connectivity issues on local custom chains; if you see chain mismatch or connection loops, prefer Rabby for smoother local testing.
- Test RPC connectivity:
cast block-number --rpc-url http://127.0.0.1:6751/anvil
-
Open a terminal and go to
frontend.cd frontend yarn install cp .env.example .env # in .env NEXT_PUBLIC_DAPP_ADDRESS=<your_dapp_address> NEXT_PUBLIC_CARTESI_TOKEN_ADDRESS=<CartesiToken> NEXT_PUBLIC_RPC_URL=http://127.0.0.1:6751/anvil yarn dev
Tip: Frontend also has codegen scripts (yarn codegen) for GraphQL and typechain.
Cartesi backend (cartesi-backend):
yarn build— Bundle TS and prepare dApp codecartesi build— Build the Cartesi machine imagecartesi run --services explorer,graphql --epoch-length 1— Run local node
Smart contracts (smart-contract):
yarn deploy:cannon— Deploy CartesiToken, MelodiousVault, TrackNFT, ArtistTokenyarn mint:ctsi-to— Mint CTSI to a wallet (MINT_TO,MINT_AMOUNT)yarn verify:deployment— Check deployed contracts are live and callable
API server (server):
yarn infra:up/yarn infra:down— Start/stop Postgres + Redisyarn start:dev— Reset DB + push schema, run dev serveryarn start:test— Dev server without DB resetyarn seed:ads— Seed ads data
Frontend (frontend):
yarn dev— Start Next.js (Turbopack)yarn build/yarn start— Build and run in production modeyarn codegen— Generate GraphQL and typechain artifacts
- “Insufficient CTSI balance” when subscribing or purchasing Artist tokens: mint more via
MINT_TO=<your_wallet> MINT_AMOUNT=10000 yarn mint:ctsi-to. - GraphQL endpoint not reachable: ensure
cartesi runstarted with--services explorer,graphql. - Postgres/Redis connection issues: check Docker is running and
yarn infra:upsucceeded; verify ports in.env. - Contract calls failing on Cannon: confirm
cartesi runis active,.envvalues are accurate, and you deployed tohttp://127.0.0.1:6751/anvil.
genre.script.shseeds base genres and is part of the required local setup. It uses Foundry’scastto submit inputs to the Cartesi InputBox.- All addresses shown in examples are for local development. Replace with your own when deploying elsewhere.
Enjoy building with Melodious! 🎵