🎭 Theater & Live Performance · lighting cue logs

LuxGraph · Jetton

A real-time synchronization layer for live performance. Pay 0.01 USDT-on-TON to broadcast a signed, immutable lighting trigger or log a cue execution. Producers pay to verify show-timing accuracy for union compliance, while fans pay a micropayment to 'pulse' the lighting rig via a dedicated audience-interaction lane. Every state change is a settled transaction, ensuring the technical director’s log is cryptographically audit-proof.

TON Jetton paywall· jetton native
Section · Onchain

The primitive.

full primer →

The lighting cue logs payload sits behind an HTTP 402 wall priced in Jettons; directors pay with one Tonkeeper confirmation carrying a one-time memo, and the server unlocks it only after the transfer settles on TON.

Why this primitiveBy turning cue triggers into paid primitives, the app prevents spam interference in the DMX stream while creating a high-fidelity, trustless log of show execution for payroll and performance auditing.

Kernel
an HTTP 402 paywall metered in Jettons (USDT-on-TON shape) — the client sends a transfer carrying a one-time memo through TON Connect and the server re-reads the TON indexer to match it before releasing the payload
Drives the UI as
a 'pay to unlock' button that shows the memo, the settled transfer, and a tonscan link
Appendix · Secrets

Required keys.

TON_DEPLOYER_MNEMONIC
24-word testnet seed for the deploy script. Fund it free via the Telegram test giver.
open ↗
TONCENTER_API_KEY
Optional. Higher rate limits on the testnet indexer.
open ↗
TON_RECEIVER_ADDRESS
Collects Jetton paywall payments. Can equal the deployer wallet.
open ↗
TON_JETTON_MASTER
Jetton metered by the paywall. Leave empty to meter in Toncoin.
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.

Target

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

Build "LuxGraph · Jetton" in ONE Lovable message. Single-page Jetton-metered paid app on the TON testnet.

CONCEPT
A real-time synchronization layer for live performance. Pay 0.01 USDT-on-TON to broadcast a signed, immutable lighting trigger or log a cue execution. Producers pay to verify show-timing accuracy for union compliance, while fans pay a micropayment to 'pulse' the lighting rig via a dedicated audience-interaction lane. Every state change is a settled transaction, ensuring the technical director’s log is cryptographically audit-proof.
Discipline: Theater & Live Performance (lighting cue logs).
Onchain primitive: Jetton micropayments on TON (USDT-on-TON shape, TEP-74 transfers). Why: By turning cue triggers into paid primitives, the app prevents spam interference in the DMX stream while creating a high-fidelity, trustless log of show execution for payroll and performance auditing.

5-CREDIT BUDGET (HARD LIMIT)
- ONE single-page app. No Lovable Cloud, no database, no auth beyond TON Connect.
- NO custom smart contract. Payments settle as ordinary TEP-74 Jetton transfers to your receiver wallet.
- Self-host the verifier as ONE TanStack server route inside the same app (shape below).
- At most ONE AI call per user action (Lovable AI Gateway with LOVABLE_API_KEY, only if AI is part of the idea).
- Skip tests, skip CI, skip docs. Ship the demo.

STACK
- React + Vite + TanStack Start, single page (the index route).
- SSR-safe wallet mount is MANDATORY. Never import @tonconnect/ui-react at module
  scope of a route file — it touches `window` and crashes SSR. Use
  lazy(() => import('./ton-client-entry')) inside <ClientOnly> + <Suspense>, and
  keep <TonConnectUIProvider> inside ton-client-entry.tsx only.
- Publish public/tonconnect-manifest.json ({ url, name, iconUrl }) and pass
  manifestUrl={`${window.location.origin}/tonconnect-manifest.json`}.
- TESTNET IS FORCED: send with `network: CHAIN.TESTNET` and refuse to submit when
  `wallet.account.chain !== CHAIN.TESTNET`, with a 'switch your wallet to testnet' hint.
- Amounts are nanotons as strings ("50000000" = 0.05 TON). A text-comment body is
  beginCell().storeUint(0, 32).storeStringTail(text).endCell().toBoc().toString('base64').
