🎵 Music & Sound Design · sample licensing

Signed Broker

musicians hits the endpoint, gets a 402 with the payment requirement, and signs a 0.01 USDC EIP-3009 authorization from a Privy embedded wallet before PayAI settles on Base Sepolia.

Base x402· agent-native micropayment
Section · Agentic

The kernel.

full primer →

An agent runs the protocol server-side and musicians get a signed, auditable result they can act on without leaving the app.

Why this primitiveBase x402 on Base Sepolia fits sample licensing in Music & Sound Design because musicians can settle 0.01 USDC via a signed EIP-3009 authorization before the broker endpoint returns anything.

Kernel
HTTP 402 + `PAYMENT-SIGNATURE` on Base Sepolia — the server issues a v2 challenge, the agent signs an EIP-3009 USDC authorization via a Privy embedded EVM wallet, the PayAI facilitator verifies and settles on-chain, and the server returns the protected payload with a `PAYMENT-RESPONSE` tx hash
Drives the UI as
a four-step flow log — Challenge · Sign · Retry · Settle — with the unlocked payload and a Basescan tx link at the end
Appendix · Secrets

Required key.

LOVABLE_API_KEY
Auto-provisioned by Lovable when you enable the Lovable AI add-on. Powers the buyer, seller and merchant agents through an OpenAI-compatible gateway in front of every frontier LLM. Zero copy-paste.
open ↗

Add this 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 the key above is set first. read the build strategy →

Build "Signed Broker · x402" as a ONE-SHOT Lovable build. The participant has only
5 credits — this single message must produce a working demo with no follow-ups.
Single-page TanStack Start app. Cut scope ruthlessly.

CONCEPT
Lovable AI runs the clearance agent that negotiates sample rights via A2A so producers legally release tracks containing uncleared audio.
Reframed as a paid, agent-callable HTTP endpoint on Base Sepolia x402 (0.01 USDC via Privy embedded EVM wallet + EIP-3009 + PayAI facilitator).
Discipline: Music & Sound Design (sample licensing).

LOVABLE BUDGET (HARD CAP: ONE-SHOT, ~5 CREDITS TOTAL):
The participant has FIVE Lovable credits for the whole build. This prompt MUST
ship a working demo on the FIRST message with zero follow-ups. Engineer for that.
- ONE TanStack Start app, ONE route (`src/routes/index.tsx`). No extra pages, no auth, no nav.
- ONE TanStack server route under `src/routes/api/public/` that runs the protocol.
- ONE client surface (a button + flow log) that triggers the payment and renders the result.
- NO database, NO Lovable Cloud, NO extra integrations beyond what's listed below.
- NO tests, NO docs pages, NO settings screens.
- Demo-fallback contract: every code path must boot with NO secrets and return
  realistic simulated envelopes flagged `simulated: true`. Real signing activates
  only when the user signs in and the wallet is funded.

PROTOCOL SURFACE — x402 on Base Sepolia (self-contained; participant has no skills)

CONFIG (src/data/x402.json) — copy exactly:
```json
{
  "endpoint":     "https://x402.payai.network/api/base-sepolia/paid-content",
  "proxy":        "/api/public/x402-proxy",
  "usdcAddress":  "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
  "chainId":      84532,
  "network":      "eip155:84532",
  "faucetUrl":    "https://faucet.circle.com/",
  "explorer":     "https://sepolia.basescan.org",
  "amount":       "10000",
  "amountLabel":  "0.01 USDC"
}
```

RPC (src/data/rpc.json) — Alchemy Base Sepolia (falls back to public if no key):
```json
{ "baseSepolia": "https://base-sepolia.g.alchemy.com/v2/demo" }
```
The public RPC is rate-limited; wire an Alchemy key when you have one.

SAME-ORIGIN PROXY (src/routes/api/public/x402-proxy.ts) — CRITICAL: PayAI facilitator
sends no CORS headers, so a direct browser fetch throws "Failed to fetch" BEFORE the
402 lands. Every request MUST route through this same-origin proxy. Forward
`PAYMENT-SIGNATURE` (request) and `PAYMENT-RESPONSE` (response) verbatim:
```ts
import { createFileRoute } from "@tanstack/react-router";
import x402Cfg from "@/data/x402.json";

/** Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14 */
export const Route = createFileRoute("/api/public/x402-proxy")({
  server: {
    handlers: {
      GET: async ({ request }) => {
        const sig = request.headers.get("PAYMENT-SIGNATURE");
        const upstream = await fetch(x402Cfg.endpoint, {
          method: "GET",
          headers: sig ? { "PAYMENT-SIGNATURE": sig } : {},
        });
        const body = await upstream.arrayBuffer();
        const out = new Headers();
        const ct = upstream.headers.get("content-type");
        if (ct) out.set("Content-Type", ct);
        const pr = upstream.headers.get("PAYMENT-RESPONSE");
        if (pr) out.set("PAYMENT-RESPONSE", pr);
        out.set("Access-Control-Expose-Headers", "PAYMENT-RESPONSE");
        return new Response(body, { status: upstream.status, headers: out });
      },
    },
  },
});
```
The `/api/public/*` prefix bypasses Lovable's published-site auth gate — that's
the design. Do NOT add auth middleware here.

FOUR-STEP FLOW (client lib src/lib/x402.ts + UI in src/routes/index.tsx):

