🎵 Music & Sound Design · copyright protection

Onchain Audio Watermarking

Embed immutable proof of ownership and usage terms in audio files verified via blockchain.

Sepolia smart contract· onchain logic
Section · Onchain

The primitive.

full primer →

Copyright protection gets a tiny Solidity contract deployed to Ethereum Sepolia; musicians see a 'verified onchain' badge with the live contract address and a one-tap Etherscan link.

Why this primitiveSepolia contracts provide tamper-proof evidence of audio copyright.

Kernel
a Solidity contract deployed to Base Sepolia via MetaMask private key, then verified on BaseScan (Etherscan v2)
Drives the UI as
a 'verified onchain' badge with the live contract address and a BaseScan link
Appendix · Secrets

Required keys.

METAMASK_PRIVATE_KEY
Exported from MetaMask. Fund on Base Sepolia via the Coinbase faucet.
open ↗
BASE_SEPOLIA_RPC_URL
Alchemy Base Sepolia HTTPS endpoint (or https://sepolia.base.org).
open ↗
ETHERSCAN_API_KEY
Single Etherscan v2 key — covers BaseScan (chainId 84532) with no extra key.
open ↗
PRIVY_APP_ID
Enables Google sign-in and sponsored Base Sepolia transactions.
open ↗
PINATA_JWT
Pins images / JSON / manifests to IPFS.
open ↗

Add these in your Lovable project under Settings → Secrets before pasting the prompt below.

Appendix · Mega-prompt

The build prompt.

Paste into a fresh Lovable project. Make sure all five secrets above are set first. read the build strategy →

Build "Onchain Audio Watermarking" in ONE Lovable message. Single-page demo.

CONCEPT
Embed immutable proof of ownership and usage terms in audio files verified via blockchain.
Discipline: Music & Sound Design (copyright protection).
Onchain primitive: Sepolia smart contract. Why this primitive: Sepolia contracts provide tamper-proof evidence of audio copyright.

5-CREDIT BUDGET (HARD LIMIT):
- ONE single-page app. No router, no Lovable Cloud, no database, no auth flows beyond Privy drop-in.
- ONE Solidity contract, <=80 lines, deployed to Base Sepolia (chainId 84532), verified on BaseScan.
- Privy is always the auth + sponsored-tx layer (Google login, embedded wallet).
- Pinata/IPFS only if the idea genuinely needs to store a file or metadata.
- At most ONE AI call per user action (use Lovable AI Gateway with LOVABLE_API_KEY if AI is part of the idea).
- Skip tests, skip CI, skip docs pages. Ship the demo, nothing else.

STACK
- React + Vite single page (the index route).
- Privy embedded wallet — NATIVE Privy gas sponsorship on Base Sepolia (no ZeroDev,
  no smart-account SDK, no bundler). The EOA embedded wallet is the tx sender;
  Privy's paymaster covers gas so the user sees US$0.00.
- `defaultChain` and `supportedChains` MUST be a REAL viem `defineChain` object,
  not a `{ id, name }` stub (a stub compiles but breaks embedded-wallet transport init):
    import { defineChain } from "viem";
    const baseSepolia = defineChain({
      id: 84532, name: "Base Sepolia",
      nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
      rpcUrls: { default: { http: [import.meta.env.VITE_BASE_SEPOLIA_RPC_URL || "https://sepolia.base.org"] } },
      blockExplorers: { default: { name: "BaseScan", url: "https://sepolia.basescan.org" } },
    });
    <PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
      config={{ loginMethods:['google'],
                embeddedWallets:{ ethereum:{ createOnLogin:'users-without-wallets' } },
                defaultChain: baseSepolia as never,
                supportedChains: [baseSepolia] as never }}>
- IMPORTANT — Privy mount must be LAZY + CLIENT-ONLY (`@privy-io/react-auth` crashes
  under SSR): load `PrivyProvider` via `lazy(() => import('./privy-client-entry'))`
  inside `<ClientOnly><Suspense>` in a `privy-root.tsx`. Never import
  `@privy-io/react-auth` at module scope of a route file.
- EVERY tx call passes `{ sponsor: true }` AND `address: embedded.address`:
    import { useSendTransaction, useWallets } from "@privy-io/react-auth";
    const { sendTransaction } = useSendTransaction();
    const embedded = wallets.find(w => w.walletClientType === "privy");
    const receipt = await sendTransaction(
      { to: CONTRACT_ADDRESS, data, chainId: 84532 },
      { address: embedded.address, sponsor: true },
    );
  Without `sponsor: true` Privy silently falls back to user-paid gas.
  Without `address` Privy may route through a non-embedded wallet and prompt.
- Wrap the `sendTransaction` call in a 45s `Promise.race` timeout whose rejection
  message names the two required Privy dashboard settings (below), so the failure
  mode is diagnosable from the UI.
- PRIVY DASHBOARD (required, one-time, in the Privy console for VITE_PRIVY_APP_ID):
    1. Chains -> add Base Sepolia (84532) AND toggle
       "Allow transactions from the client" ON. Without this, `sendTransaction`
       hangs forever with no error.
    2. Gas Sponsorship -> add a Base Sepolia policy (unlimited or capped).
       Without it, embedded wallets need native ETH for gas and hit
       "insufficient funds" before the tx ever lands.
- Hardhat in /contracts (kept outside the Vite bundle). Install
  `@nomicfoundation/hardhat-ethers` AND `@nomicfoundation/hardhat-verify` (>=2.x).
  DO NOT install `@nomicfoundation/hardhat-toolbox` — it drags Hardhat 3 peers.
- hardhat.config.cjs — Base Sepolia + Etherscan v2 single-key:
    require("@nomicfoundation/hardhat-ethers");
    require("@nomicfoundation/hardhat-verify");
    const pk = process.env.METAMASK_PRIVATE_KEY;
    module.exports = {
      solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
      networks: { baseSepolia: {
        url: process.env.BASE_SEPOLIA_RPC_URL || "https://sepolia.base.org",
        accounts: pk ? [pk.startsWith("0x") ? pk : "0x" + pk] : [],
        chainId: 84532,
      } },
      etherscan: {
        apiKey: process.env.ETHERSCAN_API_KEY,          // single Etherscan v2 key covers BaseScan
        customChains: [{
          network: "baseSepolia", chainId: 84532,
          urls: {
            apiURL: "https://api.etherscan.io/v2/api?chainid=84532",
            browserURL: "https://sepolia.basescan.org",
          },
        }],
      },
      sourcify: { enabled: false },
    };
- Deploy: `npx hardhat run scripts/deploy.cjs --network baseSepolia`.
- Verify (run RIGHT AFTER deploy, no constructor args for these contracts):
  `npx hardhat verify --network baseSepolia <address>`
  On success it prints "Successfully verified contract … on the block explorer"
  and the source becomes readable at
  `https://sepolia.basescan.org/address/<address>#code`.
- Frontend reads: create a viem public client with the Base Sepolia RPC too —
  `createPublicClient({ chain: baseSepolia, transport: http(import.meta.env.VITE_BASE_SEPOLIA_RPC_URL) })`
  (import `baseSepolia` from `viem/chains`).
  Expose the RPC to the client by also setting VITE_BASE_SEPOLIA_RPC_URL to the same value.
- Write the deployed address to `src/data/contract.json` so the UI links to
  `https://sepolia.basescan.org/address/<address>`.

CONTRACT (contracts/OnchainAudioWatermarking.sol):
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title OnchainAudioWatermarking
/// @notice Embed immutable proof of ownership and usage terms in audio files verified via blockchain.
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
contract OnchainAudioWatermarking {
    event Logged(address indexed author, string cid, uint256 at);
    /// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
    function log(string calldata cid) external {
        emit Logged(msg.sender, cid, block.timestamp);
    }
}
```

USER FLOW
1. Land on page -> 'Sign in with Google' (Privy) -> embedded wallet auto-provisioned on Base Sepolia.
2. User performs a copyright protection action; the app calls `log(payload)` on the contract via Privy sponsored tx and shows the BaseScan link as proof.
3. Footer renders: "Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14"

REQUIRED SECRETS (Lovable -> Project Settings -> Secrets):
- METAMASK_PRIVATE_KEY  Base Sepolia deployer key. Fund it: https://portal.cdp.coinbase.com/products/faucet
                        (alt: https://www.alchemy.com/faucets/base-sepolia)
- BASE_SEPOLIA_RPC_URL  Alchemy Base Sepolia HTTPS endpoint (https://eth-base-sepolia.g.alchemy.com/v2/<key>)
                        OR the public default https://sepolia.base.org. Create a free app: https://dashboard.alchemy.com/
- ETHERSCAN_API_KEY     Single Etherscan v2 key — verifies on BaseScan (chainId 84532) with no extra key.
                        Get: https://etherscan.io/myapikey
- PRIVY_APP_ID          Google sign-in + sponsored tx. Enable Base Sepolia (84532) in your Privy dashboard.
                        Docs: https://docs.privy.io/llms-full.txt
- PINATA_JWT            IPFS uploads (only if app pins media). Docs: https://docs.pinata.cloud/llms-full.txt

CREDIT (must appear in UI footer AND as NatSpec on every deployed contract):
Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
Appendix · Market

Market sizing.

TAM
$1.3B
audio copyright management
SAM
$350M
digital watermarking technologies
SOM
$40M
blockchain watermark adopters

Indicative figures for hackathon pitches — refine with your own research before raising.

See also

Adjacent entries.