- Read chain state from the public indexer https://testnet.toncenter.com/api/v3
  (/transactions?account=…, /jetton/transfers?address=…). Never poll a wallet for history.
- Contracts live in /contracts, compiled with @ton-community/func-js and deployed with
  @ton/ton + @ton/crypto from a node script — keep them out of the Vite bundle.
- Persistent amber "TON testnet only · no real value moves here" banner at the top of the shell.

PAYWALL PROTOCOL (HTTP 402 + memo verification)
- GET /api/public/ton-paid-content with no PAYMENT-MEMO header returns 402 and a challenge:
    { tonVersion: 1, network: "ton:testnet",
      accepts: [{ scheme: "jetton-transfer", payTo: "<receiver>", asset: "<jetton master>",
                  amount: "<smallest units>", decimals: 6, symbol: "USDT",
                  memoPrefix: "chx-", maxTimeoutSeconds: 900 }] }
- The client mints a one-time memo (`chx-` + 12 hex chars), then sends ONE TON Connect message:
  a TEP-74 `transfer` (op 0x0f8a7ea5) to the payer's jetton wallet with destination = payTo,
  forward_ton_amount > 0 and a forward payload carrying the memo as a text comment.
  Forward TON must be non-zero or the memo never reaches the receiver.
- The client then polls the same endpoint with the `PAYMENT-MEMO` header.
- The SERVER verifies independently — never trust the client's word for a payment:
    GET https://testnet.toncenter.com/api/v3/jetton/transfers?address=<payTo>&direction=in&limit=50
    match jetton_master === asset, amount >= required, decoded_forward_payload comment === memo,
    transaction_aborted === false, and transaction_now within the last 15 minutes.
  Only then return 200 with the payload plus a PAYMENT-RESPONSE header.
- Rate-limit the endpoint per IP and reject memos that do not match /^chx-[a-f0-9]{8,32}$/.
- Toncoin fallback: if no jetton master is configured, verify a plain 0.02 TON transfer with the
  same memo through /transactions?account=<payTo> — identical flow, one config flag.

USER FLOW
1. Connect Tonkeeper (testnet) via TON Connect; free test coins from https://t.me/testgiver_ton_bot.
2. Directors hit the locked lighting cue logs resource -> 402 challenge renders as a step list.
3. One wallet confirmation sends the Jetton transfer with the memo; the app polls until the
   server sees it on-chain, then reveals the payload with a tonscan link.
4. Footer renders: "Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14"

TON SURVIVAL KIT (non-obvious rules — follow all of them)
1. BUFFER: browsers have no `Buffer`, but every TON lib returns one, so
   `cell.toBoc().toString("base64")` throws "Buffer is not defined". Add one helper and
   await it at the top of EVERY function touching @ton/core, @ton/crypto or @ton/ton —
   including the TON Connect path, which is the one people forget:
     export async function ensureBuffer() {
       const g = globalThis as typeof globalThis & { Buffer?: unknown };
       if (g.Buffer) return;
       g.Buffer = (await import("buffer")).Buffer;
     }
2. ADDRESS FLAVOURS: one key renders as four strings. `EQ…`/`UQ…` are the mainnet
   flavours (bounceable / non-bounceable), `kQ…`/`0Q…` are the test-network flavours.
   Never string-compare addresses across flavours — normalise first with
   `Address.parse(a).equals(Address.parse(b))`. Render with an explicit flavour:
     addr.toString({ testOnly: true, bounceable: false, urlSafe: true })
   Send user transfers NON-bounceable (`bounce: false`); a bounceable send to an
   uninitialised wallet returns the funds and the demo looks broken.
3. WALLET VERSION: the same mnemonic derives DIFFERENT addresses per wallet version.
   A 24-word TON phrase -> `WalletContractV4` (workchain 0); a 12-word BIP39 phrase
   (Gram, MyTonWallet) -> `WalletContractV5R1`. Derive both, query balances, and use
   the funded one — do not guess. A TON wallet is itself a contract: it needs ~0.05 TON
   and its first send carries `init` with `seqno: 0`. "Not deployed" is normal for a
   fresh address, not an error.