1. CHALLENGE — `GET /api/public/x402-proxy` → expect HTTP 402 with JSON
   `{ x402Version: 2, accepts: [PaymentRequirement, ...], error }`. Pick the
   `accepts[]` entry where `network === "eip155:84532"` AND `scheme === "exact"`.
   Amount is `req.amount` (atomic string) — for USDC 6-decimals, `"10000"` = 0.01 USDC.
   NOTE: v2 uses `amount`, NOT v1's `maxAmountRequired`. Network id is CAIP-2
   (`"eip155:84532"`), NOT `"base-sepolia"`.

2. SIGN — Build EIP-3009 `TransferWithAuthorization` typed data and sign it via
   the Privy embedded EVM wallet's EIP-1193 provider (NOT React hooks):
   ```ts
   const provider = await embedded.getEthereumProvider();
   const sig = await provider.request({
     method: "eth_signTypedData_v4",
     params: [address, JSON.stringify(typedData)],
   });
   ```
   Typed data domain uses `chainId: 84532`, `verifyingContract: req.asset`,
   and — CRITICAL — `name` and `version` come from `req.extra.name` /
   `req.extra.version` (e.g. `"USDC"` / `"2"`), NEVER hardcoded to `"1"`.
   Message fields:
   - `from` = the Privy wallet address
   - `to`   = `req.payTo`
   - `value` = `req.amount` (string, atomic units)
   - `validAfter`  = `Math.floor(Date.now()/1000) - 60`
   - `validBefore` = `Math.floor(Date.now()/1000) + (req.maxTimeoutSeconds ?? 300)`
   - `nonce` = fresh 32-byte hex (`crypto.getRandomValues(new Uint8Array(32))` → `"0x…"`)
   NEVER reuse a nonce.

3. RETRY — Wrap the signed authorization into the x402 v2 envelope. CRITICAL:
   v2 wraps under `accepted`, echoing the FULL PaymentRequirement you picked.
   A top-level `{scheme, network, payload}` (v1 shape) is rejected as
   `invalid_payload`:
   ```json
   {
     "x402Version": 2,
     "accepted": { /* the full PaymentRequirement you picked, verbatim */ },
     "payload": {
       "signature": "0x…",
       "authorization": { "from": "…", "to": "…", "value": "10000",
                          "validAfter": "…", "validBefore": "…", "nonce": "0x…" }
     }
   }
   ```
   Base64-encode this JSON, send as `PAYMENT-SIGNATURE` header (exact case),
   retry `GET /api/public/x402-proxy`.

4. SETTLE — On 200, read the `PAYMENT-RESPONSE` response header, base64-decode
   to `{ success: true, transaction: "0x…", network: "eip155:84532", payer: "0x…" }`.
   Link the tx to `${explorer}/tx/${transaction}`.

PRIVY MOUNT (SSR-safe, non-negotiable):
- NEVER import `@privy-io/react-auth` at module scope of a route or a file
  reachable from `src/router.tsx` — it crashes workerd under SSR.
- Load it via `lazy(() => import("./privy-client-entry"))` inside a
  `<ClientOnly>` + `<Suspense>` boundary in `src/components/privy-root.tsx`.
- Configure with `loginMethods: ['email', 'google']` and
  `embeddedWallets: { ethereum: { createOnLogin: 'users-without-wallets' } }`.
- Read the wallet with `useWallets()`; get the EIP-1193 provider with
  `await wallets[0].getEthereumProvider()`.

USER FLOW (the entire app):
1. Sign In (email/google) — Privy creates an embedded EVM wallet.
2. Show the wallet address + a "Fund with Circle faucet" link that opens
   `https://faucet.circle.com/` with a "choose Base Sepolia + USDC" hint.
3. "Refresh USDC balance" button — reads balance via viem `createPublicClient`
   against `rpcCfg.baseSepolia`.
4. "Unlock content" button — runs steps 1-4 above, streams each into a live
   flow log with clear labels (Challenge · Sign · Retry · Settle).
5. On success, render the unlocked JSON payload + a Basescan link to the tx.

FAILURE MODES (surface the facilitator body verbatim in the flow log):
- `invalid_payload` → sent v1 envelope shape; wrap under `accepted` (step 3).
- `invalid_signature` → wrong `chainId` or hardcoded `extra.version`; use `84532`
  and read `extra.version` from the picked requirement.
- `insufficient_funds` → wallet has ETH but no USDC; fund via Circle faucet.
- `TypeError: Failed to fetch` at step 1 → called facilitator directly, bypassing
  the proxy; ALL requests must go through `/api/public/x402-proxy`.

SIMULATE MODE (default when user isn't signed in): the flow log walks through
the four steps with fake data flagged `simulated: true`, no real fetch, no
signing prompt. The button label switches from "Unlock (simulate)" to
"Unlock (live · Base Sepolia)" once the wallet is ready and funded.

STACK
- TanStack Start app, the index route only.
- Tailwind + shadcn. Editorial look: gold accent on a dark or warm-cream background,
  generous type, one strong headline, one primary action.
- Footer renders: "Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14".
- Libraries: template defaults + `@privy-io/react-auth` + `viem` + `zod`. Nothing else.

CREDIT (UI footer + JSDoc on the proxy handler): Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
Appendix · Market

Market sizing.

TAM
$11B
global music software and creator services
SAM
$800M
sample licensing and clearance platforms
SOM
$25M
indie producer micro-clearance spend

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

See also

Adjacent entries.