4. EXPLORER: link everything to https://testnet.tonscan.org/address/<addr> and
   https://testnet.tonscan.org/tx/<hash>. Derive the base URL from config, never hardcode.
5. WALLET REALITY CHECK: mobile Tonkeeper and Gram ship mainnet-only, so a test-network
   demo opened on a phone dead-ends with "your wallet is on TON mainnet". Ship a fallback:
   generate a throwaway wallet in the browser (`mnemonicNew()` from @ton/crypto, mnemonic
   in localStorage, funded from the faucet) and sign locally with `WalletContractV4`.
   Lock that browser-held key to the test network — never let it touch real funds.
6. TONCENTER: v3 rate-limits hard (HTTP 429). Wrap every read in a retry with backoff and
   send `X-API-Key: TONCENTER_API_KEY` on anything user-facing.
7. PAYMENT VERIFICATION: verify SERVER-side only, never trust a client-reported hash.
   Mint a one-time `chx-<hex>` memo, then match the recipient's recent transactions on
   amount >= price, decoded comment === memo, `transaction_aborted === false`, and a
   15-minute freshness window. Comments must be sent as a base64 BOC, not plain text:
     beginCell().storeUint(0, 32).storeStringTail(memo).endCell().toBoc().toString("base64")
8. SSR: mount TON Connect client-side only — `lazy(() => import("./ton-client-entry"))`
   inside `<ClientOnly>` + `<Suspense>`. Importing @tonconnect/ui-react at route module
   scope crashes the server render. `tonconnect-manifest.json` must sit at a public https URL.
9. INSTALL: npm i @tonconnect/ui-react @ton/ton @ton/core @ton/crypto buffer
   (add @ton-community/func-js only when you compile and deploy a FunC contract).
END TON SURVIVAL KIT

REQUIRED SECRETS (Lovable -> Project Settings -> Secrets):
- TON_DEPLOYER_MNEMONIC  24-word testnet wallet seed used by the deploy script. Fund it free: https://t.me/testgiver_ton_bot
- TONCENTER_API_KEY      Optional but recommended for rate limits. Get one from https://t.me/tonapibot
- TON_RECEIVER_ADDRESS   Testnet wallet that collects the Jetton payments (can equal the deployer).
- TON_JETTON_MASTER      Jetton master address metered by the paywall; leave empty to meter in Toncoin.
- PINATA_JWT            IPFS uploads (only if the app pins media). Docs: https://docs.pinata.cloud/llms-full.txt

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

Market sizing.

TAM
$2.1B
The global live event production and automated show-control market.
SAM
$120M
Professional theaters, concert touring, and immersive 'pay-to-play' nightlife venues.
SOM
$8.5M
Off-Broadway productions, regional technical directors, and experimental light-art festivals on Base.

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

See also

Adjacent entries.

lighting cue logs
LightCue Automation
Record and trigger lighting cues onchain to verify show timing and enable automated playback.
playwright collaboration
DraftFlow · Jetton
Pay-per-contribution script evolution. Every time a playwright pushes a new scene, dialogue tweak, or stage direction, the production pays a $0.01 micro-royalty. This turns the script into a living, metered asset where writers are paid for the act of creation in real-time. Producers unlock specific drafts or 'forks' of a play for rehearsal by paying a settled $0.01 fee per actor access, ensuring the creative sweat equity is instantly monetized and timestamped on-chain.
casting marketplace
StageRead · Jetton
A high-frequency talent scout protocol where every audition tape submission and casting call 'side' download is a micro-settlement. Directors pay $0.01 to unlock a performer's reel, and actors pay $0.01 to commit their encrypted audition data to the chain. This replaces monthly subscription models with a 'pay-per-opportunity' architecture, preventing platform bloat and ensuring only high-intent interactions between talent and production.
lighting rights management
LumenSync · Jetton
A protocol for lighting designers to meter the 'burn' of their intellectual property. Lighting consoles ping the the Jetton paywall endpoint to unlock specific DMX map frames or complex Chamsys/MA3 sequence macros. Venues pay 0.01 USDT-on-TON per cue-trigger or per-minute of 'look' duration, ensuring designers are compensated for every performance without complex manual auditing.